Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/zvirja/esphome-display-layout
Layout util for ESPHome display component
https://github.com/zvirja/esphome-display-layout
Last synced: 8 days ago
JSON representation
Layout util for ESPHome display component
- Host: GitHub
- URL: https://github.com/zvirja/esphome-display-layout
- Owner: zvirja
- License: mit
- Created: 2023-03-16T17:39:35.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2023-03-16T18:33:33.000Z (almost 2 years ago)
- Last Synced: 2024-11-09T02:25:00.982Z (2 months ago)
- Language: C++
- Size: 13.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ESPHome Display Layout
This repo contains a small layout utils to make designing screens simpler for ESPHome display module (e.g. famous [T5 4.7 Inch E-paper](https://www.lilygo.cc/products/t5-4-7-inch-e-paper-v2-3)).
⚠ **DISCLAIMER** Utility is very simple and misses a lot of essential features to be a proper layouting lib. It however provides an MVP to do a simple layouting.
# Installation
- Copy `layout_utils.hpp` to folder next to your ESPHome `yaml` file
- Add reference to the file:
```yaml
esphome:
includes:
- layout_utils.hpp
```
- Use macros/functions to build root layout component (usually horizontal or vertical panel). Render it at the end:
```yaml
display:
- platform: lilygo_t5_47_display
id: t5_display
rotation: 270
update_interval: never
lambda: |-
#define xres 540
#define yres 960
#define x_pad 10 // border padding
#define y_pad 10 // border paddingauto layout = _COL_A(START | STRETCH,
_T(id(font_text_40), "Hello"),_EXPAND(
_T(id(font_text_40), "World")
)
);layout->measure();
Rect rect = Rect(x_pad, 0, xres - x_pad * 2, yres);
layout->render(it, rect);
```
# Usage
Library provides a set of macros/functions (called BLOCKs internally to not collide with other possible layout entities) to use. Library consists of the following basic blocks.
## Layout
### Stack Panel
This is a [typical](https://wpf-tutorial.com/panels/stackpanel/) Stack Panel component which just stacks element one by one.
Properties:
- Direction: Can be either horizontal or vertical
- Main axis alignment
- Cross axis alignmentFunctions:
- `_COL(TBlocks&&...blocks)` - Renders a list of blocks _vertically_ with the default alignment
- `_COL_A(Align align, TBlocks&&...blocks)` - Renders a list of blocks _vertically_, allows to specify the alignment
- `_ROW(TBlocks&&...blocks)` - Renders a list of blocks _horizontally_ with the default alignment
- `_ROW_A(Align align, TBlocks&&...blocks)` - Renders a list of blocks _horizontally_, allows to specify the alignmentAlignment:
```cpp
// Alignment along main axis (vertical for vertical panel, horizontal for horizontal panel)
SPACE_BETWEEN = 0,
START = 1 << 0,
CENTER = 1 << 1,
END = 1 << 2,
// Alignment perpendicular to main axis (horizontal for vertical panel, vertical for horizontal panel)
TOP = 0,
MIDDLE = 1 << 3,
BOTTOM = 1 << 4,
STRETCH = 1 << 5,// Aliases for better readability
LEFT = TOP,
RIGHT = BOTTOM
```Play with them to feel how they work.
Example:
```yaml
_COL(
_T(id(font_text_40), "Hello"),_ROW_A(CENTER | STRETCH,
_T(id(font_text_40), "My"),
_T(id(font_text_40), "World")
)
);Valid alignments: `CENTER | MIDDLE`, `START | STRETCH`
```### EXPAND to put in Stack Panel
To understand why you need expander, you have to first understand how panel layouting works. Panel consists of the following steps (if there are nested panels, happens recursively):
1. Measure. Ask each child block how much space it needs
2. Position. Use the measured dimenions to position blocks depending on the specified panel alignment (e.g. `END` - put all the available space at the beginning; `SPACE_BETWEEN` - distribute free space between the blocks evenly)
3. Render. Render each component one by one after positioning them.Expander is a dummy components which wraps another component. It tells parent Panel to give all the available space to it upon rendering. If there is more than one EXPAND block next to each to each other, free space is distributed evently before them.
Notice, when EXPAND is used, the main-axis alignment (`START/CENTER/END/SPACE_BETWEEN`) is effectively ignored, as there is no free space to distribute.
Functions:
- `_EXPAND(x)` - Wrap child component giving it all the available space.Example:
```yaml
```yaml
_COL(
_T(id(font_text_20), "Header"),
_EXPAND(
_COL_A(CENTER | STRETCH
_VSPACE(25),
_T(id(font_text_40), "HELLO"),
_VSPACE(10),
_T(id(font_text_40), "WORLD"),
_VSPACE(25)
)
),_T(id(font_text_20), "Footer")
);
```Notice that here Header will be at the top, Footer at the bottom and content in the middle will occupy the remaining space. It was build for exactly such purposes.
### Spacers
Components to introduce space between components.
Functions:
- `_HSPACE(x)` - Introduces horizontal padding
- `_VSPACE(x)` - Introduces vertical paddingExample:
```yaml
_COL_A(START | STRETCH,
_T(id(font_text_40), "Hello"),
_VSPACE(50),_ROW_A(START | STRETCH,
_T(id(font_text_40), "My"),
_HSPACE(50),
_T(id(font_text_40), "World")
)
);
```### Debug container
This container just renders a border around inner component. Useful for debugging.
Functions:
- `_D(x)` - Render a frame around inner component## Elements
### Text
Text block renders the text using the specified font.
Functions:
- `_T(Font* font, const char* format, TArgs...args)` - Render text using the specified font
- ` _TROW(TArgs&&...textBlocks)` - Render a text row aligning all the inner text blocks by baseline.Text Row renders a few text blocks one by one in a row. The difference between TextRow and usage of horizontal panel (`_ROW()`) is that Text Row is aligning all the text blocks by baseline.
It's often hard to achieve similar effect with pure panel, especially if you mix e.g. text and icon fonts.Notice, `_T()` accepts format string & arguments exactly like `it.printf()` works.
Notice, `_TROW()` accepts text blocks only. If you put inside non-text blocks, compilation will fail with a cryptic error 😉Example:
```yaml
_COL(
_T(id(font_text_40), "Hello %d", 42),_TROW(
_T(id(font_text_40), "My"),
_T(id(font_text_40), "World")
)
);
```### Horizontal line
Just renders a horizontal line. Takes all the available space given by parent container if possible (e.g. if it's put inside vertical panel with `STRETCH` alignment).
Functions:
- `_HR(thickness, hpad, vpad)` - Renders a horizontal lineExample:
```yaml
_COL_A(START | STRETCH,
_T(id(font_text_40), "Hello"),
_VSPACE(25),
_HR(10, 0, 0),
_VSPACE(25),_T(id(font_text_40), "World")
);
```