feat(draw): support transforming widgets and improfe sw transform

For details see: https://docs.lvgl.io/master/overview/style.html
This commit is contained in:
Gabor Kiss-Vamosi
2022-04-26 10:45:12 +02:00
parent 69aa421acd
commit 318146a2c2
48 changed files with 1804 additions and 1117 deletions

View File

@@ -121,7 +121,7 @@ Move the object with this value in Y direction. Applied after layouts, aligns an
</ul>
### transform_zoom
Zoom image-like objects. Multiplied with the zoom set on the object. The value 256 (or `LV_IMG_ZOOM_NONE`) means normal size, 128 half size, 512 double size, and so on
Zoom an objects. The value 256 (or `LV_IMG_ZOOM_NONE`) means normal size, 128 half size, 512 double size, and so on
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -130,7 +130,7 @@ Zoom image-like objects. Multiplied with the zoom set on the object. The value 2
</ul>
### transform_angle
Rotate image-like objects. Added to the rotation set on the object. The value is interpreted in 0.1 degree units. E.g. 45 deg. = 450
Rotate an objects. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -138,6 +138,24 @@ Rotate image-like objects. Added to the rotation set on the object. The value is
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Ext. draw</strong> Yes</li>
</ul>
### transform_pivot_x
Set the pivot point's X coordinate for transformations. Relative to the object's top left corner'
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Layout</strong> No</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Ext. draw</strong> No</li>
</ul>
### transform_pivot_y
Set the pivot point's Y coordinate for transformations. Relative to the object's top left corner'
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Layout</strong> No</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Ext. draw</strong> No</li>
</ul>
## Padding
Properties to describe spacing between the parent's sides and the children and among the children. Very similar to the padding properties in HTML.

View File

@@ -268,6 +268,20 @@ lv_style_transition_dsc_init(&trans1, trans_props, lv_anim_path_ease_out, durati
lv_style_set_transition(&style1, &trans1);
```
## Opacity and Transformations
If the 'opa ', `transform_angle`, or `transform_zoom` properties are set their non-default value LVGL creates a snapshot about the widget and all its children in order to blend the whole widget with the set opacity and transformation properties.
These properties have this effect only on the `MAIN` part of the widget.
The created snapshot is called "intermediate layer" or simply "layer". If only `opa` is set to a value different from 255 LVGL can build the layer from smaller chunks. The size of these chunks can be configured by the following properties in `lv_conf.h`:
- `LV_LAYER_SIMPLE_BUF_SIZE`: [bytes] the optimal target buffer size. LVGL will try to allocate this size of memory.
- `LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE`: [bytes] used if `LV_LAYER_SIMPLE_BUF_SIZE` couldn't be allocated.
If transformation properties were also used the layer can not be rendered in chunks, but one larger memory needs to be allocated. The required memory depends on the angle, zoom and pivot parameters, and the size of the area to redraw, but it's never larger than the size of the widget (including the extra draw size used for shadow, outline, etc).
If the widget can fully cover the area to redraw, LVGL creates an RGB layer (which is faster to render and uses less memory). If the opposite case ARGB rendering needs to be used. A widget might not cover its area if it has radius, `bg_opa != 255`, shadow, outline, etc.
The click area of the widget is also transformed accordingly.
## Color filter
TODO

View File

@@ -92,6 +92,11 @@ In other words transformations work only on true color images stored as C array,
Note that the real coordinates of image objects won't change during transformation. That is `lv_obj_get_width/height/x/y()` will return the original, non-zoomed coordinates.
**IMPORTANT**
The transformation of the image is independent of the transformation properties coming from styles. (See [here](/overview/style#opacity-and-transformations)). The main differences are that pure image widget transformation
- doesn't transform the children of the image widget
- image is transformed directly without creating an intermediate layer (buffer) to snapshot the widget
### Size mode
By default, when the image is zoomed or rotated the real coordinates of the image object are not changed.