A36模拟器工程
This commit is contained in:
122
fr3092_lvglcode/lvgl/docs/overview/animation.md
Normal file
122
fr3092_lvglcode/lvgl/docs/overview/animation.md
Normal file
@ -0,0 +1,122 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/animation.md
|
||||
```
|
||||
# Animations
|
||||
|
||||
You can automatically change the value of a variable between a start and an end value using animations.
|
||||
The animation will happen by the periodical call of an "animator" function with the corresponding value parameter.
|
||||
|
||||
The *animator* functions has the following prototype:
|
||||
```c
|
||||
void func(void * var, lv_anim_var_t value);
|
||||
```
|
||||
This prototype is compatible with the majority of the *set* function of LVGL. For example `lv_obj_set_x(obj, value)` or `lv_obj_set_width(obj, value)`
|
||||
|
||||
|
||||
## Create an animation
|
||||
To create an animation an `lv_anim_t` variable has to be initialized and configured with `lv_anim_set_...()` functions.
|
||||
|
||||
```c
|
||||
|
||||
/* INITIALIZE AN ANIMATION
|
||||
*-----------------------*/
|
||||
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
|
||||
/* MANDATORY SETTINGS
|
||||
*------------------*/
|
||||
|
||||
/*Set the "animator" function*/
|
||||
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
|
||||
/*Set the "animator" function*/
|
||||
lv_anim_set_var(&a, obj);
|
||||
|
||||
/*Length of the animation [ms]*/
|
||||
lv_anim_set_time(&a, duration);
|
||||
|
||||
/*Set start and end values. E.g. 0, 150*/
|
||||
lv_anim_set_values(&a, start, end);
|
||||
|
||||
/* OPTIONAL SETTINGS
|
||||
*------------------*/
|
||||
|
||||
/*Time to wait before starting the animation [ms]*/
|
||||
lv_anim_set_delay(&a, delay);
|
||||
|
||||
/*Set path (curve). Default is linear*/
|
||||
lv_anim_set_path(&a, lv_anim_path_ease_in);
|
||||
|
||||
/*Set a callback to call when animation is ready.*/
|
||||
lv_anim_set_ready_cb(&a, ready_cb);
|
||||
|
||||
/*Set a callback to call when animation is started (after delay).*/
|
||||
lv_anim_set_start_cb(&a, start_cb);
|
||||
|
||||
/*Play the animation backward too with this duration. Default is 0 (disabled) [ms]*/
|
||||
lv_anim_set_playback_time(&a, wait_time);
|
||||
|
||||
/*Delay before playback. Default is 0 (disabled) [ms]*/
|
||||
lv_anim_set_playback_delay(&a, wait_time);
|
||||
|
||||
/*Number of repetitions. Default is 1. LV_ANIM_REPEAT_INFINIT for infinite repetition*/
|
||||
lv_anim_set_repeat_count(&a, wait_time);
|
||||
|
||||
/*Delay before repeat. Default is 0 (disabled) [ms]*/
|
||||
lv_anim_set_repeat_delay(&a, wait_time);
|
||||
|
||||
/*true (default): apply the start vale immediately, false: apply start vale after delay when then anim. really starts. */
|
||||
lv_anim_set_early_apply(&a, true/false);
|
||||
|
||||
/* START THE ANIMATION
|
||||
*------------------*/
|
||||
lv_anim_start(&a); /*Start the animation*/
|
||||
```
|
||||
|
||||
|
||||
You can apply multiple different animations on the same variable at the same time.
|
||||
For example, animate the x and y coordinates with `lv_obj_set_x` and `lv_obj_set_y`. However, only one animation can exist with a given variable and function pair.
|
||||
Therefore `lv_anim_start()` will delete the already existing variable-function animations.
|
||||
|
||||
## Animation path
|
||||
|
||||
You can determinate the path of animation. In the most simple case, it is linear, which means the current value between *start* and *end* is changed linearly.
|
||||
A *path* is a function which calculates the next value to set based on the current state of the animation. Currently, there are the following built-in paths functions:
|
||||
|
||||
- `lv_anim_path_linear` linear animation
|
||||
- `lv_anim_path_step` change in one step at the end
|
||||
- `lv_anim_path_ease_in` slow at the beginning
|
||||
- `lv_anim_path_ease_out` slow at the end
|
||||
- `lv_anim_path_ease_in_out` slow at the beginning and end too
|
||||
- `lv_anim_path_overshoot` overshoot the end value
|
||||
- `lv_anim_path_bounce` bounce back a little from the end value (like hitting a wall)
|
||||
|
||||
|
||||
## Speed vs time
|
||||
By default, you can set the animation time. But, in some cases, the animation speed is more practical.
|
||||
|
||||
The `lv_anim_speed_to_time(speed, start, end)` function calculates the required time in milliseconds to reach the end value from a start value with the given speed.
|
||||
The speed is interpreted in _unit/sec_ dimension. For example, `lv_anim_speed_to_time(20,0,100)` will give 5000 milliseconds. For example, in case of `lv_obj_set_x` *unit* is pixels so *20* means *20 px/sec* speed.
|
||||
|
||||
## Delete animations
|
||||
|
||||
You can delete an animation by `lv_anim_del(var, func)` by providing the animated variable and its animator function.
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/anim/index.rst
|
||||
|
||||
```
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_anim.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
368
fr3092_lvglcode/lvgl/docs/overview/coords.md
Normal file
368
fr3092_lvglcode/lvgl/docs/overview/coords.md
Normal file
@ -0,0 +1,368 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/coords.md
|
||||
```
|
||||
# Positions, sizes, and layouts
|
||||
|
||||
## Overview
|
||||
Similarly to many other parts of LVGL, the concept of setting the coordinates were inspired by CSS. It doesn't mean a perfect copy of the standard but subsets of CSS were implemented (sometimes with minor adjustments).
|
||||
It shorts it means:
|
||||
- the set coordinates (size, position, layouts, etc) are stored in styles
|
||||
- support min-width, max-width, min-height, max-height
|
||||
- have pixel, percentage, and "content" units
|
||||
- x=0; y=0 coordinate means the to top-left corner of the parent plus the left/top padding plus border width
|
||||
- width/height means the full size, the "content area" is smaller with padding and border width
|
||||
- a subset of flexbox and grid layouts are supported
|
||||
|
||||
### Units
|
||||
- pixel: Simply a position in pixels. A simple integer always mean pixel. E.g. `lv_obj_set_x(btn, 10)`
|
||||
- percentage: The percentage of the size of the object or its parent (depending on the property). The `lv_pct(value)` converts a value to percentage. E.g. `lv_obj_set_width(btn, lv_pct(50))`
|
||||
- `LV_SIZE_CONTENT`: Special value to set the width/height of an object to involve all the children. Its similar to `auto` in CSS. E.g. `lv_obj_set_width(btn, LV_SIZE_CONTENT)`.
|
||||
|
||||
### Boxing model
|
||||
LVGL follows CSS's [border-box](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing) model.
|
||||
An object's "box" is built from the following parts:
|
||||
- bounding box: the width/height of the elements.
|
||||
- border width: the width of the border.
|
||||
- padding: space between the sides of the object and its children.
|
||||
- content: the content area which size if the bounding box reduced by the border width and the size of the paddings.
|
||||
|
||||

|
||||
|
||||
The border is drawn inside the bounding box. Inside the border LVGL keeps "padding size" to place the children.
|
||||
|
||||
The outline is drawn outside of the bounding box.
|
||||
|
||||
### Important notes
|
||||
This section describes special cases in which LVGL's behavior might look unexpected.
|
||||
|
||||
#### Postponed coordinate calculation
|
||||
LVGL doesn't recalculate all the coordinate changes immediately to improve performance.
|
||||
Instead, the objects are marked as "dirty" and before redrawing the screen LVGL checks if there are any "dirty" objects. If so it refreshes their position, size and layout.
|
||||
|
||||
In other words, if you need to get the any coordinate of an object and it the coordinates were just changed LVGL's needs to be forced to recalculate to coordinates.
|
||||
To do this call `lv_obj_update_layout(obj)`.
|
||||
|
||||
The size and position might depends on the parent or layout therefor `lv_obj_update_layout` recalculates the coordinates of all objects on the screen of `obj`.
|
||||
|
||||
#### Removing styles
|
||||
As it's described in the [Using styles](#using-styles) section the coordinates can be set via style properties too.
|
||||
To be more precise under the hood every style coordinate related property is stored as style a property. If you use `lv_obj_set_x(obj, 20)` LVGL saves `x=20` in the local style of the object.
|
||||
|
||||
It's an internal mechanism and doesn't matter much as you use LVGL. However, there is one case in which you need to aware of that. If the style(s) of an object are removed by
|
||||
```c
|
||||
lv_obj_remove_style_all(obj)
|
||||
```
|
||||
|
||||
or
|
||||
```c
|
||||
lv_obj_remove_style(obj, NULL, LV_PART_MAIN);
|
||||
```
|
||||
the earlier set coordinates will be removed as well.
|
||||
|
||||
For example:
|
||||
```c
|
||||
/*The size of obj1 will be set back to the default in the end*/
|
||||
lv_obj_set_size(obj1, 200, 100); /*Now obj1 has 200;100 size*/
|
||||
lv_obj_remove_style_all(obj1); /*It removes the set sizes*/
|
||||
|
||||
|
||||
/*obj2 will have 200;100 size in the end */
|
||||
lv_obj_remove_style_all(obj2);
|
||||
lv_obj_set_size(obj2, 200, 100);
|
||||
```
|
||||
|
||||
## Position
|
||||
|
||||
### Simple way
|
||||
To simple set the x and y coordinates of an object use
|
||||
```c
|
||||
lv_obj_set_x(obj, 10);
|
||||
lv_obj_set_y(obj, 20);
|
||||
lv_obj_set_pos(obj, 10, 20); //Or in one function
|
||||
```
|
||||
|
||||
By default the the x and y coordinates are measured from the top left corner of the parent's content area.
|
||||
For example if the parent has 5 pixel padding on every side, the above code will place `obj` to (15, 25) because the content area starts after the padding.
|
||||
|
||||
If percentage values are calculated from the parents content area size.
|
||||
```c
|
||||
lv_obj_set_x(btn, lv_pct(10)); //x = 10 % of parant content area width
|
||||
```
|
||||
|
||||
### Align
|
||||
In some cases it's convenient to change the origin of the positioning from the the default top left. If the origin is changed e.g. to bottom-right, the (0,0) position means: align to the bottom-right corner.
|
||||
To change the origin use:
|
||||
```c
|
||||
lv_obj_set_align(obj, align);
|
||||
```
|
||||
|
||||
To change the alignment and set new coordinates:
|
||||
```c
|
||||
lv_obj_align(obj, align, x, y);
|
||||
```
|
||||
|
||||
The following alignment options can be used:
|
||||
- `LV_ALIGN_TOP_LEFT`
|
||||
- `LV_ALIGN_TOP_MID`
|
||||
- `LV_ALIGN_TOP_RIGHT`
|
||||
- `LV_ALIGN_BOTTOM_LEFT`
|
||||
- `LV_ALIGN_BOTTOM_MID`
|
||||
- `LV_ALIGN_BOTTOM_RIGHT`
|
||||
- `LV_ALIGN_LEFT_MID`
|
||||
- `LV_ALIGN_RIGHT_MID`
|
||||
- `LV_ALIGN_CENTER`
|
||||
|
||||
It quite common to align a children to the center of its parent, there fore is a dedicated function for it:
|
||||
```c
|
||||
lv_obj_center(obj);
|
||||
|
||||
//Has the same effect
|
||||
lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0);
|
||||
```
|
||||
|
||||
If the parent's size changes the set alignment and position of the children is applied again automatically.
|
||||
|
||||
The functions introduced above aligns the object to its parent. However it's also possible to align an object to an arbitrary object.
|
||||
```c
|
||||
lv_obj_align_to(obj_to_align, reference_obj, align, x, y);
|
||||
```
|
||||
|
||||
Besides the alignments options above the following can be used to align the object outside of the reference object:
|
||||
|
||||
- `LV_ALIGN_OUT_TOP_LEFT`
|
||||
- `LV_ALIGN_OUT_TOP_MID`
|
||||
- `LV_ALIGN_OUT_TOP_RIGHT`
|
||||
- `LV_ALIGN_OUT_BOTTOM_LEFT`
|
||||
- `LV_ALIGN_OUT_BOTTOM_MID`
|
||||
- `LV_ALIGN_OUT_BOTTOM_RIGHT`
|
||||
- `LV_ALIGN_OUT_LEFT_TOP`
|
||||
- `LV_ALIGN_OUT_LEFT_MID`
|
||||
- `LV_ALIGN_OUT_LEFT_BOTTOM`
|
||||
- `LV_ALIGN_OUT_RIGHT_TOP`
|
||||
- `LV_ALIGN_OUT_RIGHT_MID`
|
||||
- `LV_ALIGN_OUT_RIGHT_BOTTOM`
|
||||
|
||||
For example to align a label above a button and center the label is horizontally:
|
||||
```c
|
||||
lv_obj_align_to(label, btn, LV_ALIGN_OUT_TOP_MID, 0, -10);
|
||||
```
|
||||
|
||||
Not that - unlike with `lv_obj_align()` - `lv_obj_align_to()` can not realign the object if its coordinates or the reference object's coordinates changes.
|
||||
|
||||
## Size
|
||||
|
||||
### Simple way
|
||||
The width and the height of an object can be set easily as well:
|
||||
```c
|
||||
lv_obj_set_width(obj, 200);
|
||||
lv_obj_set_height(obj, 100);
|
||||
lv_obj_set_size(obj, 200, 100); //Or in one function
|
||||
```
|
||||
|
||||
Percentage values are calculated based on the parent's content area size. For example to set the object's height to the screen height:
|
||||
```c
|
||||
lv_obj_set_height(obj, lv_pct(100));
|
||||
```
|
||||
|
||||
Size setting supports a value: `LV_SIZE_CONTENT`. It means the object's size in the respective direction will be set to involve its the children.
|
||||
Note that only children on the right and bottom will be considered and children on the top and left remains cropped. This limitation makes the behavior more predictable.
|
||||
|
||||
Object with `LV_OBJ_FLAG_HIDDEN` or `LV_OBJ_FLAG_FLOATING` will be ignored by `LV_SIZE_CONTENT` calculation.
|
||||
|
||||
The above functions set the size of the bounding box of the object but the size of the content area can be set as well. It means the object's bounding box will be larger with the paddings than the set size.
|
||||
```c
|
||||
lv_obj_set_content_width(obj, 50); //The actual width: padding left + 50 + padding right
|
||||
lv_obj_set_content_height(obj, 30); //The actual width: padding top + 30 + padding bottom
|
||||
```
|
||||
|
||||
The size of the bounding box and the content area can be get with the following functions:
|
||||
```c
|
||||
lv_coord_t w = lv_obj_get_width(obj);
|
||||
lv_coord_t h = lv_obj_get_height(obj);
|
||||
lv_coord_t content_w = lv_obj_get_content_width(obj);
|
||||
lv_coord_t content_h = lv_obj_get_content_height(obj);
|
||||
```
|
||||
|
||||
## Using styles
|
||||
Under the hood the position, size and alignment properties are style properties.
|
||||
The above described "simple functions" hide the style related code for the sake of simplicity and set the position, size, and alignment properties in the local styles of the obejct.
|
||||
|
||||
However, using styles as to set the coordinates has some great advantages:
|
||||
- It makes easy to set the width/height/etc for several object together with ease. E.g. all make all the sliders 100x10 pixels sized.
|
||||
- It also makes possible to modify the values in one place.
|
||||
- The values can be overwritten by other styles. For example `style_btn` makes the object `100x50` by default but adding `style_full_width` overwrites only the width of the object.
|
||||
- The object can have different position or size in different state. E.g. 100 px wide in `LV_STATE_DEFAULT` but 120 px in `LV_STATE_PRESSED`.
|
||||
- Style transitions can be used to make the coordinate changes smooth.
|
||||
|
||||
|
||||
Here are some examples to set an object's size using a style:
|
||||
```c
|
||||
static lv_style_t style;
|
||||
lv_style_init(&style);
|
||||
lv_style_set_width(&style, 100);
|
||||
|
||||
lv_obj_t * btn = lv_btn_create(lv_scr_act());
|
||||
lv_obj_add_style(btn, &style, LV_PART_MAIN);
|
||||
```
|
||||
|
||||
As you will see below there are some other great features of size and position setting.
|
||||
However, to keep the LVGL's API lean only the most common coordinate setting features have a "simple" version and the more complex features can be used via styles.
|
||||
|
||||
## Translation
|
||||
|
||||
Let's say the there are 3 buttons next to each other. Their position is set as described above.
|
||||
Now you want to move a buttons up a little when it's pressed.
|
||||
|
||||
One way to achieve this is setting a new Y coordinate for pressed state:
|
||||
```c
|
||||
static lv_style_t style_normal;
|
||||
lv_style_init(&style_normal);
|
||||
lv_style_set_y(&style_normal, 100);
|
||||
|
||||
static lv_style_t style_pressed;
|
||||
lv_style_init(&style_pressed);
|
||||
lv_style_set_y(&style_pressed, 80);
|
||||
|
||||
lv_obj_add_style(btn1, &style_normal, LV_STATE_DEFAULT);
|
||||
lv_obj_add_style(btn1, &style_pressed, LV_STATE_PRESSED);
|
||||
|
||||
lv_obj_add_style(btn2, &style_normal, LV_STATE_DEFAULT);
|
||||
lv_obj_add_style(btn2, &style_pressed, LV_STATE_PRESSED);
|
||||
|
||||
lv_obj_add_style(btn3, &style_normal, LV_STATE_DEFAULT);
|
||||
lv_obj_add_style(btn3, &style_pressed, LV_STATE_PRESSED);
|
||||
```
|
||||
|
||||
It works but it's not really flexible because the pressed coordinate is hard-coded. If the buttons are not at y=100 `style_pressed` won't work as expected. To solve this translations can be used:
|
||||
```c
|
||||
static lv_style_t style_normal;
|
||||
lv_style_init(&style_normal);
|
||||
lv_style_set_y(&style_normal, 100);
|
||||
|
||||
static lv_style_t style_pressed;
|
||||
lv_style_init(&style_pressed);
|
||||
lv_style_set_translate_y(&style_pressed, -20);
|
||||
|
||||
lv_obj_add_style(btn1, &style_normal, LV_STATE_DEFAULT);
|
||||
lv_obj_add_style(btn1, &style_pressed, LV_STATE_PRESSED);
|
||||
|
||||
lv_obj_add_style(btn2, &style_normal, LV_STATE_DEFAULT);
|
||||
lv_obj_add_style(btn2, &style_pressed, LV_STATE_PRESSED);
|
||||
|
||||
lv_obj_add_style(btn3, &style_normal, LV_STATE_DEFAULT);
|
||||
lv_obj_add_style(btn3, &style_pressed, LV_STATE_PRESSED);
|
||||
```
|
||||
|
||||
Translation is applied from the current position of the object.
|
||||
|
||||
Percentage values can be used in translations as well. The percentage is relative to the size of the object (and not to the size of the parent). For example `lv_pct(50)` will move the object with half of its width/height.
|
||||
|
||||
The translations is applied after the layouts are calculated. Therefore, even the layouted objects' position can be translated.
|
||||
|
||||
The translation actually moves the object. It means it makes the scrollbars and `LV_SIZE_CONTENT` sized objects react on the position change.
|
||||
|
||||
|
||||
## Transformation
|
||||
Similarly to the position the size can be changed relative to the current size as well.
|
||||
The transformed width and height is added on both sides of the object. That is 10 px transformed width makes the object 2x10 pixel wider.
|
||||
|
||||
Unlike position translation, the size transformation doesn't make the object "really" larger. In other words scrollbars, layouts, `LV_SIZE_CONTENT` will not consider the transformed size.
|
||||
Hence size transformation if "only" a visual effect.
|
||||
|
||||
This code makes the a button larger when it's pressed:
|
||||
```c
|
||||
static lv_style_t style_pressed;
|
||||
lv_style_init(&style_pressed);
|
||||
lv_style_set_transform_width(&style_pressed, 10);
|
||||
lv_style_set_transform_height(&style_pressed, 10);
|
||||
|
||||
lv_obj_add_style(btn, &style_pressed, LV_STATE_PRESSED);
|
||||
```
|
||||
|
||||
### Min and Max size
|
||||
Similarly to CSS, LVGL also support `min-width`, `max-width`, `min-height` and `max-height`. These are limits preventing an object's size to be smaller/larger then these values.
|
||||
They are especially useful if the size is set by percentage or `LV_SIZE_CONTENT`.
|
||||
```c
|
||||
static lv_style_t style_max_height;
|
||||
lv_style_init(&style_max_height);
|
||||
lv_style_set_y(&style_max_height, 200);
|
||||
|
||||
lv_obj_set_height(obj, lv_pct(100));
|
||||
lv_obj_add_style(obj, &style_max_height, LV_STATE_DEFAULT); //Limit the height to 200 px
|
||||
```
|
||||
|
||||
Percentage values can be used as well which are relative to the size of the parent's content area size.
|
||||
```c
|
||||
static lv_style_t style_max_height;
|
||||
lv_style_init(&style_max_height);
|
||||
lv_style_set_y(&style_max_height, lv_pct(50));
|
||||
|
||||
lv_obj_set_height(obj, lv_pct(100));
|
||||
lv_obj_add_style(obj, &style_max_height, LV_STATE_DEFAULT); //Limit the height to half parent height
|
||||
```
|
||||
|
||||
## Layout
|
||||
|
||||
### Overview
|
||||
Layouts can update the position and size of an object's children. They can be used to automatically arrange the children into a line or column, or in much more complicated forms.
|
||||
|
||||
The position and size set by the layout overwrites the "normal" x, y, width, and height settings.
|
||||
|
||||
There is only one function that is the same for every layout: `lv_obj_set_layout(obj, <LAYOUT_NAME>)` sets the layout on an object.
|
||||
For the further settings of the parent and children see the documentations of the given layout.
|
||||
|
||||
### Built-in layout
|
||||
LVGL comes with two very powerful layouts:
|
||||
- Flexbox
|
||||
- Grid
|
||||
|
||||
Both are heavily inspired by the CSS layouts with the same name.
|
||||
|
||||
### Flags
|
||||
There are some flags that can be used on object to affect how they behave with layouts:
|
||||
- `LV_OBJ_FLAG_HIDDEN` Hidden object are ignored from layout calculations.
|
||||
- `LV_OBJ_FLAG_IGNORE_LAYOUT` The object is simply ignored by the layouts. Its coordinates can be set as usual.
|
||||
- `LV_OBJ_FLAG_FLOATING` Same as `LV_OBJ_FLAG_IGNORE_LAYOUT` but the object with `LV_OBJ_FLAG_FLOATING` will be ignored from `LV_SIZE_CONTENT` calculations.
|
||||
|
||||
These flags can be added/removed with `lv_obj_add/clear_flag(obj, FLAG);`
|
||||
|
||||
### Adding new layouts
|
||||
|
||||
LVGL can be freely extended by a custom layouts like this:
|
||||
```c
|
||||
uint32_t MY_LAYOUT;
|
||||
|
||||
...
|
||||
|
||||
MY_LAYOUT = lv_layout_register(my_layout_update, &user_data);
|
||||
|
||||
...
|
||||
|
||||
void my_layout_update(lv_obj_t * obj, void * user_data)
|
||||
{
|
||||
/*Will be called automatically if required to reposition/resize the children of "obj" */
|
||||
}
|
||||
```
|
||||
|
||||
Custom style properties can be added too that can be get and used in the update callback. For example:
|
||||
```c
|
||||
uint32_t MY_PROP;
|
||||
...
|
||||
|
||||
LV_STYLE_MY_PROP = lv_style_register_prop();
|
||||
|
||||
...
|
||||
static inline void lv_style_set_my_prop(lv_style_t * style, uint32_t value)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_style_set_prop(style, LV_STYLE_MY_PROP, v);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
|
190
fr3092_lvglcode/lvgl/docs/overview/display.md
Normal file
190
fr3092_lvglcode/lvgl/docs/overview/display.md
Normal file
@ -0,0 +1,190 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/display.md
|
||||
```
|
||||
# Displays
|
||||
|
||||
``` important:: The basic concept of *display* in LVGL is explained in the [Porting](/porting/display) section. So before reading further, please read the [Porting](/porting/display) section first.
|
||||
```
|
||||
|
||||
## Multiple display support
|
||||
|
||||
In LVGL, you can have multiple displays, each with their own driver and objects. The only limitation is that every display needs to be have same color depth (as defined in `LV_COLOR_DEPTH`).
|
||||
If the displays are different in this regard the rendered image can be converted to the correct format in the drivers `flush_cb`.
|
||||
|
||||
Creating more displays is easy: just initialize more display buffers and register another driver for every display.
|
||||
When you create the UI, use `lv_disp_set_default(disp)` to tell the library on which display to create objects.
|
||||
|
||||
Why would you want multi-display support? Here are some examples:
|
||||
- Have a "normal" TFT display with local UI and create "virtual" screens on VNC on demand. (You need to add your VNC driver).
|
||||
- Have a large TFT display and a small monochrome display.
|
||||
- Have some smaller and simple displays in a large instrument or technology.
|
||||
- Have two large TFT displays: one for a customer and one for the shop assistant.
|
||||
|
||||
### Using only one display
|
||||
Using more displays can be useful, but in most cases, it's not required. Therefore, the whole concept of multi-display is completely hidden if you register only one display.
|
||||
By default, the lastly created (the only one) display is used as default.
|
||||
|
||||
`lv_scr_act()`, `lv_scr_load(scr)`, `lv_layer_top()`, `lv_layer_sys()`, `LV_HOR_RES` and `LV_VER_RES` are always applied on the lastly created (default) screen.
|
||||
If you pass `NULL` as `disp` parameter to display related function, usually the default display will be used.
|
||||
E.g. `lv_disp_trig_activity(NULL)` will trigger a user activity on the default screen. (See below in [Inactivity](#Inactivity)).
|
||||
|
||||
### Mirror display
|
||||
|
||||
To mirror the image of the display to another display, you don't need to use the multi-display support. Just transfer the buffer received in `drv.flush_cb` to another display too.
|
||||
|
||||
### Split image
|
||||
You can create a larger display from smaller ones. You can create it as below:
|
||||
1. Set the resolution of the displays to the large display's resolution.
|
||||
2. In `drv.flush_cb`, truncate and modify the `area` parameter for each display.
|
||||
3. Send the buffer's content to each display with the truncated area.
|
||||
|
||||
## Screens
|
||||
|
||||
Every display has each set of [Screens](overview/object#screen-the-most-basic-parent) and the object on the screens.
|
||||
|
||||
Be sure not to confuse displays and screens:
|
||||
|
||||
* **Displays** are the physical hardware drawing the pixels.
|
||||
* **Screens** are the high-level root objects associated with a particular display. One display can have multiple screens associated with it, but not vice versa.
|
||||
|
||||
Screens can be considered the highest level containers which have no parent.
|
||||
The screen's size is always equal to its display and size their position is (0;0). Therefore, the screens coordinates can't be changed, i.e. `lv_obj_set_pos()`, `lv_obj_set_size()` or similar functions can't be used on screens.
|
||||
|
||||
A screen can be created from any object type but, the two most typical types are the [Base object](/widgets/obj) and the [Image](/widgets/core/img) (to create a wallpaper).
|
||||
|
||||
To create a screen, use `lv_obj_t * scr = lv_<type>_create(NULL, copy)`. `copy` can be an other screen to copy it.
|
||||
|
||||
To load a screen, use `lv_scr_load(scr)`. To get the active screen, use `lv_scr_act()`. These functions works on the default display. If you want to to specify which display to work on, use `lv_disp_get_scr_act(disp)` and `lv_disp_load_scr(disp, scr)`. Screen can be loaded with animations too. Read more [here](object.html#load-screens).
|
||||
|
||||
Screens can be deleted with `lv_obj_del(scr)`, but ensure that you do not delete the currently loaded screen.
|
||||
|
||||
### Transparent screens
|
||||
|
||||
Usually, the opacity of the screen is `LV_OPA_COVER` to provide a solid background for its children. If it's not the case (opacity < 100%) the display's background color or image will be visible.
|
||||
See the [Display background](#display-background) section for more details. If the display's background opacity is also not `LV_OPA_COVER` LVGL has no solid background to draw.
|
||||
|
||||
This configuration (transparent screen ans display) could be used to create for example OSD menus where a video is played to lower layer, and menu is created on an upper layer.
|
||||
|
||||
To handle transparent displays special (slower) color mixing algorithms needs to be used by LVGL so this feature needs to enabled with `LV_COLOR_SCREEN_TRANSP` n `lv_conf.h`.
|
||||
As this mode operates on the Alpha channel of the pixels `LV_COLOR_DEPTH = 32` is also required. The Alpha channel of 32-bit colors will be 0 where there are no objects and will be 255 where there are solid objects.
|
||||
|
||||
In summary, to enable transparent screen and displays to create OSD menu-like UIs:
|
||||
- Enable `LV_COLOR_SCREEN_TRANSP` in `lv_conf.h`
|
||||
- Be sure to use `LV_COLOR_DEPTH 32`
|
||||
- Set the screens opacity to `LV_OPA_TRANSP` e.g. with `lv_obj_set_style_local_bg_opa(lv_scr_act(), LV_OBJMASK_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP)`
|
||||
- Set the display opacity to `LV_OPA_TRANSP` with `lv_disp_set_bg_opa(NULL, LV_OPA_TRANSP);`
|
||||
|
||||
## Features of displays
|
||||
|
||||
### Inactivity
|
||||
|
||||
The user's inactivity is measured on each display. Every use of an [Input device](/overview/indev) (if [associated with the display](/porting/indev#other-features)) counts as an activity.
|
||||
To get time elapsed since the last activity, use `lv_disp_get_inactive_time(disp)`. If `NULL` is passed, the overall smallest inactivity time will be returned from all displays (**not the default display**).
|
||||
|
||||
You can manually trigger an activity using `lv_disp_trig_activity(disp)`. If `disp` is `NULL`, the default screen will be used (**and not all displays**).
|
||||
|
||||
### Background
|
||||
Every display has background color, a background image and background opacity properties. They become visible when the current screen is transparent or not positioned to cover the whole display.
|
||||
|
||||
Background color is a simple color to fill the display. It can be adjusted with `lv_disp_set_bg_color(disp, color)`;
|
||||
|
||||
Background image is path to file or pointer to an `lv_img_dsc_t` variable (converted image) to be used as wallpaper. It can be set with `lv_disp_set_bg_color(disp, &my_img)`;
|
||||
If the background image is set (not `NULL`) the background won't filled with `bg_color`.
|
||||
|
||||
The opacity of the background color or image can be adjusted with `lv_disp_set_bg_opa(disp, opa)`.
|
||||
|
||||
The `disp` parameter of these functions can be `NULL` to refer it to the default display.
|
||||
|
||||
|
||||
## Colors
|
||||
|
||||
The color module handles all color-related functions like changing color depth, creating colors from hex code, converting between color depths, mixing colors, etc.
|
||||
|
||||
The following variable types are defined by the color module:
|
||||
|
||||
- **lv_color1_t** Store monochrome color. For compatibility, it also has R, G, B fields but they are always the same value (1 byte)
|
||||
- **lv_color8_t** A structure to store R (3 bit),G (3 bit),B (2 bit) components for 8-bit colors (1 byte)
|
||||
- **lv_color16_t** A structure to store R (5 bit),G (6 bit),B (5 bit) components for 16-bit colors (2 byte)
|
||||
- **lv_color32_t** A structure to store R (8 bit),G (8 bit), B (8 bit) components for 24-bit colors (4 byte)
|
||||
- **lv_color_t** Equal to `lv_color1/8/16/24_t` according to color depth settings
|
||||
- **lv_color_int_t** `uint8_t`, `uint16_t` or `uint32_t` according to color depth setting. Used to build color arrays from plain numbers.
|
||||
- **lv_opa_t** A simple `uint8_`t type to describe opacity.
|
||||
|
||||
The `lv_color_t`, `lv_color1_t`, `lv_color8_t`, `lv_color16_t` and `lv_color32_t` types have got four fields:
|
||||
|
||||
- **ch.red** red channel
|
||||
- **ch.green** green channel
|
||||
- **ch.blue** blue channel
|
||||
- **full** red + green + blue as one number
|
||||
|
||||
You can set the current color depth in *lv_conf.h*, by setting the `LV_COLOR_DEPTH` define to 1 (monochrome), 8, 16 or 32.
|
||||
|
||||
### Convert color
|
||||
You can convert a color from the current color depth to another. The converter functions return with a number, so you have to use the `full` field:
|
||||
|
||||
```c
|
||||
lv_color_t c;
|
||||
c.red = 0x38;
|
||||
c.green = 0x70;
|
||||
c.blue = 0xCC;
|
||||
|
||||
lv_color1_t c1;
|
||||
c1.full = lv_color_to1(c); /*Return 1 for light colors, 0 for dark colors*/
|
||||
|
||||
lv_color8_t c8;
|
||||
c8.full = lv_color_to8(c); /*Give a 8 bit number with the converted color*/
|
||||
|
||||
lv_color16_t c16;
|
||||
c16.full = lv_color_to16(c); /*Give a 16 bit number with the converted color*/
|
||||
|
||||
lv_color32_t c24;
|
||||
c32.full = lv_color_to32(c); /*Give a 32 bit number with the converted color*/
|
||||
```
|
||||
|
||||
### Swap 16 colors
|
||||
You may set `LV_COLOR_16_SWAP` in *lv_conf.h* to swap the bytes of *RGB565* colors. It's useful if you send the 16-bit colors via a byte-oriented interface like SPI.
|
||||
|
||||
As 16-bit numbers are stored in Little Endian format (lower byte on the lower address), the interface will send the lower byte first. However, displays usually need the higher byte first. A mismatch in the byte order will result in highly distorted colors.
|
||||
|
||||
### Create and mix colors
|
||||
You can create colors with the current color depth using the LV_COLOR_MAKE macro. It takes 3 arguments (red, green, blue) as 8-bit numbers.
|
||||
For example to create light red color: `my_color = COLOR_MAKE(0xFF,0x80,0x80)`.
|
||||
|
||||
Colors can be created from HEX codes too: `my_color = lv_color_hex(0x288ACF)` or `my_color = lv_folro_hex3(0x28C)`.
|
||||
|
||||
Mixing two colors is possible with `mixed_color = lv_color_mix(color1, color2, ratio)`. Ration can be 0..255. 0 results fully color2, 255 result fully color1.
|
||||
|
||||
Colors can be created with from HSV space too using `lv_color_hsv_to_rgb(hue, saturation, value)` . `hue` should be in 0..360 range, `saturation` and `value` in 0..100 range.
|
||||
|
||||
### Opacity
|
||||
To describe opacity the `lv_opa_t` type is created as a wrapper to `uint8_t`. Some defines are also introduced:
|
||||
|
||||
- **LV_OPA_TRANSP** Value: 0, means the opacity makes the color completely transparent
|
||||
- **LV_OPA_10** Value: 25, means the color covers only a little
|
||||
- **LV_OPA_20 ... OPA_80** come logically
|
||||
- **LV_OPA_90** Value: 229, means the color near completely covers
|
||||
- **LV_OPA_COVER** Value: 255, means the color completely covers
|
||||
|
||||
You can also use the `LV_OPA_*` defines in `lv_color_mix()` as a *ratio*.
|
||||
|
||||
## API
|
||||
|
||||
|
||||
### Display
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_disp.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
||||
|
||||
### Colors
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_color.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
206
fr3092_lvglcode/lvgl/docs/overview/drawing.md
Normal file
206
fr3092_lvglcode/lvgl/docs/overview/drawing.md
Normal file
@ -0,0 +1,206 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/drawing.md
|
||||
```
|
||||
# Drawing
|
||||
|
||||
With LVGL, you don't need to draw anything manually. Just create objects (like buttons, labels, arc, etc), move and change them, and LVGL will refresh and redraw what is required.
|
||||
|
||||
However, it might be useful to have a basic understanding of how drawing happens in LVGL to add customization, make it easier to find bugs or just out of curiosity.
|
||||
|
||||
The basic concept is to not draw directly to the screen, but draw to an internal draw buffer first. When drawing (rendering) is ready copy that buffer to the screen.
|
||||
|
||||
The draw buffer can be smaller than the screen's size. LVGL will simply render in "tiles" that fit into the given draw buffer.
|
||||
|
||||
This approach has two main advantages compared to directly drawing to the screen:
|
||||
1. It avoids flickering while the layers of the UI are drawn. For example, if LVGL drawn directly into the display, when drawing a *background + button + text*, each "stage" would be visible for a short time .
|
||||
2. It's faster to modify a buffer in internal RAM and finally write one pixel only once than reading/writing the display directly on each pixel access.
|
||||
(e.g. via a display controller with SPI interface).
|
||||
|
||||
Note that, this concept is different from "traditional" double buffering where there are 2 screen sized frame buffers:
|
||||
one holds the current image to show on the display, and rendering happens to the other (inactive) frame buffer, and they are swapped when the rendering is finished.
|
||||
The main difference is that with LVGL you don't have to store 2 frame buffers (which usually requires external RAM) but only smaller draw buffer(s) that can easily fit into the internal RAM too.
|
||||
|
||||
|
||||
## Mechanism of screen refreshing
|
||||
|
||||
Be sure to get familiar with the [Buffering modes of LVGL](/porting/display) first.
|
||||
|
||||
LVGL refreshes the screen in the following steps:
|
||||
1. Something happens on the UI which requires redrawing. For example, a button is pressed, a chart is changed or an animation happened, etc.
|
||||
2. LVGL saves the changed object's old and new area into a buffer, called an *Invalid area buffer*. For optimization, in some cases, objects are not added to the buffer:
|
||||
- Hidden objects are not added.
|
||||
- Objects completely out of their parent are not added.
|
||||
- Areas partially out of the parent are cropped to the parent's area.
|
||||
- The objects on other screens are not added.
|
||||
3. In every `LV_DISP_DEF_REFR_PERIOD` (set in `lv_conf.h`) the followings happen:
|
||||
- LVGL checks the invalid areas and joins the adjacent or intersecting areas.
|
||||
- Takes the first joined area, if it's smaller than the *draw buffer*, then simply render the area's content into the *draw buffer*.
|
||||
If the area doesn't fit into the buffer, draw as many lines as possible to the *draw buffer*.
|
||||
- When the area is rendered, call `flush_cb` from the display driver to refresh the display.
|
||||
- If the area was larger than the buffer, render the remaining parts too.
|
||||
- Do the same with all the joined areas.
|
||||
|
||||
When an area is redrawn, the library searches the top most object which covers that area, and starts drawing from that object.
|
||||
For example, if a button's label has changed, the library will see that it's enough to draw the button under the text, and it's not required to draw the screen under the button too.
|
||||
|
||||
The difference between buffering modes regarding the drawing mechanism is the following:
|
||||
1. **One buffer** - LVGL needs to wait for `lv_disp_flush_ready()` (called from `flush_cb`) before starting to redraw the next part.
|
||||
2. **Two buffers** - LVGL can immediately draw to the second buffer when the first is sent to `flush_cb` because the flushing should be done by DMA (or similar hardware) in the background.
|
||||
3. **Double buffering** - `flush_cb` should only swap the address of the frame buffer.
|
||||
|
||||
## Masking
|
||||
*Masking* is the basic concept of LVGL's draw engine.
|
||||
To use LVGL it's not required to know about the mechanisms described here, you might find interesting to know how drawing works under hood.
|
||||
Knowing about mask comes in handy if you want to customize drawing.
|
||||
|
||||
To learn masking let's learn the steps of drawing first.
|
||||
LVGL performs the following steps to render any shape, image or text. It can be considered as a drawing pipeline.
|
||||
|
||||
1. **Prepare the draw descriptors** Create a draw descriptor from an object's styles (e.g. `lv_draw_rect_dsc_t`). It tells the parameters of drawing, for example the colors, widths, opacity, fonts, radius, etc.
|
||||
2. **Call the draw function** Call the draw function with the draw descriptor and some other parameters (e.g. `lv_draw_rect()`). It renders the primitive shape to the current draw buffer.
|
||||
3. **Create masks** If the shape is very simple and doesn't require masks go to #5. Else create the required masks (e.g. a rounded rectangle mask)
|
||||
4. **Calculate all the added mask**. It creates 0..255 values into a *mask buffer* with the "shape" of the created masks.
|
||||
E.g. in case of a "line mask" according to the parameters of the mask, keep one side of the buffer as it is (255 by default) and set the rest to 0 to indicate that this side should be removed.
|
||||
5. **Blend a color or image** During blending masks (make some pixels transparent or opaque), blending modes (additive, subtractive, etc), opacity are handled.
|
||||
|
||||
LVGL has the following built-in mask types which can be calculated and applied real-time:
|
||||
- `LV_DRAW_MASK_TYPE_LINE` Removes a side from a line (top, bottom, left or right). `lv_draw_line` uses 4 of it.
|
||||
Essentially, every (skew) line is bounded with 4 line masks by forming a rectangle.
|
||||
- `LV_DRAW_MASK_TYPE_RADIUS` Removes the inner or outer parts of a rectangle which can have radius. It's also used to create circles by setting the radius to large value (`LV_RADIUS_CIRCLE`)
|
||||
- `LV_DRAW_MASK_TYPE_ANGLE` Removes a circle sector. It is used by `lv_draw_arc` to remove the "empty" sector.
|
||||
- `LV_DRAW_MASK_TYPE_FADE` Create a vertical fade (change opacity)
|
||||
- `LV_DRAW_MASK_TYPE_MAP` The mask is stored in an array and the necessary parts are applied
|
||||
|
||||
Masks are used the create almost every basic primitives:
|
||||
- **letters** Create a mask from the letter and draw a rectangle with the letter's color considering the mask.
|
||||
- **line** Created from 4 "line masks", to mask out the left, right, top and bottom part of the line to get perfectly perpendicular line ending.
|
||||
- **rounded rectangle** A mask is created real-time to add radius to the corners.
|
||||
- **clip corner** To clip to overflowing content (usually children) on the rounded corners also a rounded rectangle mask is applied.
|
||||
- **rectangle border** Same as a rounded rectangle, but inner part is masked out too.
|
||||
- **arc drawing** A circle border is drawn, but an arc mask is applied too.
|
||||
- **ARGB images** The alpha channel is separated into a mask and the image is drawn as a normal RGB image.
|
||||
|
||||
## Hook drawing
|
||||
Although widgets can be very well customized by styles there might be cases when something really custom is required.
|
||||
To ensure a great level of flexibility LVGL sends a lot events during drawing with parameters that tells what LVGL is about to draw.
|
||||
Some fields of these parameters can be modified to draw something else or any custom drawing can be added manually.
|
||||
|
||||
A good use case for it is the [Button matrix](/widgets/core/btnmatrix) widget. By default its buttons can be styled in different states but you can't style the buttons one by one.
|
||||
However, an event is sent for ever button and you can tell LVGL for example to use different colors on a specific buttons or manually draw an image on an some buttons.
|
||||
|
||||
Below each related events are described in detail.
|
||||
|
||||
### Main drawing
|
||||
|
||||
These events are related to the actual drawing of the object. E.g. drawing of buttons, texts, etc happens here.
|
||||
|
||||
`lv_event_get_clip_area(event)` can be used to get the current clip area. The clip area is required in draw functions to make them draw only on limited area.
|
||||
|
||||
#### LV_EVENT_DRAW_MAIN_BEGIN
|
||||
|
||||
Sent before starting to draw an object. It's a good place to add masks manually. E.g. add a line mask that "removes" the right side of an object.
|
||||
|
||||
#### LV_EVENT_DRAW_MAIN
|
||||
|
||||
The actual drawing of the object happens in this event. E.g. a rectangle for a button is drawn here. First, the widgets' internal events are called to perform drawing and after that you can draw anything on top of them.
|
||||
For example you can add a custom text or an image.
|
||||
|
||||
#### LV_EVENT_DRAW_MAIN_END
|
||||
|
||||
Called when the main drawing is finished. You can draw anything here as well and it's also good place to remove the masks created in `LV_EVENT_DRAW_MAIN_BEGIN`.
|
||||
|
||||
### Post drawing
|
||||
|
||||
Post drawing events are called when all the children of an object are drawn. For example LVGL use the post drawing phase to draw the scrollbars because they should be above all the children.
|
||||
|
||||
`lv_event_get_clip_area(event)` can be used to get the current clip area.
|
||||
|
||||
#### LV_EVENT_DRAW_POST_BEGIN
|
||||
|
||||
Sent before starting the post draw phase. Masks can be added here too to mask out the post drawn content.
|
||||
|
||||
#### LV_EVENT_DRAW_POST
|
||||
|
||||
The actual drawing should happens here.
|
||||
|
||||
#### LV_EVENT_DRAW_POST_END
|
||||
|
||||
Called when post drawing has finished. If the masks were not removed in `LV_EVENT_DRAW_MAIN_END` they should be removed here.
|
||||
|
||||
### Part drawing
|
||||
|
||||
When LVGL draws a part of an object (e.g. a slider's indicator, a table's cell or a button matrix's button) it sends events before and after drawing that part with some context of the drawing.
|
||||
It allows changing the parts on a very low level with masks, extra drawing, or changing the parameters the LVGL is planning to use for drawing.
|
||||
|
||||
In these events an `lv_obj_draw_part_t` structure is used to describe the context of the drawing. Not all fields are set for every part and widget.
|
||||
To see which fields are set for a widget see the widget's documentation.
|
||||
|
||||
`lv_obj_draw_part_t` has the following fields:
|
||||
|
||||
```c
|
||||
// Always set
|
||||
const lv_area_t * clip_area; // The current clip area, required if you need to draw something in the event
|
||||
uint32_t part; // The current part for which the event is sent
|
||||
uint32_t id; // The index of the part. E.g. a button's index on button matrix or table cell index.
|
||||
|
||||
// Draw desciptors, set only if related
|
||||
lv_draw_rect_dsc_t * rect_dsc; // A draw descriptor that can be modified to changed what LVGL will draw. Set only for rectangle-like parts
|
||||
lv_draw_label_dsc_t * label_dsc; // A draw descriptor that can be modified to changed what LVGL will draw. Set only for text-like parts
|
||||
lv_draw_line_dsc_t * line_dsc; // A draw descriptor that can be modified to changed what LVGL will draw. Set only for line-like parts
|
||||
lv_draw_img_dsc_t * img_dsc; // A draw descriptor that can be modified to changed what LVGL will draw. Set only for image-like parts
|
||||
lv_draw_arc_dsc_t * arc_dsc; // A draw descriptor that can be modified to changed what LVGL will draw. Set only for arc-like parts
|
||||
|
||||
// Other paramters
|
||||
lv_area_t * draw_area; // The area of the part being drawn
|
||||
const lv_point_t * p1; // A point calculated during drawing. E.g. a point of chart or the center of an arc.
|
||||
const lv_point_t * p2; // A point calculated during drawing. E.g. a point of chart.
|
||||
char text[16]; // A text calculated during drawing. Can be modified. E.g. tick labels on a chart axis.
|
||||
lv_coord_t radius; // E.g. the radius of an arc (not the corner radius).
|
||||
int32_t value; // A value calculated during drawing. E.g. Chart's tick line value.
|
||||
const void * sub_part_ptr; // A pointer the identifies something in the part. E.g. chart series.
|
||||
```
|
||||
|
||||
`lv_event_get_draw_part_dsc(event)` can be used to get a pointer to `lv_obj_draw_part_t`.
|
||||
|
||||
#### LV_EVENT_DRAW_PART_BEGIN
|
||||
|
||||
Start the drawing of a part. It's good place to modify the draw descriptors (e.g. `rect_dsc`), or add masks.
|
||||
|
||||
#### LV_EVENT_DRAW_PART_END
|
||||
|
||||
Finish the drawing of a part. It's a good place to draw extra content on the part, or remove the masks added in `LV_EVENT_DRAW_PART_BEGIN`.
|
||||
|
||||
### Others
|
||||
|
||||
#### LV_EVENT_COVER_CHECK
|
||||
|
||||
This event is used to check whether an object fully covers an area or not.
|
||||
|
||||
`lv_event_get_cover_area(event)` returns an pointer to an area to check and `lv_event_set_cover_res(event, res)` can be used to set one of these results:
|
||||
- `LV_COVER_RES_COVER` the areas is fully covered by the object
|
||||
- `LV_COVER_RES_NOT_COVER` the areas is not covered by the object
|
||||
- `LV_COVER_RES_MASKED` there is a mask on the object so it can not covert the area
|
||||
|
||||
Here are some cases why can't an object fully cover an area:
|
||||
- It's simply not fully on the that area
|
||||
- It has radius
|
||||
- It has not 100% background opacity
|
||||
- It's an ARGB or chroma keyed image
|
||||
- It has not normal blending mode. In this case LVGL needs to know the colors under the object to make the blending properly
|
||||
- It's a text, etc
|
||||
|
||||
In short if for any reason the the area below the object is visible than it doesn't cover that area.
|
||||
|
||||
Before sending this event LVGL checks if at least the widget's coordinates fully cover the area or not. If not the event is not called.
|
||||
|
||||
You need to check only the drawing you have added. The existing properties known by widget are handled in the widget's internal events.
|
||||
E.g. if a widget has > 0 radius it might not cover an area but you need to handle `radius` only if you will modify it and widget can't know about it.
|
||||
|
||||
#### LV_EVENT_REFR_EXT_DRAW_SIZE
|
||||
|
||||
If you need to draw outside of a widget LVGL needs to know about it to provide the extra space for drawing.
|
||||
Let's say you create an event the writes the current value of a slider above its knob. In this case LVGL needs to know that the slider's draw area should be larger with the size required for the text.
|
||||
|
||||
You can simple set the required draw area with `lv_event_set_ext_draw_size(e, size)`.
|
||||
|
168
fr3092_lvglcode/lvgl/docs/overview/event.md
Normal file
168
fr3092_lvglcode/lvgl/docs/overview/event.md
Normal file
@ -0,0 +1,168 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/event.md
|
||||
```
|
||||
# Events
|
||||
|
||||
Events are triggered in LVGL when something happens which might be interesting to the user, e.g. if an object:
|
||||
- is clicked
|
||||
- is scrolled
|
||||
- its value has changed
|
||||
- redrawn, etc.
|
||||
|
||||
## Add events to the object
|
||||
|
||||
The user can assign callback functions to an object to see its events. In practice, it looks like this:
|
||||
```c
|
||||
lv_obj_t * btn = lv_btn_create(lv_scr_act());
|
||||
lv_obj_add_event_cb(btn, my_event_cb, LV_EVENT_CLICKED, NULL); /*Assign an event callback*/
|
||||
|
||||
...
|
||||
|
||||
static void my_event_cb(lv_event_t * event)
|
||||
{
|
||||
printf("Clicked\n");
|
||||
}
|
||||
```
|
||||
In the example `LV_EVENT_CLICKED` means that only the click event will call `my_event_cb`. See the [list of event codes](#event-codes) for all the options.
|
||||
`LV_EVENT_ALL` can be used to receive all the events.
|
||||
|
||||
The last parameter of `lv_obj_add_event_cb` is a pointer to any custom data that will be available in the event. It will be described later in more detail.
|
||||
|
||||
More events can be added to an object, like this:
|
||||
```c
|
||||
lv_obj_add_event_cb(obj, my_event_cb_1, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_add_event_cb(obj, my_event_cb_2, LV_EVENT_PRESSED, NULL);
|
||||
lv_obj_add_event_cb(obj, my_event_cb_3, LV_EVENT_ALL, NULL); /*No filtering, receive all events*/
|
||||
```
|
||||
|
||||
Even the same event callback can be used on an object with different `user_data`. For example:
|
||||
```c
|
||||
lv_obj_add_event_cb(obj, increment_on_click, LV_EVENT_CLICKED, &num1);
|
||||
lv_obj_add_event_cb(obj, increment_on_click, LV_EVENT_CLICKED, &num2);
|
||||
```
|
||||
|
||||
The events will be called in the order as they were added.
|
||||
|
||||
|
||||
More objects can use the same *event callback*.
|
||||
|
||||
|
||||
## Remove event(s) from an object
|
||||
|
||||
Events can be removed from an object with the `lv_obj_remove_event_cb(obj, event_cb)` function or `lv_obj_remove_event_dsc(obj, event_dsc)`. `event_dsc` is a pointer returned by `lv_obj_add_event_cb`.
|
||||
|
||||
## Event codes
|
||||
|
||||
The event codes can be grouped into these categories:
|
||||
- Input device events
|
||||
- Drawing events
|
||||
- Other events
|
||||
- Special events
|
||||
- Custom events
|
||||
|
||||
All objects (such as Buttons/Labels/Sliders etc.) regardless their type receive the *Input device*, *Drawing* and *Other* events.
|
||||
|
||||
However the *Special events* are specific to a particular widget type. See the [widgets' documentation](/widgets/index) to learn when they are sent,
|
||||
|
||||
*Custom events* are added by the user and therefore these are never sent by LVGL.
|
||||
|
||||
The following event codes exist:
|
||||
|
||||
### Input device events
|
||||
- `LV_EVENT_PRESSED` The object has been pressed
|
||||
- `LV_EVENT_PRESSING` The object is being pressed (called continuously while pressing)
|
||||
- `LV_EVENT_PRESS_LOST` The object is still being pressed but slid cursor/finger off of the object
|
||||
- `LV_EVENT_SHORT_CLICKED` The object was pressed for a short period of time, then released it. Not called if scrolled.
|
||||
- `LV_EVENT_LONG_PRESSED` Object has been pressed for at least the `long_press_time` specified in the input device driver. Not called if scrolled.
|
||||
- `LV_EVENT_LONG_PRESSED_REPEAT` Called after `long_press_time` in every `long_press_repeat_time` ms. Not called if scrolled.
|
||||
- `LV_EVENT_CLICKED` Called on release if the object not scrolled (regardless to long press)
|
||||
- `LV_EVENT_RELEASED` Called in every cases when the object has been released
|
||||
- `LV_EVENT_SCROLL_BEGIN` Scrolling begins
|
||||
- `LV_EVENT_SCROLL_END` Scrolling ends
|
||||
- `LV_EVENT_SCROLL` The object was scrolled
|
||||
- `LV_EVENT_GESTURE` A gesture is detected. Get the gesture with `lv_indev_get_gesture_dir(lv_indev_get_act());`
|
||||
- `LV_EVENT_KEY` A key is sent to the object. Get the key with `lv_indev_get_key(lv_indev_get_act());`
|
||||
- `LV_EVENT_FOCUSED` The object is focused
|
||||
- `LV_EVENT_DEFOCUSED` The object is defocused
|
||||
- `LV_EVENT_LEAVE` The object is defocused but still selected
|
||||
- `LV_EVENT_HIT_TEST` Perform advanced hit-testing. Use `lv_hit_test_info_t * a = lv_event_get_hit_test_info(e)` and check if `a->point` can click the object or not. If not set `a->res = false`
|
||||
|
||||
|
||||
### Drawing events
|
||||
- `LV_EVENT_COVER_CHECK` Check if the object fully covers an area. The event parameter is `lv_cover_check_info_t *`.
|
||||
- `LV_EVENT_REFR_EXT_DRAW_SIZE` Get the required extra draw area around the object (e.g. for shadow). The event parameter is `lv_coord_t *` to store the size. Overwrite it only with a larger value.
|
||||
- `LV_EVENT_DRAW_MAIN_BEGIN` Starting the main drawing phase.
|
||||
- `LV_EVENT_DRAW_MAIN` Perform the main drawing
|
||||
- `LV_EVENT_DRAW_MAIN_END` Finishing the main drawing phase
|
||||
- `LV_EVENT_DRAW_POST_BEGIN` Starting the post draw phase (when all children are drawn)
|
||||
- `LV_EVENT_DRAW_POST` Perform the post draw phase (when all children are drawn)
|
||||
- `LV_EVENT_DRAW_POST_END` Finishing the post draw phase (when all children are drawn)
|
||||
- `LV_EVENT_DRAW_PART_BEGIN` Starting to draw a part. The event parameter is `lv_obj_draw_dsc_t *`. Learn more [here](/overview/drawing).
|
||||
- `LV_EVENT_DRAW_PART_END` Finishing to draw a part. The event parameter is `lv_obj_draw_dsc_t *`. Learn more [here](/overview/drawing).
|
||||
|
||||
### Other events
|
||||
- `LV_EVENT_DELETE` Object is being deleted
|
||||
- `LV_EVENT_CHILD_CHANGED` Child was removed/added
|
||||
- `LV_EVENT_SIZE_CHANGED` Object coordinates/size have changed
|
||||
- `LV_EVENT_STYLE_CHANGED` Object's style has changed
|
||||
- `LV_EVENT_BASE_DIR_CHANGED` The base dir has changed
|
||||
- `LV_EVENT_GET_SELF_SIZE` Get the internal size of a widget
|
||||
|
||||
### Special events
|
||||
- `LV_EVENT_VALUE_CHANGED` The object's value has changed (i.e. slider moved)
|
||||
- `LV_EVENT_INSERT` A text is being inserted to the object. The event data is `char *` being inserted.
|
||||
- `LV_EVENT_REFRESH` Notify the object to refresh something on it (for the user)
|
||||
- `LV_EVENT_READY` A process has finished
|
||||
- `LV_EVENT_CANCEL` A process has been canceled
|
||||
|
||||
|
||||
### Custom events
|
||||
Any custom event codes can be registered by `uint32_t MY_EVENT_1 = lv_event_register_id();`
|
||||
|
||||
And can be sent to any object with `lv_event_send(obj, MY_EVENT_1, &some_data)`
|
||||
|
||||
## Sending events
|
||||
|
||||
To manually send events to an object, use `lv_event_send(obj, <EVENT_CODE> &some_data)`.
|
||||
|
||||
For example, it can be used to manually close a message box by simulating a button press (although there are simpler ways of doing this):
|
||||
```c
|
||||
/*Simulate the press of the first button (indexes start from zero)*/
|
||||
uint32_t btn_id = 0;
|
||||
lv_event_send(mbox, LV_EVENT_VALUE_CHANGED, &btn_id);
|
||||
```
|
||||
|
||||
### Refresh event
|
||||
|
||||
`LV_EVENT_REFRESH` is special event because it's designed to be used by the user to notify an object to refresh itself. Some examples:
|
||||
- notify a label to refresh its text according to one or more variables (e.g. current time)
|
||||
- refresh a label when the language changes
|
||||
- enable a button if some conditions are met (e.g. the correct PIN is entered)
|
||||
- add/remove styles to/from an object if a limit is exceeded, etc
|
||||
|
||||
## Fields of lv_event_t
|
||||
|
||||
`lv_event_t` is the only parameter passed to event callback and it contains all the data about the event. The following values can be get from it:
|
||||
- `lv_event_get_code(e)` get the event code
|
||||
- `lv_event_get_target(e)` get the object to which the event is sent
|
||||
- `lv_event_get_original_target(e)` get the object to which the event is sent originally sent (different from `lv_event_get_target` if [event bubbling](#event-bubbling) is enabled)
|
||||
- `lv_event_get_user_data(e)` get the pointer passed as the last parameter of `lv_obj_add_event_cb`.
|
||||
- `lv_event_get_param(e)` get the parameter passed as the last parameter of `lv_event_send`
|
||||
|
||||
|
||||
## Event bubbling
|
||||
|
||||
If `lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE)` is enabled all events will be sent to the object's parent too. If the parent also has `LV_OBJ_FLAG_EVENT_BUBBLE` enabled the event will be sent to its parent too, and so on.
|
||||
|
||||
The *target* parameter of the event is always the current target object, not the original object. To get the original target call `lv_event_get_original_target(e)` in the event handler.
|
||||
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/event/index.rst
|
||||
|
||||
```
|
116
fr3092_lvglcode/lvgl/docs/overview/file-system.md
Normal file
116
fr3092_lvglcode/lvgl/docs/overview/file-system.md
Normal file
@ -0,0 +1,116 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/file-system.md
|
||||
```
|
||||
# File system
|
||||
|
||||
LVGL has a 'File system' abstraction module that enables you to attach any type of file systems.
|
||||
The file system is identified by a drive letter.
|
||||
For example, if the SD card is associated with the letter `'S'`, a file can be reached like `"S:path/to/file.txt"`.
|
||||
|
||||
## Add a driver
|
||||
|
||||
To add a driver, `lv_fs_drv_t` needs to be initialized like this:
|
||||
```c
|
||||
lv_fs_drv_t drv;
|
||||
lv_fs_drv_init(&drv); /*Basic initialization*/
|
||||
|
||||
drv.letter = 'S'; /*An uppercase letter to identify the drive */
|
||||
drv.file_size = sizeof(my_file_object); /*Size required to store a file object*/
|
||||
drv.rddir_size = sizeof(my_dir_object); /*Size required to store a directory object (used by dir_open/close/read)*/
|
||||
drv.ready_cb = my_ready_cb; /*Callback to tell if the drive is ready to use */
|
||||
drv.open_cb = my_open_cb; /*Callback to open a file */
|
||||
drv.close_cb = my_close_cb; /*Callback to close a file */
|
||||
drv.read_cb = my_read_cb; /*Callback to read a file */
|
||||
drv.write_cb = my_write_cb; /*Callback to write a file */
|
||||
drv.seek_cb = my_seek_cb; /*Callback to seek in a file (Move cursor) */
|
||||
drv.tell_cb = my_tell_cb; /*Callback to tell the cursor position */
|
||||
drv.trunc_cb = my_trunc_cb; /*Callback to delete a file */
|
||||
drv.size_cb = my_size_cb; /*Callback to tell a file's size */
|
||||
drv.rename_cb = my_rename_cb; /*Callback to rename a file */
|
||||
|
||||
|
||||
drv.dir_open_cb = my_dir_open_cb; /*Callback to open directory to read its content */
|
||||
drv.dir_read_cb = my_dir_read_cb; /*Callback to read a directory's content */
|
||||
drv.dir_close_cb = my_dir_close_cb; /*Callback to close a directory */
|
||||
|
||||
drv.free_space_cb = my_free_space_cb; /*Callback to tell free space on the drive */
|
||||
|
||||
drv.user_data = my_user_data; /*Any custom data if required*/
|
||||
|
||||
lv_fs_drv_register(&drv); /*Finally register the drive*/
|
||||
|
||||
```
|
||||
|
||||
Any of the callbacks can be `NULL` to indicate that operation is not supported.
|
||||
|
||||
As an example of how the callbacks are used, if you use `lv_fs_open(&file, "S:/folder/file.txt", LV_FS_MODE_WR)`, LVGL:
|
||||
|
||||
1. Verifies that a registered drive exists with the letter `'S'`.
|
||||
2. Checks if it's `open_cb` is implemented (not `NULL`).
|
||||
3. Calls the set `open_cb` with `"folder/file.txt"` path.
|
||||
|
||||
## Usage example
|
||||
|
||||
The example below shows how to read from a file:
|
||||
```c
|
||||
lv_fs_file_t f;
|
||||
lv_fs_res_t res;
|
||||
res = lv_fs_open(&f, "S:folder/file.txt", LV_FS_MODE_RD);
|
||||
if(res != LV_FS_RES_OK) my_error_handling();
|
||||
|
||||
uint32_t read_num;
|
||||
uint8_t buf[8];
|
||||
res = lv_fs_read(&f, buf, 8, &read_num);
|
||||
if(res != LV_FS_RES_OK || read_num != 8) my_error_handling();
|
||||
|
||||
lv_fs_close(&f);
|
||||
```
|
||||
*The mode in `lv_fs_open` can be `LV_FS_MODE_WR` to open for write or `LV_FS_MODE_RD | LV_FS_MODE_WR` for both*
|
||||
|
||||
This example shows how to read a directory's content. It's up to the driver how to mark the directories, but it can be a good practice to insert a `'/'` in front of the directory name.
|
||||
```c
|
||||
lv_fs_dir_t dir;
|
||||
lv_fs_res_t res;
|
||||
res = lv_fs_dir_open(&dir, "S:/folder");
|
||||
if(res != LV_FS_RES_OK) my_error_handling();
|
||||
|
||||
char fn[256];
|
||||
while(1) {
|
||||
res = lv_fs_dir_read(&dir, fn);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
my_error_handling();
|
||||
break;
|
||||
}
|
||||
|
||||
/*fn is empty, if not more files to read*/
|
||||
if(strlen(fn) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
printf("%s\n", fn);
|
||||
}
|
||||
|
||||
lv_fs_dir_close(&dir);
|
||||
```
|
||||
|
||||
## Use drivers for images
|
||||
|
||||
[Image](/widgets/core/img) objects can be opened from files too (besides variables stored in the flash).
|
||||
|
||||
To initialize the image, the following callbacks are required:
|
||||
- open
|
||||
- close
|
||||
- read
|
||||
- seek
|
||||
- tell
|
||||
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_fs.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
255
fr3092_lvglcode/lvgl/docs/overview/font.md
Normal file
255
fr3092_lvglcode/lvgl/docs/overview/font.md
Normal file
@ -0,0 +1,255 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/font.md
|
||||
```
|
||||
# Fonts
|
||||
|
||||
In LVGL fonts are collections of bitmaps and other information required to render the images of the letters (glyph).
|
||||
A font is stored in a `lv_font_t` variable and can be set in style's *text_font* field. For example:
|
||||
```c
|
||||
lv_style_set_text_font(&my_style, LV_STATE_DEFAULT, &lv_font_montserrat_28); /*Set a larger font*/
|
||||
```
|
||||
|
||||
The fonts have a **bpp (bits per pixel)** property. It shows how many bits are used to describe a pixel in the font. The value stored for a pixel determines the pixel's opacity.
|
||||
This way, with higher *bpp*, the edges of the letter can be smoother. The possible *bpp* values are 1, 2, 4 and 8 (higher value means better quality).
|
||||
|
||||
The *bpp* also affects the required memory size to store the font. For example, *bpp = 4* makes the font nearly 4 times greater compared to *bpp = 1*.
|
||||
|
||||
## Unicode support
|
||||
|
||||
LVGL supports **UTF-8** encoded Unicode characters.
|
||||
Your editor needs to be configureed to save your code/text as UTF-8 (usually this the default) and be sure that, `LV_TXT_ENC` is set to `LV_TXT_ENC_UTF8` in *lv_conf.h*. (This is the default value)
|
||||
|
||||
To test it try
|
||||
```c
|
||||
lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL);
|
||||
lv_label_set_text(label1, LV_SYMBOL_OK);
|
||||
```
|
||||
|
||||
If all works well, a ✓ character should be displayed.
|
||||
|
||||
## Built-in fonts
|
||||
|
||||
There are several built-in fonts in different sizes, which can be enabled in `lv_conf.h` by *LV_FONT_...* defines.
|
||||
### Normal fonts
|
||||
Containing all the ASCII characters, the degree symbol (U+00B0), the bullet symbol (U+2022) and the build in symbols (see below).
|
||||
- `LV_FONT_MONTSERRAT_12` 12 px font
|
||||
- `LV_FONT_MONTSERRAT_14` 14 px font
|
||||
- `LV_FONT_MONTSERRAT_16` 16 px font
|
||||
- `LV_FONT_MONTSERRAT_18` 18 px font
|
||||
- `LV_FONT_MONTSERRAT_20` 20 px font
|
||||
- `LV_FONT_MONTSERRAT_22` 22 px font
|
||||
- `LV_FONT_MONTSERRAT_24` 24 px font
|
||||
- `LV_FONT_MONTSERRAT_26` 26 px font
|
||||
- `LV_FONT_MONTSERRAT_28` 28 px font
|
||||
- `LV_FONT_MONTSERRAT_30` 30 px font
|
||||
- `LV_FONT_MONTSERRAT_32` 32 px font
|
||||
- `LV_FONT_MONTSERRAT_34` 34 px font
|
||||
- `LV_FONT_MONTSERRAT_36` 36 px font
|
||||
- `LV_FONT_MONTSERRAT_38` 38 px font
|
||||
- `LV_FONT_MONTSERRAT_40` 40 px font
|
||||
- `LV_FONT_MONTSERRAT_42` 42 px font
|
||||
- `LV_FONT_MONTSERRAT_44` 44 px font
|
||||
- `LV_FONT_MONTSERRAT_46` 46 px font
|
||||
- `LV_FONT_MONTSERRAT_48` 48 px font
|
||||
|
||||
### Special fonts
|
||||
- `LV_FONT_MONTSERRAT_12_SUBPX` Same as normal 12 px font but with [subpixel rendering](#subpixel-rendering)
|
||||
- `LV_FONT_MONTSERRAT_28_COMPRESSED` Same as normal 28 px font but [compressed font](#compress-fonts) with 3 bpp
|
||||
- `LV_FONT_DEJAVU_16_PERSIAN_HEBREW` 16 px font with normal range + Hebrew, Arabic, Perisan letters and all their forms
|
||||
- `LV_FONT_SIMSUN_16_CJK`16 px font with normal range + 1000 most common CJK radicals
|
||||
- `LV_FONT_UNSCII_8` 8 px pixel perfect font with only ASCII characters
|
||||
- `LV_FONT_UNSCII_16` 16 px pixel perfect font with only ASCII characters
|
||||
|
||||
|
||||
The built-in fonts are **global variables** with names like `lv_font_montserrat_16` for 16 px hight font. To use them in a style, just add a pointer to a font variable like shown above.
|
||||
|
||||
The built-in fonts have *bpp = 4*, contains the ASCII characters and uses the [Montserrat](https://fonts.google.com/specimen/Montserrat) font.
|
||||
|
||||
In addition to the ASCII range, the following symbols are also added to the built-in fonts from the [FontAwesome](https://fontawesome.com/) font.
|
||||
|
||||

|
||||
|
||||
The symbols can be used as:
|
||||
```c
|
||||
lv_label_set_text(my_label, LV_SYMBOL_OK);
|
||||
```
|
||||
|
||||
Or with together with strings:
|
||||
```c
|
||||
lv_label_set_text(my_label, LV_SYMBOL_OK "Apply");
|
||||
```
|
||||
|
||||
Or more symbols together:
|
||||
```c
|
||||
lv_label_set_text(my_label, LV_SYMBOL_OK LV_SYMBOL_WIFI LV_SYMBOL_PLAY);
|
||||
```
|
||||
|
||||
## Special features
|
||||
|
||||
### Bidirectional support
|
||||
Most of the languages use Left-to-Right (LTR for short) writing direction, however some languages (such as Hebrew, Persian or Arabic) uses Right-to-Left (RTL for short) direction.
|
||||
|
||||
LVGL not only supports RTL texts but supports mixed (a.k.a. bidirectional, BiDi) text rendering too. Some examples:
|
||||
|
||||

|
||||
|
||||
The BiDi support can be enabled by `LV_USE_BIDI` in *lv_conf.h*
|
||||
|
||||
All texts have a base direction (LTR or RTL) which determines some rendering rules and the default alignment of the text (Left or Right).
|
||||
However, in LVGL, base direction is applied not only for labels. It's a general property which can be set for every object.
|
||||
If unset then it will be inherited from the parent.
|
||||
So it's enough to set the base direction of the screen and every object will inherit it.
|
||||
|
||||
The default base direction of screen can be set by `LV_BIDI_BASE_DIR_DEF` in *lv_conf.h* and other objects inherit the base direction from their parent.
|
||||
|
||||
To set an object's base direction use `lv_obj_set_base_dir(obj, base_dir)`. The possible base direction are:
|
||||
- `LV_BIDI_DIR_LTR`: Left to Right base direction
|
||||
- `LV_BIDI_DIR_RTL`: Right to Left base direction
|
||||
- `LV_BIDI_DIR_AUTO`: Auto detect base direction
|
||||
- `LV_BIDI_DIR_INHERIT`: Inherit the base direction from the parent (default for non-screen objects)
|
||||
|
||||
This list summarizes the effect of RTL base direction on objects:
|
||||
- Create objects by default on the right
|
||||
- `lv_tabview`: displays tabs from right to left
|
||||
- `lv_checkbox`: Show the box on the right
|
||||
- `lv_btnmatrix`: Show buttons from right to left
|
||||
- `lv_list`: Show the icon on the right
|
||||
- `lv_dropdown`: Align the options to the right
|
||||
- The texts in `lv_table`, `lv_btnmatrix`, `lv_keyboard`, `lv_tabview`, `lv_dropdown`, `lv_roller` are "BiDi processed" to be displayed correctly
|
||||
|
||||
### Arabic and Persian support
|
||||
There are some special rules to display Arabic and Persian characters: the *form* of the character depends on their position in the text.
|
||||
A different form of the same letter needs to be used if it isolated, start, middle or end position. Besides these some conjunction rules also should be taken into account.
|
||||
|
||||
LVGL supports to apply these rules if `LV_USE_ARABIC_PERSIAN_CHARS` is enabled.
|
||||
|
||||
However, there some limitations:
|
||||
- Only displaying texts is supported (e.g. on labels), text inputs (e.g. text area) doesn't support this feature
|
||||
- Static text (i.e. const) are not processed. E.g. texts set by `lv_label_set_text()` will "Arabic processed" but `lv_lable_set_text_static()` won't.
|
||||
- Text get functions (e.g. `lv_label_get_text()`) will return the processed text.
|
||||
|
||||
### Subpixel rendering
|
||||
|
||||
Subpixel rendering means to triple the horizontal resolution by rendering on Red, Green and Blue channel instead of pixel level. It takes advantage of the position of physical color channels of each pixel.
|
||||
It results in higher quality letter anti-aliasing. Lear more [here](https://en.wikipedia.org/wiki/Subpixel_rendering).
|
||||
|
||||
Subpixel rendering requires to generate the fonts with special settings:
|
||||
- In the online converter tick the `Subpixel` box
|
||||
- In the command line tool use `--lcd` flag. Note that the generated font needs about 3 times more memory.
|
||||
|
||||
Subpixel rendering works only if the color channels of the pixels have a horizontal layout. That is the R, G, B channels are next each other and not above each other.
|
||||
The order of color channels also needs to match with the library settings. By default the LVGL assumes `RGB` order, however it can be swapped by setting `LV_SUBPX_BGR 1` in *lv_conf.h*.
|
||||
|
||||
### Compress fonts
|
||||
The bitmaps of the fonts can be compressed by
|
||||
- ticking the `Compressed` check box in the online converter
|
||||
- not passing `--no-compress` flag to the offline converter (applies compression by default)
|
||||
|
||||
The compression is more effective with larger fonts and higher bpp. However, it's about 30% slower to render the compressed fonts.
|
||||
Therefore it's recommended to compress only the largest fonts of user interface, because
|
||||
- they need the most memory
|
||||
- they can be compressed better
|
||||
- and probably they are used less frequently then the medium sized fonts. (so performance cost is smaller)
|
||||
|
||||
## Add new font
|
||||
|
||||
There are several ways to add a new font to your project:
|
||||
1. The simplest method is to use the [Online font converter](https://lvgl.io/tools/fontconverter). Just set the parameters, click the *Convert* button, copy the font to your project and use it. **Be sure to carefully read the steps provided on that site or you will get an error while converting.**
|
||||
2. Use the [Offline font converter](https://github.com/lvgl/lv_font_conv). (Requires Node.js to be installed)
|
||||
3. If you want to create something like the built-in fonts (Roboto font and symbols) but in different size and/or ranges, you can use the `built_in_font_gen.py` script in `lvgl/scripts/built_in_font` folder.
|
||||
(It requires Python and `lv_font_conv` to be installed)
|
||||
|
||||
To declare the font in a file, use `LV_FONT_DECLARE(my_font_name)`.
|
||||
|
||||
To make the fonts globally available (like the builtin fonts), add them to `LV_FONT_CUSTOM_DECLARE` in *lv_conf.h*.
|
||||
|
||||
## Add new symbols
|
||||
The built-in symbols are created from [FontAwesome](https://fontawesome.com/) font.
|
||||
|
||||
1. Search symbol on [https://fontawesome.com](https://fontawesome.com). For example the [USB symbol](https://fontawesome.com/icons/usb?style=brands). Copy it's Unicode ID which is `0xf287` in this case.
|
||||
2. Open the [Online font converter](https://lvgl.io/tools/fontconverter). Add Add [FontAwesome.woff](https://lvgl.io/assets/others/FontAwesome5-Solid+Brands+Regular.woff). .
|
||||
3. Set the parameters such as Name, Size, BPP. You'll use this name to declare and use the font in your code.
|
||||
4. Add the Unicode ID of the symbol to the range field. E.g.` 0xf287` for the USB symbol. More symbols can be enumerated with `,`.
|
||||
5. Convert the font and copy it to your project. Make sure to compile the .c file of your font.
|
||||
6. Declare the font using `extern lv_font_t my_font_name;` or simply `LV_FONT_DECLARE(my_font_name);`.
|
||||
|
||||
**Using the symbol**
|
||||
1. Convert the Unicode value to UTF8. You can do it e.g on [this site](http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=f287&mode=hex). For `0xf287` the *Hex UTF-8 bytes* are `EF 8A 87`.
|
||||
2. Create a `define` from the UTF8 values: `#define MY_USB_SYMBOL "\xEF\x8A\x87"`
|
||||
3. Create a label and set the text. Eg. `lv_label_set_text(label, MY_USB_SYMBOL)`
|
||||
|
||||
Note - `lv_label_set_text(label, MY_USB_SYMBOL)` searches for this symbol in the font defined in `style.text.font` properties. To use the symbol you may need to change it. Eg ` style.text.font = my_font_name`
|
||||
|
||||
## Load font in run-time
|
||||
`lv_font_load` can be used to load a font from a file. The font to load needs to have a special binary format. (Not TTF or WOFF).
|
||||
Use [lv_font_conv](https://github.com/lvgl/lv_font_conv/) with `--format bin` option to generate an LVGL compatible font file.
|
||||
|
||||
Note that to load a font [LVGL's filesystem](/overview/file-system) needs to be enabled and a driver needs to be added.
|
||||
|
||||
Example
|
||||
```c
|
||||
lv_font_t * my_font;
|
||||
my_font = lv_font_load(X/path/to/my_font.bin);
|
||||
|
||||
/*Use the font*/
|
||||
|
||||
/*Free the font if not required anymore*/
|
||||
lv_font_free(my_font);
|
||||
```
|
||||
|
||||
|
||||
## Add a new font engine
|
||||
|
||||
LVGL's font interface is designed to be very flexible.
|
||||
You don't need to use LVGL's internal font engine but, you can add your own.
|
||||
For example, use [FreeType](https://www.freetype.org/) to real-time render glyphs from TTF fonts or use an external flash to store the font's bitmap and read them when the library needs them.
|
||||
|
||||
A ready to use FreeType can be found in [lv_freetype](https://github.com/lvgl/lv_lib_freetype) repository.
|
||||
|
||||
To do this a custom `lv_font_t` variable needs to be created:
|
||||
```c
|
||||
/*Describe the properties of a font*/
|
||||
lv_font_t my_font;
|
||||
my_font.get_glyph_dsc = my_get_glyph_dsc_cb; /*Set a callback to get info about gylphs*/
|
||||
my_font.get_glyph_bitmap = my_get_glyph_bitmap_cb; /*Set a callback to get bitmap of a glyp*/
|
||||
my_font.line_height = height; /*The real line height where any text fits*/
|
||||
my_font.base_line = base_line; /*Base line measured from the top of line_height*/
|
||||
my_font.dsc = something_required; /*Store any implementation specific data here*/
|
||||
my_font.user_data = user_data; /*Optionally some extra user data*/
|
||||
|
||||
...
|
||||
|
||||
/* Get info about glyph of `unicode_letter` in `font` font.
|
||||
* Store the result in `dsc_out`.
|
||||
* The next letter (`unicode_letter_next`) might be used to calculate the width required by this glyph (kerning)
|
||||
*/
|
||||
bool my_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next)
|
||||
{
|
||||
/*Your code here*/
|
||||
|
||||
/* Store the result.
|
||||
* For example ...
|
||||
*/
|
||||
dsc_out->adv_w = 12; /*Horizontal space required by the glyph in [px]*/
|
||||
dsc_out->box_h = 8; /*Height of the bitmap in [px]*/
|
||||
dsc_out->box_w = 6; /*Width of the bitmap in [px]*/
|
||||
dsc_out->ofs_x = 0; /*X offset of the bitmap in [pf]*/
|
||||
dsc_out->ofs_y = 3; /*Y offset of the bitmap measured from the as line*/
|
||||
dsc_out->bpp = 2; /*Bits per pixel: 1/2/4/8*/
|
||||
|
||||
return true; /*true: glyph found; false: glyph was not found*/
|
||||
}
|
||||
|
||||
|
||||
/* Get the bitmap of `unicode_letter` from `font`. */
|
||||
const uint8_t * my_get_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter)
|
||||
{
|
||||
/* Your code here */
|
||||
|
||||
/* The bitmap should be a continuous bitstream where
|
||||
* each pixel is represented by `bpp` bits */
|
||||
|
||||
return bitmap; /*Or NULL if not found*/
|
||||
}
|
||||
```
|
330
fr3092_lvglcode/lvgl/docs/overview/image.md
Normal file
330
fr3092_lvglcode/lvgl/docs/overview/image.md
Normal file
@ -0,0 +1,330 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/image.md
|
||||
```
|
||||
# Images
|
||||
|
||||
An image can be a file or variable which stores the bitmap itself and some metadata.
|
||||
|
||||
## Store images
|
||||
You can store images in two places
|
||||
- as a variable in the internal memory (RAM or ROM)
|
||||
- as a file
|
||||
|
||||
### Variables
|
||||
The images stored internally in a variable is composed mainly of an `lv_img_dsc_t` structure with the following fields:
|
||||
- **header**
|
||||
- *cf* Color format. See [below](#color-format)
|
||||
- *w* width in pixels (<= 2048)
|
||||
- *h* height in pixels (<= 2048)
|
||||
- *always zero* 3 bits which need to be always zero
|
||||
- *reserved* reserved for future use
|
||||
- **data** pointer to an array where the image itself is stored
|
||||
- **data_size** length of `data` in bytes
|
||||
|
||||
These are usually stored within a project as C files. They are linked into the resulting executable like any other constant data.
|
||||
|
||||
### Files
|
||||
To deal with files you need to add a *Drive* to LVGL. In short, a *Drive* is a collection of functions (*open*, *read*, *close*, etc.) registered in LVGL to make file operations.
|
||||
You can add an interface to a standard file system (FAT32 on SD card) or you create your simple file system to read data from an SPI Flash memory.
|
||||
In every case, a *Drive* is just an abstraction to read and/or write data to a memory.
|
||||
See the [File system](/overview/file-system) section to learn more.
|
||||
|
||||
Images stored as files are not linked into the resulting executable, and must be read to RAM before being drawn. As a result, they are not as resource-friendly as variable images. However, they are easier to replace without needing to recompile the main program.
|
||||
|
||||
## Color formats
|
||||
Various built-in color formats are supported:
|
||||
- **LV_IMG_CF_TRUE_COLOR** Simply stores the RGB colors (in whatever color depth LVGL is configured for).
|
||||
- **LV_IMG_CF_TRUE_COLOR_ALPHA** Like `LV_IMG_CF_TRUE_COLOR` but it also adds an alpha (transparency) byte for every pixel.
|
||||
- **LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED** Like `LV_IMG_CF_TRUE_COLOR` but if a pixel has `LV_COLOR_TRANSP` (set in *lv_conf.h*) color the pixel will be transparent.
|
||||
- **LV_IMG_CF_INDEXED_1/2/4/8BIT** Uses a palette with 2, 4, 16 or 256 colors and stores each pixel in 1, 2, 4 or 8 bits.
|
||||
- **LV_IMG_CF_ALPHA_1/2/4/8BIT** **Only stores the Alpha value on 1, 2, 4 or 8 bits.** The pixels take the color of `style.image.color` and the set opacity. The source image has to be an alpha channel. This is ideal for bitmaps similar to fonts (where the whole image is one color but you'd like to be able to change it).
|
||||
|
||||
The bytes of the `LV_IMG_CF_TRUE_COLOR` images are stored in the following order.
|
||||
|
||||
For 32-bit color depth:
|
||||
- Byte 0: Blue
|
||||
- Byte 1: Green
|
||||
- Byte 2: Red
|
||||
- Byte 3: Alpha
|
||||
|
||||
For 16-bit color depth:
|
||||
- Byte 0: Green 3 lower bit, Blue 5 bit
|
||||
- Byte 1: Red 5 bit, Green 3 higher bit
|
||||
- Byte 2: Alpha byte (only with LV_IMG_CF_TRUE_COLOR_ALPHA)
|
||||
|
||||
For 8-bit color depth:
|
||||
- Byte 0: Red 3 bit, Green 3 bit, Blue 2 bit
|
||||
- Byte 2: Alpha byte (only with LV_IMG_CF_TRUE_COLOR_ALPHA)
|
||||
|
||||
|
||||
You can store images in a *Raw* format to indicate that, it's not a built-in color format and an external [Image decoder](#image-decoder) needs to be used to decode the image.
|
||||
- **LV_IMG_CF_RAW** Indicates a basic raw image (e.g. a PNG or JPG image).
|
||||
- **LV_IMG_CF_RAW_ALPHA** Indicates that the image has alpha and an alpha byte is added for every pixel.
|
||||
- **LV_IMG_CF_RAW_CHROME_KEYED** Indicates that the image is chrome keyed as described in `LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED` above.
|
||||
|
||||
|
||||
## Add and use images
|
||||
|
||||
You can add images to LVGL in two ways:
|
||||
- using the online converter
|
||||
- manually create images
|
||||
|
||||
### Online converter
|
||||
The online Image converter is available here: https://lvgl.io/tools/imageconverter
|
||||
|
||||
Adding an image to LVGL via online converter is easy.
|
||||
|
||||
1. You need to select a *BMP*, *PNG* or *JPG* image first.
|
||||
2. Give the image a name that will be used within LVGL.
|
||||
3. Select the [Color format](#color-formats).
|
||||
4. Select the type of image you want. Choosing a binary will generate a `.bin` file that must be stored separately and read using the [file support](#files). Choosing a variable will generate a standard C file that can be linked into your project.
|
||||
5. Hit the *Convert* button. Once the conversion is finished, your browser will automatically download the resulting file.
|
||||
|
||||
In the converter C arrays (variables), the bitmaps for all the color depths (1, 8, 16 or 32) are included in the C file, but only the color depth that matches `LV_COLOR_DEPTH` in *lv_conf.h* will actually be linked into the resulting executable.
|
||||
|
||||
In case of binary files, you need to specify the color format you want:
|
||||
- RGB332 for 8-bit color depth
|
||||
- RGB565 for 16-bit color depth
|
||||
- RGB565 Swap for 16-bit color depth (two bytes are swapped)
|
||||
- RGB888 for 32-bit color depth
|
||||
|
||||
### Manually create an image
|
||||
If you are generating an image at run-time, you can craft an image variable to display it using LVGL. For example:
|
||||
|
||||
```c
|
||||
uint8_t my_img_data[] = {0x00, 0x01, 0x02, ...};
|
||||
|
||||
static lv_img_dsc_t my_img_dsc = {
|
||||
.header.always_zero = 0,
|
||||
.header.w = 80,
|
||||
.header.h = 60,
|
||||
.data_size = 80 * 60 * LV_COLOR_DEPTH / 8,
|
||||
.header.cf = LV_IMG_CF_TRUE_COLOR, /*Set the color format*/
|
||||
.data = my_img_data,
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
If the color format is `LV_IMG_CF_TRUE_COLOR_ALPHA` you can set `data_size` like `80 * 60 * LV_IMG_PX_SIZE_ALPHA_BYTE`.
|
||||
|
||||
Another (possibly simpler) option to create and display an image at run-time is to use the [Canvas](/widgets/core/canvas) object.
|
||||
|
||||
### Use images
|
||||
|
||||
The simplest way to use an image in LVGL is to display it with an [lv_img](/widgets/core/img) object:
|
||||
|
||||
```c
|
||||
lv_obj_t * icon = lv_img_create(lv_scr_act(), NULL);
|
||||
|
||||
/*From variable*/
|
||||
lv_img_set_src(icon, &my_icon_dsc);
|
||||
|
||||
/*From file*/
|
||||
lv_img_set_src(icon, "S:my_icon.bin");
|
||||
```
|
||||
|
||||
If the image was converted with the online converter, you should use `LV_IMG_DECLARE(my_icon_dsc)` to declare the image in the file where you want to use it.
|
||||
|
||||
|
||||
## Image decoder
|
||||
As you can see in the [Color formats](#color-formats) section, LVGL supports several built-in image formats. In many cases, these will be all you need. LVGL doesn't directly support, however, generic image formats like PNG or JPG.
|
||||
|
||||
To handle non-built-in image formats, you need to use external libraries and attach them to LVGL via the *Image decoder* interface.
|
||||
|
||||
The image decoder consists of 4 callbacks:
|
||||
- **info** get some basic info about the image (width, height and color format).
|
||||
- **open** open the image: either store the decoded image or set it to `NULL` to indicate the image can be read line-by-line.
|
||||
- **read** if *open* didn't fully open the image this function should give some decoded data (max 1 line) from a given position.
|
||||
- **close** close the opened image, free the allocated resources.
|
||||
|
||||
You can add any number of image decoders. When an image needs to be drawn, the library will try all the registered image decoder until finding one which can open the image, i.e. knowing that format.
|
||||
|
||||
The `LV_IMG_CF_TRUE_COLOR_...`, `LV_IMG_INDEXED_...` and `LV_IMG_ALPHA_...` formats (essentially, all non-`RAW` formats) are understood by the built-in decoder.
|
||||
|
||||
### Custom image formats
|
||||
|
||||
The easiest way to create a custom image is to use the online image converter and set `Raw`, `Raw with alpha` or `Raw with chrome keyed` format. It will just take every byte of the binary file you uploaded and write it as the image "bitmap". You then need to attach an image decoder that will parse that bitmap and generate the real, renderable bitmap.
|
||||
|
||||
`header.cf` will be `LV_IMG_CF_RAW`, `LV_IMG_CF_RAW_ALPHA` or `LV_IMG_CF_RAW_CHROME_KEYED` accordingly. You should choose the correct format according to your needs: fully opaque image, use alpha channel or use chroma keying.
|
||||
|
||||
After decoding, the *raw* formats are considered *True color* by the library. In other words, the image decoder must decode the *Raw* images to *True color* according to the format described in [#color-formats](Color formats) section.
|
||||
|
||||
If you want to create a custom image, you should use `LV_IMG_CF_USER_ENCODED_0..7` color formats. However, the library can draw the images only in *True color* format (or *Raw* but finally it's supposed to be in *True color* format).
|
||||
So the `LV_IMG_CF_USER_ENCODED_...` formats are not known by the library, therefore, they should be decoded to one of the known formats from [#color-formats](Color formats) section.
|
||||
It's possible to decode the image to a non-true color format first, for example, `LV_IMG_INDEXED_4BITS`, and then call the built-in decoder functions to convert it to *True color*.
|
||||
|
||||
With *User encoded* formats, the color format in the open function (`dsc->header.cf`) should be changed according to the new format.
|
||||
|
||||
|
||||
### Register an image decoder
|
||||
|
||||
Here's an example of getting LVGL to work with PNG images.
|
||||
|
||||
First, you need to create a new image decoder and set some functions to open/close the PNG files. It should looks like this:
|
||||
|
||||
```c
|
||||
/*Create a new decoder and register functions */
|
||||
lv_img_decoder_t * dec = lv_img_decoder_create();
|
||||
lv_img_decoder_set_info_cb(dec, decoder_info);
|
||||
lv_img_decoder_set_open_cb(dec, decoder_open);
|
||||
lv_img_decoder_set_close_cb(dec, decoder_close);
|
||||
|
||||
|
||||
/**
|
||||
* Get info about a PNG image
|
||||
* @param decoder pointer to the decoder where this function belongs
|
||||
* @param src can be file name or pointer to a C array
|
||||
* @param header store the info here
|
||||
* @return LV_RES_OK: no error; LV_RES_INV: can't get the info
|
||||
*/
|
||||
static lv_res_t decoder_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header)
|
||||
{
|
||||
/*Check whether the type `src` is known by the decoder*/
|
||||
if(is_png(src) == false) return LV_RES_INV;
|
||||
|
||||
/* Read the PNG header and find `width` and `height` */
|
||||
...
|
||||
|
||||
header->cf = LV_IMG_CF_RAW_ALPHA;
|
||||
header->w = width;
|
||||
header->h = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a PNG image and return the decided image
|
||||
* @param decoder pointer to the decoder where this function belongs
|
||||
* @param dsc pointer to a descriptor which describes this decoding session
|
||||
* @return LV_RES_OK: no error; LV_RES_INV: can't get the info
|
||||
*/
|
||||
static lv_res_t decoder_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)
|
||||
{
|
||||
|
||||
/*Check whether the type `src` is known by the decoder*/
|
||||
if(is_png(src) == false) return LV_RES_INV;
|
||||
|
||||
/*Decode and store the image. If `dsc->img_data` is `NULL`, the `read_line` function will be called to get the image data line-by-line*/
|
||||
dsc->img_data = my_png_decoder(src);
|
||||
|
||||
/*Change the color format if required. For PNG usually 'Raw' is fine*/
|
||||
dsc->header.cf = LV_IMG_CF_...
|
||||
|
||||
/*Call a built in decoder function if required. It's not required if`my_png_decoder` opened the image in true color format.*/
|
||||
lv_res_t res = lv_img_decoder_built_in_open(decoder, dsc);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.
|
||||
* Required only if the "open" function can't open the whole decoded pixel array. (dsc->img_data == NULL)
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
* @param x start x coordinate
|
||||
* @param y start y coordinate
|
||||
* @param len number of pixels to decode
|
||||
* @param buf a buffer to store the decoded pixels
|
||||
* @return LV_RES_OK: ok; LV_RES_INV: failed
|
||||
*/
|
||||
lv_res_t decoder_built_in_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x,
|
||||
lv_coord_t y, lv_coord_t len, uint8_t * buf)
|
||||
{
|
||||
/*With PNG it's usually not required*/
|
||||
|
||||
/*Copy `len` pixels from `x` and `y` coordinates in True color format to `buf` */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the allocated resources
|
||||
* @param decoder pointer to the decoder where this function belongs
|
||||
* @param dsc pointer to a descriptor which describes this decoding session
|
||||
*/
|
||||
static void decoder_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)
|
||||
{
|
||||
/*Free all allocated data*/
|
||||
|
||||
/*Call the built-in close function if the built-in open/read_line was used*/
|
||||
lv_img_decoder_built_in_close(decoder, dsc);
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
So in summary:
|
||||
- In `decoder_info`, you should collect some basic information about the image and store it in `header`.
|
||||
- In `decoder_open`, you should try to open the image source pointed by `dsc->src`. Its type is already in `dsc->src_type == LV_IMG_SRC_FILE/VARIABLE`.
|
||||
If this format/type is not supported by the decoder, return `LV_RES_INV`.
|
||||
However, if you can open the image, a pointer to the decoded *True color* image should be set in `dsc->img_data`.
|
||||
If the format is known but, you don't want to decode while image (e.g. no memory for it) set `dsc->img_data = NULL` to call `read_line` to get the pixels.
|
||||
- In `decoder_close` you should free all the allocated resources.
|
||||
- `decoder_read` is optional. Decoding the whole image requires extra memory and some computational overhead.
|
||||
However, if can decode one line of the image without decoding the whole image, you can save memory and time.
|
||||
To indicate that, the *line read* function should be used, set `dsc->img_data = NULL` in the open function.
|
||||
|
||||
|
||||
### Manually use an image decoder
|
||||
|
||||
LVGL will use the registered image decoder automatically if you try and draw a raw image (i.e. using the `lv_img` object) but you can use them manually too. Create a `lv_img_decoder_dsc_t` variable to describe the decoding session and call `lv_img_decoder_open()`.
|
||||
|
||||
```c
|
||||
|
||||
lv_res_t res;
|
||||
lv_img_decoder_dsc_t dsc;
|
||||
res = lv_img_decoder_open(&dsc, &my_img_dsc, LV_COLOR_WHITE);
|
||||
|
||||
if(res == LV_RES_OK) {
|
||||
/*Do something with `dsc->img_data`*/
|
||||
lv_img_decoder_close(&dsc);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Image caching
|
||||
Sometimes it takes a lot of time to open an image.
|
||||
Continuously decoding a PNG image or loading images from a slow external memory would be inefficient and detrimental to the user experience.
|
||||
|
||||
Therefore, LVGL caches a given number of images. Caching means some images will be left open, hence LVGL can quickly access them from `dsc->img_data` instead of needing to decode them again.
|
||||
|
||||
Of course, caching images is resource-intensive as it uses more RAM (to store the decoded image). LVGL tries to optimize the process as much as possible (see below), but you will still need to evaluate if this would be beneficial for your platform or not. If you have a deeply embedded target which decodes small images from a relatively fast storage medium, image caching may not be worth it.
|
||||
|
||||
### Cache size
|
||||
The number of cache entries can be defined in `LV_IMG_CACHE_DEF_SIZE` in *lv_conf.h*. The default value is 1 so only the most recently used image will be left open.
|
||||
|
||||
The size of the cache can be changed at run-time with `lv_img_cache_set_size(entry_num)`.
|
||||
|
||||
### Value of images
|
||||
When you use more images than cache entries, LVGL can't cache all of the images. Instead, the library will close one of the cached images (to free space).
|
||||
|
||||
To decide which image to close, LVGL uses a measurement it previously made of how long it took to open the image. Cache entries that hold slower-to-open images are considered more valuable and are kept in the cache as long as possible.
|
||||
|
||||
If you want or need to override LVGL's measurement, you can manually set the *time to open* value in the decoder open function in `dsc->time_to_open = time_ms` to give a higher or lower value. (Leave it unchanged to let LVGL set it.)
|
||||
|
||||
Every cache entry has a *"life"* value. Every time an image opening happens through the cache, the *life* of all entries are decreased to make them older.
|
||||
When a cached image is used, its *life* is increased by the *time to open* value to make it more alive.
|
||||
|
||||
If there is no more space in the cache, always the entry with the smallest life will be closed.
|
||||
|
||||
### Memory usage
|
||||
Note that, the cached image might continuously consume memory. For example, if 3 PNG images are cached, they will consume memory while they are opened.
|
||||
|
||||
Therefore, it's the user's responsibility to be sure there is enough RAM to cache, even the largest images at the same time.
|
||||
|
||||
### Clean the cache
|
||||
Let's say you have loaded a PNG image into a `lv_img_dsc_t my_png` variable and use it in an `lv_img` object. If the image is already cached and you then change the underlying PNG file, you need to notify LVGL to cache the image again. Otherwise, there is no easy way of detecting that the underlying file changed and LVGL will still draw the old image.
|
||||
|
||||
To do this, use `lv_img_cache_invalidate_src(&my_png)`. If `NULL` is passed as a parameter, the whole cache will be cleaned.
|
||||
|
||||
|
||||
## API
|
||||
|
||||
|
||||
### Image buffer
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_img_buf.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
112
fr3092_lvglcode/lvgl/docs/overview/indev.md
Normal file
112
fr3092_lvglcode/lvgl/docs/overview/indev.md
Normal file
@ -0,0 +1,112 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/indev.md
|
||||
```
|
||||
# Input devices
|
||||
|
||||
An input device usually means:
|
||||
- Pointer-like input device like touchpad or mouse
|
||||
- Keypads like a normal keyboard or simple numeric keypad
|
||||
- Encoders with left/right turn and push options
|
||||
- External hardware buttons which are assigned to specific points on the screen
|
||||
|
||||
|
||||
``` important:: Before reading further, please read the [Porting](/porting/indev) section of Input devices
|
||||
```
|
||||
|
||||
## Pointers
|
||||
|
||||
Pointer input devices can have a cursor. (typically for mouses)
|
||||
|
||||
```c
|
||||
...
|
||||
lv_indev_t * mouse_indev = lv_indev_drv_register(&indev_drv);
|
||||
|
||||
LV_IMG_DECLARE(mouse_cursor_icon); /*Declare the image file.*/
|
||||
lv_obj_t * cursor_obj = lv_img_create(lv_scr_act(), NULL); /*Create an image object for the cursor */
|
||||
lv_img_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/
|
||||
lv_indev_set_cursor(mouse_indev, cursor_obj); /*Connect the image object to the driver*/
|
||||
|
||||
```
|
||||
|
||||
Note that the cursor object should have `lv_obj_set_click(cursor_obj, false)`.
|
||||
For images, *clicking* is disabled by default.
|
||||
|
||||
## Keypad and encoder
|
||||
|
||||
You can fully control the user interface without touchpad or mouse using a keypad or encoder(s). It works similar to the *TAB* key on the PC to select the element in an application or a web page.
|
||||
|
||||
### Groups
|
||||
|
||||
The objects, you want to control with keypad or encoder, needs to be added to a *Group*.
|
||||
In every group, there is exactly one focused object which receives the pressed keys or the encoder actions.
|
||||
For example, if a [Text area](/widgets/core/textarea) is focused and you press some letter on a keyboard, the keys will be sent and inserted into the text area.
|
||||
Similarly, if a [Slider](/widgets/core/slider) is focused and you press the left or right arrows, the slider's value will be changed.
|
||||
|
||||
You need to associate an input device with a group. An input device can send the keys to only one group but, a group can receive data from more than one input device too.
|
||||
|
||||
To create a group use `lv_group_t * g = lv_group_create()` and to add an object to the group use `lv_group_add_obj(g, obj)`.
|
||||
|
||||
To associate a group with an input device use `lv_indev_set_group(indev, g)`, where `indev` is the return value of `lv_indev_drv_register()`
|
||||
|
||||
#### Keys
|
||||
There are some predefined keys which have special meaning:
|
||||
- **LV_KEY_NEXT** Focus on the next object
|
||||
- **LV_KEY_PREV** Focus on the previous object
|
||||
- **LV_KEY_ENTER** Triggers `LV_EVENT_PRESSED/CLICKED/LONG_PRESSED` etc. events
|
||||
- **LV_KEY_UP** Increase value or move upwards
|
||||
- **LV_KEY_DOWN** Decrease value or move downwards
|
||||
- **LV_KEY_RIGHT** Increase value or move the the right
|
||||
- **LV_KEY_LEFT** Decrease value or move the the left
|
||||
- **LV_KEY_ESC** Close or exit (E.g. close a [Drop down list](/widgets/core/dropdown))
|
||||
- **LV_KEY_DEL** Delete (E.g. a character on the right in a [Text area](/widgets/core/textarea))
|
||||
- **LV_KEY_BACKSPACE** Delete a character on the left (E.g. in a [Text area](/widgets/core/textarea))
|
||||
- **LV_KEY_HOME** Go to the beginning/top (E.g. in a [Text area](/widgets/core/textarea))
|
||||
- **LV_KEY_END** Go to the end (E.g. in a [Text area](/widgets/core/textarea)))
|
||||
|
||||
The most important special keys are `LV_KEY_NEXT/PREV`, `LV_KEY_ENTER` and `LV_KEY_UP/DOWN/LEFT/RIGHT`.
|
||||
In your `read_cb` function, you should translate some of your keys to these special keys to navigate in the group and interact with the selected object.
|
||||
|
||||
Usually, it's enough to use only `LV_KEY_LEFT/RIGHT` because most of the objects can be fully controlled with them.
|
||||
|
||||
With an encoder, you should use only `LV_KEY_LEFT`, `LV_KEY_RIGHT`, and `LV_KEY_ENTER`.
|
||||
|
||||
#### Edit and navigate mode
|
||||
|
||||
Since a keypad has plenty of keys, it's easy to navigate between the objects and edit them using the keypad. But, the encoders have a limited number of "keys" hence, it is difficult to navigate using the default options. *Navigate* and *Edit* are created to avoid this problem with the encoders.
|
||||
|
||||
In *Navigate* mode, the encoders `LV_KEY_LEFT/RIGHT` is translated to `LV_KEY_NEXT/PREV`. Therefore the next or previous object will be selected by turning the encoder.
|
||||
Pressing `LV_KEY_ENTER` will change to *Edit* mode.
|
||||
|
||||
In *Edit* mode, `LV_KEY_NEXT/PREV` is usually used to edit the object.
|
||||
Depending on the object's type, a short or long press of `LV_KEY_ENTER` changes back to *Navigate* mode.
|
||||
Usually, an object which can not be pressed (like a [Slider](/widgets/core/slider)) leaves *Edit* mode on short click. But with objects where short click has meaning (e.g. [Button](/widgets/core/btn)), a long press is required.
|
||||
|
||||
### Styling
|
||||
|
||||
If an object is focused either by clicking it via touchpad, or focused via an encoder or keypad it goes to `LV_STATE_FOCUSED`. Hence focused styles will be applied on it.
|
||||
|
||||
If the object goes to edit mode it goes to `LV_STATE_FOCUSED | LV_STATE_EDITED` state so these style properties will be shown.
|
||||
|
||||
For a more detaild description read the [Style](https://docs.lvgl.io/v7/en/html/overview/style.html) section.
|
||||
|
||||
## API
|
||||
|
||||
|
||||
### Input device
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_indev.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
||||
|
||||
### Groups
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_group.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
31
fr3092_lvglcode/lvgl/docs/overview/index.md
Normal file
31
fr3092_lvglcode/lvgl/docs/overview/index.md
Normal file
@ -0,0 +1,31 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/index.md
|
||||
```
|
||||
|
||||
# Overview
|
||||
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
object
|
||||
coords
|
||||
style
|
||||
style-props
|
||||
scroll
|
||||
layer
|
||||
event
|
||||
indev
|
||||
display
|
||||
font
|
||||
image
|
||||
file-system
|
||||
animation
|
||||
timer
|
||||
drawing
|
||||
new_widget
|
||||
```
|
||||
|
60
fr3092_lvglcode/lvgl/docs/overview/layer.md
Normal file
60
fr3092_lvglcode/lvgl/docs/overview/layer.md
Normal file
@ -0,0 +1,60 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/layer.md
|
||||
```
|
||||
|
||||
# Layers
|
||||
|
||||
## Order of creation
|
||||
|
||||
By default, LVGL draws old objects on the background and new objects on the foreground.
|
||||
|
||||
For example, assume we added a button to a parent object named button1 and then another button named button2. Then button1 (with its child object(s)) will be in the background and can be covered by button2 and its children.
|
||||
|
||||
|
||||

|
||||
|
||||
```c
|
||||
/*Create a screen*/
|
||||
lv_obj_t * scr = lv_obj_create(NULL, NULL);
|
||||
lv_scr_load(scr); /*Load the screen*/
|
||||
|
||||
/*Create 2 buttons*/
|
||||
lv_obj_t * btn1 = lv_btn_create(scr, NULL); /*Create a button on the screen*/
|
||||
lv_btn_set_fit(btn1, true, true); /*Enable to automatically set the size according to the content*/
|
||||
lv_obj_set_pos(btn1, 60, 40); /*Set the position of the button*/
|
||||
|
||||
lv_obj_t * btn2 = lv_btn_create(scr, btn1); /*Copy the first button*/
|
||||
lv_obj_set_pos(btn2, 180, 80); /*Set the position of the button*/
|
||||
|
||||
/*Add labels to the buttons*/
|
||||
lv_obj_t * label1 = lv_label_create(btn1, NULL); /*Create a label on the first button*/
|
||||
lv_label_set_text(label1, "Button 1"); /*Set the text of the label*/
|
||||
|
||||
lv_obj_t * label2 = lv_label_create(btn2, NULL); /*Create a label on the second button*/
|
||||
lv_label_set_text(label2, "Button 2"); /*Set the text of the label*/
|
||||
|
||||
/*Delete the second label*/
|
||||
lv_obj_del(label2);
|
||||
```
|
||||
|
||||
## Bring to the foreground
|
||||
|
||||
There are several ways to bring an object to the foreground:
|
||||
- Use `lv_obj_set_top(obj, true)`. If `obj` or any of its children is clicked, then LVGL will automatically bring the object to the foreground.
|
||||
It works similarly to a typical GUI on a PC. When a window in the background is clicked, it will come to the foreground automatically.
|
||||
- Use `lv_obj_move_foreground(obj)` to explicitly tell the library to bring an object to the foreground. Similarly, use `lv_obj_move_background(obj)` to move to the background.
|
||||
- When `lv_obj_set_parent(obj, new_parent)` is used, `obj` will be on the foreground on the `new_parent`.
|
||||
|
||||
|
||||
## Top and sys layers
|
||||
|
||||
LVGL uses two special layers named as `layer_top` and `layer_sys`.
|
||||
Both are visible and common on all screens of a display. **They are not, however, shared among multiple physical displays.** The `layer_top` is always on top of the default screen (`lv_scr_act()`), and `layer_sys` is on top of `layer_top`.
|
||||
|
||||
The `layer_top` can be used by the user to create some content visible everywhere. For example, a menu bar, a pop-up, etc. If the `click` attribute is enabled, then `layer_top` will absorb all user click and acts as a modal.
|
||||
```c
|
||||
lv_obj_set_click(lv_layer_top(), true);
|
||||
```
|
||||
|
||||
The `layer_sys` is also used for a similar purpose on LVGL. For example, it places the mouse cursor above all layers to be sure it's always visible.
|
7
fr3092_lvglcode/lvgl/docs/overview/new_widget.md
Normal file
7
fr3092_lvglcode/lvgl/docs/overview/new_widget.md
Normal file
@ -0,0 +1,7 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/new_widget.md
|
||||
```
|
||||
|
||||
# New widget
|
||||
|
218
fr3092_lvglcode/lvgl/docs/overview/object.md
Normal file
218
fr3092_lvglcode/lvgl/docs/overview/object.md
Normal file
@ -0,0 +1,218 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/object.md
|
||||
```
|
||||
# Objects
|
||||
|
||||
In the LVGL the **basic building blocks** of a user interface are the objects, also called *Widgets*.
|
||||
For example a [Button](/widgets/core/btn), [Label](/widgets/core/label), [Image](/widgets/core/img), [List](/widgets/extra/list), [Chart](/widgets/extra/chart) or [Text area](/widgets/core/textarea).
|
||||
|
||||
Check all the [Object types](/widgets/index) here.
|
||||
|
||||
All objects are referenced using an `lv_obj_t` pointer as a handle. This pointer can later be used to set or get the attributes of the object.
|
||||
|
||||
## Attributes
|
||||
|
||||
### Basic attributes
|
||||
|
||||
All object types share some basic attributes:
|
||||
- Position
|
||||
- Size
|
||||
- Parent
|
||||
- Styles
|
||||
- Event handlers
|
||||
- Etc
|
||||
|
||||
You can set/get these attributes with `lv_obj_set_...` and `lv_obj_get_...` functions. For example:
|
||||
|
||||
```c
|
||||
/*Set basic object attributes*/
|
||||
lv_obj_set_size(btn1, 100, 50); /*Set a button's size*/
|
||||
lv_obj_set_pos(btn1, 20,30); /*Set a button's position*/
|
||||
```
|
||||
|
||||
To see all the available functions visit the [Base object's documentation](/widgets/obj).
|
||||
|
||||
### Specific attributes
|
||||
|
||||
The object types have special attributes too. For example, a slider has
|
||||
- Minimum and maximum values
|
||||
- Current value
|
||||
|
||||
For these attributes, every object type have unique API functions. For example for a slider:
|
||||
|
||||
```c
|
||||
/*Set slider specific attributes*/
|
||||
lv_slider_set_range(slider1, 0, 100); /*Set the min. and max. values*/
|
||||
lv_slider_set_value(slider1, 40, LV_ANIM_ON); /*Set the current value (position)*/
|
||||
```
|
||||
|
||||
The API of the widgets is described in their [Documentation](/widgets/index) but you can also check the respective header files (e.g. *widgets/lv_slider.h*)
|
||||
|
||||
## Working mechanisms
|
||||
|
||||
### Parent-child structure
|
||||
|
||||
A parent object can be considered as the container of its children. Every object has exactly one parent object (except screens), but a parent can have any number of children.
|
||||
There is no limitation for the type of the parent but, there are typical parent (e.g. button) and typical child (e.g. label) objects.
|
||||
|
||||
### Moving together
|
||||
|
||||
If the position of the parent changes the children will move with the parent.
|
||||
Therefore all positions are relative to the parent.
|
||||
|
||||

|
||||
|
||||
```c
|
||||
lv_obj_t * parent = lv_obj_create(lv_scr_act()); /*Create a parent object on the current screen*/
|
||||
lv_obj_set_size(parent, 100, 80); /*Set the size of the parent*/
|
||||
|
||||
lv_obj_t * obj1 = lv_obj_create(parent); /*Create an object on the previously created parent object*/
|
||||
lv_obj_set_pos(obj1, 10, 10); /*Set the position of the new object*/
|
||||
```
|
||||
|
||||
Modify the position of the parent:
|
||||
|
||||

|
||||
|
||||
```c
|
||||
lv_obj_set_pos(parent, 50, 50); /*Move the parent. The child will move with it.*/
|
||||
```
|
||||
|
||||
(For simplicity the adjusting of colors of the objects is not shown in the example.)
|
||||
|
||||
### Visibility only on the parent
|
||||
|
||||
If a child is partially or fully out of its parent then the parts outside will not be visible.
|
||||
|
||||

|
||||
|
||||
```c
|
||||
lv_obj_set_x(obj1, -30); /*Move the child a little bit off the parent*/
|
||||
```
|
||||
|
||||
### Create and delete objects
|
||||
|
||||
In LVGL objects can be created and deleted dynamically in run time. It means only the currently created (existing) objects consume RAM.
|
||||
|
||||
It allows to create a screen just when a button is clicked to open it. A delete the screen when a new screen is loaded.
|
||||
|
||||
Or the UI can be created based on the current environment of the device. For example create meter, charts, bars, slider etc according to the currently attached sensors.
|
||||
|
||||
Every widget has its own **create** function with a prototype like this:
|
||||
```c
|
||||
lv_obj_t * lv_<widget>_create(lv_obj_t * parent, <other paramaters if any>);
|
||||
```
|
||||
|
||||
In most of the cases the create functions have only a *parent* parameter that tells on which object create the new widget.
|
||||
|
||||
The return value is a pointer to the created object with `lv_obj_t *` type.
|
||||
|
||||
|
||||
There is a common **delete** function for all object types. It deletes the object and all of its children.
|
||||
|
||||
```c
|
||||
void lv_obj_del(lv_obj_t * obj);
|
||||
```
|
||||
|
||||
`lv_obj_del` will delete the object immediately.
|
||||
If for any reason you can't delete the object immediately you can use `lv_obj_del_async(obj)` that will perefome the deletion on hte next call of `lv_timer_handler()`.
|
||||
It is useful e.g. if you want to delete the parent of an object in the child's `LV_EVENT_DELETE` signal.
|
||||
|
||||
You can remove all the children of an object (but not the object itself) using `lv_obj_clean(obj)`.
|
||||
|
||||
|
||||
## Screens
|
||||
|
||||
### Create screens
|
||||
The screens are special objects which have no parent object. So they can be created like:
|
||||
```c
|
||||
lv_obj_t * scr1 = lv_obj_create(NULL);
|
||||
```
|
||||
|
||||
Screens can be created with any object type. For example, a [Base object](/widgets/obj) or an image to make a wallpaper.
|
||||
|
||||
### Get the active screen
|
||||
There is always an active screen on each display. By default, the library creates and loads a "Base object" as a screen for each display.
|
||||
|
||||
To get the currently active screen use the `lv_scr_act()` function.
|
||||
|
||||
### Load screens
|
||||
|
||||
To load a new screen, use `lv_scr_load(scr1)`.
|
||||
|
||||
### Layers
|
||||
There are two automatically generated layers:
|
||||
- top layer
|
||||
- system layer
|
||||
|
||||
They are independent of the screens and they will be shown on every screen. The *top layer* is above every object on the screen and the *system layer* is above the *top layer* too.
|
||||
You can add any pop-up windows to the *top layer* freely. But, the *system layer* is restricted to system-level things (e.g. mouse cursor will be placed here in `lv_indev_set_cursor()`).
|
||||
|
||||
The `lv_layer_top()` and `lv_layer_sys()` functions gives a pointer to the top or system layer.
|
||||
|
||||
Read the [Layer overview](/overview/layer) section to learn more about layers.
|
||||
|
||||
|
||||
#### Load screen with animation
|
||||
|
||||
A new screen can be loaded with animation too using `lv_scr_load_anim(scr, transition_type, time, delay, auto_del)`. The following transition types exist:
|
||||
- `LV_SCR_LOAD_ANIM_NONE`: switch immediately after `delay` milliseconds
|
||||
- `LV_SCR_LOAD_ANIM_OVER_LEFT/RIGHT/TOP/BOTTOM` move the new screen over the current towards the given direction
|
||||
- `LV_SCR_LOAD_ANIM_MOVE_LEFT/RIGHT/TOP/BOTTOM` move both the current and new screens towards the given direction
|
||||
- `LV_SCR_LOAD_ANIM_FADE_ON` fade the new screen over the old screen
|
||||
|
||||
Setting `auto_del` to `true` will automatically delete the old screen when the animation is finished.
|
||||
|
||||
The new screen will become active (returned by `lv_scr_act()`) when the animations starts after `delay` time.
|
||||
|
||||
### Handling multiple displays
|
||||
Screens are created on the currently selected *default display*.
|
||||
The *default display* is the last registered display with `lv_disp_drv_register` or you can explicitly select a new default display using `lv_disp_set_default(disp)`.
|
||||
|
||||
`lv_scr_act()`, `lv_scr_load()` and `lv_scr_load_anim()` operate on the default screen.
|
||||
|
||||
Visit [Multi-display support](/overview/display) to learn more.
|
||||
|
||||
## Parts
|
||||
|
||||
The widgets are built from multiple parts. For example a [Base object](/widgets/obj) uses the main and scroll bar parts but a [Slider](/widgets/core/slider) uses the main, the indicator and the knob parts.
|
||||
Parts are similar to *pseudo elements* in CSS.
|
||||
|
||||
The following predefined parts exist in LVGL:
|
||||
- `LV_PART_MAIN` A background like rectangle*/
|
||||
- `LV_PART_SCROLLBAR` The scrollbar(s)
|
||||
- `LV_PART_INDICATOR` Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox
|
||||
- `LV_PART_KNOB` Like a handle to grab to adjust the value*/
|
||||
- `LV_PART_SELECTED` Indicate the currently selected option or section
|
||||
- `LV_PART_ITEMS` Used if the widget has multiple similar elements (e.g. tabel cells)*/
|
||||
- `LV_PART_TICKS` Ticks on scales e.g. for a chart or meter
|
||||
- `LV_PART_CURSOR` Mark a specific place e.g. text area's or chart's cursor
|
||||
- `LV_PART_CUSTOM_FIRST` Custom parts can be added from here.
|
||||
|
||||
The main purpose of parts to allow styling the "components" of the widgets.
|
||||
Therefore the parts are described in more detail in the [Style overview](/overview/style) section.
|
||||
|
||||
## States
|
||||
The object can be in a combinations of the following states:
|
||||
- `LV_STATE_DEFAULT` Normal, released state
|
||||
- `LV_STATE_CHECKED` Toggled or checked state
|
||||
- `LV_STATE_FOCUSED` Focused via keypad or encoder or clicked via touchpad/mouse
|
||||
- `LV_STATE_FOCUS_KEY` Focused via keypad or encoder but not via touchpad/mouse
|
||||
- `LV_STATE_EDITED` Edit by an encoder
|
||||
- `LV_STATE_HOVERED` Hovered by mouse (not supported now)
|
||||
- `LV_STATE_PRESSED` Being pressed
|
||||
- `LV_STATE_SCROLLED` Being scrolled
|
||||
- `LV_STATE_DISABLED` Disabled state
|
||||
- `LV_STATE_USER_1` Custom state
|
||||
- `LV_STATE_USER_2` Custom state
|
||||
- `LV_STATE_USER_3` Custom state
|
||||
- `LV_STATE_USER_4` Custom state
|
||||
|
||||
The states are usually automatically changed by the library as the user presses, releases, focuses etc an object.
|
||||
However, the states can be changed manually too.
|
||||
To set or clear given state (but leave the other states untouched) use `lv_obj_add/clear_state(obj, LV_STATE_...)`
|
||||
In both cases ORed state values can be used as well. E.g. `lv_obj_add_state(obj, part, LV_STATE_PRESSED | LV_PRESSED_CHECKED)`.
|
||||
|
||||
To learn more about the states read the related section of the [Style overview](/overview/style).
|
||||
|
169
fr3092_lvglcode/lvgl/docs/overview/scroll.md
Normal file
169
fr3092_lvglcode/lvgl/docs/overview/scroll.md
Normal file
@ -0,0 +1,169 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/scroll.md
|
||||
```
|
||||
# Scroll
|
||||
|
||||
## Overview
|
||||
In LVGL scrolling works very intuitively: if an object is out of its parent content area (the size without paddings), the parent becomes scrollable and scrollbar(s) will appear. That's it.
|
||||
|
||||
Any object can be scrollable including `lv_obj_t`, `lv_img`, `lv_btn`, `lv_meter`, etc
|
||||
|
||||
The obejct can be scrolled either horizontally or vertically at a time, that is diagonal scrolling is not possible.
|
||||
|
||||
### Scrollbar
|
||||
|
||||
#### Mode
|
||||
The scrollbars are displayed according to the set `mode`. The following `mode`s exist:
|
||||
- `LV_SCROLLBAR_MODE_OFF` Never show the scrollbars
|
||||
- `LV_SCROLLBAR_MODE_ON` Always show the scrollbars
|
||||
- `LV_SCROLLBAR_MODE_ACTIVE` Show scroll bars while object is being scrolled
|
||||
- `LV_SCROLLBAR_MODE_AUTO` Show scroll bars when the content is large enough to be scrolled
|
||||
|
||||
`lv_obj_set_scrollbar_mode(obj, LV_SCROLLBAR_MODE_...)` set the scrollbar mode on an object.
|
||||
|
||||
|
||||
#### Styling
|
||||
The scrollbars have its own dedicated part, called `LV_PART_SCROLLBAR`. For example a scrollbar can turned to red like this:
|
||||
```c
|
||||
static lv_style_t style_red;
|
||||
lv_style_init(&style_red);
|
||||
lv_style_set_bg_color(&style_red, lv_color_red());
|
||||
|
||||
...
|
||||
|
||||
lv_obj_add_style(obj, &style_red, LV_PART_SCROLLBAR);
|
||||
```
|
||||
|
||||
The object goes to `LV_STATE_SCROLLED` state while it's being scrolled. It allows adding different style to the scrollbar or the object itself when scrolled.
|
||||
This code makes the scrollbar blue when the object is scrolled:
|
||||
```c
|
||||
static lv_style_t style_blue;
|
||||
lv_style_init(&style_blue);
|
||||
lv_style_set_bg_color(&style_red, lv_color_blue());
|
||||
|
||||
...
|
||||
|
||||
lv_obj_add_style(obj, &style_blue, LV_STATE_SCROLLED | LV_PART_SCROLLBAR);
|
||||
```
|
||||
|
||||
### Events
|
||||
The following events are related to scrolling:
|
||||
- `LV_EVENT_SCROLL_BEGIN` Scrolling begins
|
||||
- `LV_EVENT_SCROLL_END` Scrolling ends
|
||||
- `LV_EVENT_SCROLL` Scroll happened. Triggered on every position change.
|
||||
Scroll events
|
||||
|
||||
## Basic example
|
||||
TODO
|
||||
|
||||
## Features of scrolling
|
||||
|
||||
Besides managing "normal" scrolling there are many interesting and useful additional features too.
|
||||
|
||||
|
||||
### Scrollable
|
||||
|
||||
It's possible to make an object non-scrollable with `lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE)`.
|
||||
|
||||
Non-scrollable object can still propagate the scrolling (chain) to the parents.
|
||||
|
||||
The direction in which scrolling can happen can be controlled by `lv_obj_set_scroll_dir(obj, LV_DIR_...)`.
|
||||
The following values are possible for the direction:
|
||||
- `LV_DIR_TOP` only scroll up
|
||||
- `LV_DIR_LEFT` only scroll left
|
||||
- `LV_DIR_BOTTOM` only scroll down
|
||||
- `LV_DIR_RIGHT` only scroll right
|
||||
- `LV_DIR_HOR` only scroll horizontally
|
||||
- `LV_DIR_TOP` only scroll vertically
|
||||
- `LV_DIR_ALL` scroll any directions
|
||||
|
||||
OR-ed values are also possible. E.g. `LV_DIR_TOP | LV_DIR_LEFT`.
|
||||
|
||||
|
||||
### Scroll chain
|
||||
If an object can't be scrolled further (e.g. it's content has reached the bottom most position) the scrolling is propagated to it's parent. If the parent an be scrolled in that direction than it will be scrolled instead.
|
||||
It goes to the grad parent and grand grandparents too.
|
||||
|
||||
The propagation on scrolling in called "scroll chaining" and it can be enabled/disabled with the `LV_OBJ_FLAG_SCROLL_CHAIN` flag.
|
||||
If chaining is disabled the propagation stops on the object and the parent(s) won't be scrolled.
|
||||
|
||||
### Scroll momentum
|
||||
When the user scrolls an object and releases it LVGL can emulate a momentum for the scrolling. It's like to object were thrown and the scrolling slows down smoothly.
|
||||
|
||||
The scroll momentum can be enabled/disabled with the `LV_OBJ_FLAG_SCROLL_MOMENTUM` flag.
|
||||
|
||||
### Elastic scroll
|
||||
Normally the content can't be scrolled inside the object. That is the top side of the content can't be below the top side of the object.
|
||||
|
||||
However, with `LV_OBJ_FLAG_SCROLL_ELASTIC` a fancy effect can be added when the user "over-scrolls" the content. The scrolling slows down, and the content can be scrolled inside the object.
|
||||
When the object is releases the content is scrolled in it will be animated back to the valid position.
|
||||
|
||||
### Snaping
|
||||
The children of an object can be snapped according to specific rules when scrolling ends. Children can be made snapable individually with the `LV_OBJ_FLAG_SNAPABLE` flag.
|
||||
The object can align the snapped children in 4 ways:
|
||||
- `LV_SCROLL_SNAP_NONE` Snapping is disabled. (default)
|
||||
- `LV_SCROLL_SNAP_START` Align the children to the left/top side of the scrolled object
|
||||
- `LV_SCROLL_SNAP_END` Align the children to the right/bottom side of the scrolled object
|
||||
- `LV_SCROLL_SNAP_CENTER` Align the children to the center of the scrolled object
|
||||
|
||||
The alignment can be set with `lv_obj_set_scroll_snap_x/y(obj, LV_SCROLL_SNAP_...)`:
|
||||
|
||||
Under the hood the followings happen
|
||||
1. User scrolls an object and releases the screen
|
||||
2. LVGL calculates where would the scroll end considering scroll momentum
|
||||
3. LVGL finds the nearest scroll point
|
||||
4. LVGL scrolls the snap point with an animation
|
||||
|
||||
### Scroll one
|
||||
The "scroll one" feature tells LVGL to allow scrolling only one snapable children at a time.
|
||||
So it requires to make the children snapable and and set a scroll snap alignment different from `LV_SCROLL_SNAP_NONE`.
|
||||
|
||||
This feature can be enabled by the `LV_OBJ_FLAG_SCROLL_ONE` flag.
|
||||
|
||||
### Scroll on focus
|
||||
Imagine that there a lot of objects in a group that are on scrollable object. Pressing the "Tab" button focuses the next object but it might be out of the visible area of the scrollable object.
|
||||
If the "scroll on focus" features is enabled LVGL will automatically scroll to the objects to bring the children into the view.
|
||||
The scrolling happens recursively therefore even nested scrollable object are handled properly.
|
||||
The object will be scrolled to the view even if it's on a different page of a tabview.
|
||||
|
||||
## Scroll manually
|
||||
The following API functions allow to manually scroll objects:
|
||||
- `lv_obj_scroll_by(obj, x, y, LV_ANIM_ON/OFF)` scroll by `x` and `y` values
|
||||
- `lv_obj_scroll_to(obj, x, y, LV_ANIM_ON/OFF)` scroll to bring the given coordinate to the top left corner
|
||||
- `lv_obj_scroll_to_x(obj, x, LV_ANIM_ON/OFF)` scroll to bring the given coordinate to the left side
|
||||
- `lv_obj_scroll_to_y(obj, y, LV_ANIM_ON/OFF)` scroll to bring the given coordinate to the left side
|
||||
|
||||
## Self size
|
||||
|
||||
Self size is a property of an object. Normally, the user shouldn't use this parameter but if a custom widget is created it might be useful.
|
||||
|
||||
In short, self size tell the size of the content. To understand it better take the example of a table.
|
||||
Let's say it has 10 rows each with 50 px height. So the total height of the content is 500 px. In other words the "self height" is 500 px.
|
||||
If the user sets only 200 px height for the table LVGL will see that the self size is larger and make the table scrollable.
|
||||
|
||||
It means not only the children can make an object scrollable but a larger self size too.
|
||||
|
||||
LVGL uses the `LV_EVENT_GET_SELF_SIZE` event to get the self size of an object. Here is an example to see how to handle the event
|
||||
```c
|
||||
if(event_code == LV_EVENT_GET_SELF_SIZE) {
|
||||
lv_point_t * p = lv_event_get_param(e);
|
||||
|
||||
//If x or y < 0 then it doesn't neesd to be calculated now
|
||||
if(p->x >= 0) {
|
||||
p->x = 200; //Set or calculate the self width
|
||||
}
|
||||
|
||||
if(p->y >= 0) {
|
||||
p->y = 50; //Set or calculate the self height
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/scroll/index.rst
|
||||
|
||||
```
|
903
fr3092_lvglcode/lvgl/docs/overview/style-props.md
Normal file
903
fr3092_lvglcode/lvgl/docs/overview/style-props.md
Normal file
@ -0,0 +1,903 @@
|
||||
# Style properties
|
||||
|
||||
## Size and position
|
||||
TODO
|
||||
|
||||
|
||||
### width
|
||||
Sets the width of object. Pixel, percentage and `LV_SIZE_CONTENT` values can be used. Percentage values are relative to the width of the parent's content area.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### min_width
|
||||
Sets a minimal width. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### max_width
|
||||
Sets a maximal width. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### height
|
||||
Sets the height of object. Pixel, percentage and `LV_SIZE_CONTENT` can be used. Percentage values are relative to the height of the parent's content area.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### min_height
|
||||
Sets a minimal height. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### max_height
|
||||
Sets a maximal height. Pixel and percentage values can be used. Percentage values are relative to the height of the parent's content area.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### x
|
||||
Set the X coordinate of the object considering the set `align`. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### y
|
||||
Set the Y coordinate of the object considering the set `align`. Pixel and percentage values can be used. Percentage values are relative to the height of the parent's content area.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### align
|
||||
Set the alignment which tells from which point of the parent the X and Y coordinates should be interpreted. The possible values are: `LV_ALIGN_TOP_LEFT/MID/RIGHT`, `LV_ALIGN_BOTTOM_LEFT/MID/RIGHT`, `LV_ALIGN_LEFT/RIGHT_MID`, `LV_ALIGN_CENTER`
|
||||
<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_width
|
||||
Make the object wider on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's width.
|
||||
<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_height
|
||||
Make the object higher on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's height.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### translate_x
|
||||
Move the object with this value in X direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's width.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### translate_y
|
||||
Move the object with this value in Y direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's height.
|
||||
<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_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
|
||||
<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_angle
|
||||
Rotate image-like objects. Added to the rotation set on the object. The value is interpreted in 0.1 degree unit. E.g. 45 deg. = 450
|
||||
<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
|
||||
TODO
|
||||
|
||||
|
||||
### pad_top
|
||||
Sets the padding on the top. It makes the content area smaller in this direction.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### pad_bottom
|
||||
Sets the padding on the bottom. It makes the content area smaller in this direction.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### pad_left
|
||||
Sets the padding on the left. It makes the content area smaller in this direction.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### pad_right
|
||||
Sets the padding on the right. It makes the content area smaller in this direction.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### pad_row
|
||||
Sets the padding between the rows. Used by the layouts.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### pad_column
|
||||
Sets the padding between the columns. Used by the layouts.
|
||||
<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>
|
||||
|
||||
|
||||
## Miscellaneous
|
||||
TODO
|
||||
|
||||
|
||||
### radius
|
||||
Set the radius on every corner. The value is interpreted in pixel (>= 0) or `LV_RADIUS_CIRCLE` for max. radius
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### clip_corner
|
||||
Enable to clip the overflowed content on the rounded corner. Can be `true` or `false`.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### opa
|
||||
Scale down all opacity values of the object by this factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### color_filter_dsc
|
||||
Mix a color to all colors of the object.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### color_filter_opa
|
||||
The intensity of mixing of color filter.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### anim_time
|
||||
The animation time in milliseconds. It's meaning is widget specific. E.g. blink time of the cursor on the text area or scroll time of a roller. See the widgets' documentation to learn more.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### anim_speed
|
||||
The animation speed in pixel/sec. It's meaning is widget specific. E.g. scroll speed of label. See the widgets' documentation to learn more.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### transition
|
||||
An initialized `lv_style_transition_dsc_t` to describe a transition.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### blend_mode
|
||||
Describes how to blend the colors to the background. The possibel values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### layout
|
||||
Set the layout if the object. The children will be repositioned and resized according to the policies set for the layout. For the possible values see the documentation of the layouts.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### base_dir
|
||||
Set the base direction of the obejct. The possible values are `LV_BIDI_DIR_LTR/RTL/AUTO`.
|
||||
<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>
|
||||
|
||||
|
||||
## Background
|
||||
TODO
|
||||
|
||||
|
||||
### bg_color
|
||||
Set the background color of the object.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### bg_opa
|
||||
Set the opacity of the background. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### bg_grad_color
|
||||
Set the gradient color of the background. Used only if `grad_dir` is not `LV_GRAD_DIR_NONE`
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### bg_grad_dir
|
||||
Set the direction of the gradient of the background. The possible values are `LV_GRAD_DIR_NONE/HOR/VER`.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### bg_main_stop
|
||||
Set the point from which the background color should start for gradients. 0 means to top/left side, 255 the bottom/right side, 128 the center, 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>
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### bg_grad_stop
|
||||
Set the point from which the background's gradient color should start. 0 means to top/left side, 255 the bottom/right side, 128 the center, 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>
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### bg_img_src
|
||||
Set a background image. Can be a pointer to `lv_img_dsc_t`, a path to a file or an `LV_SYMBOL_...`
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### bg_img_opa
|
||||
Set the opacity of the background image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### bg_img_recolor
|
||||
Set a color to mix to the background image.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### bg_img_recolor_opa
|
||||
Set the intensity of background image recoloring. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means no mixing, 256, `LV_OPA_100` or `LV_OPA_COVER` means full recoloring, other values or LV_OPA_10, LV_OPA_20, etc are interpreted proportionally.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### bg_img_tiled
|
||||
If enbaled the background image will be tiled. The possible values are `true` or `false`.
|
||||
<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>
|
||||
|
||||
|
||||
## Border
|
||||
TODO
|
||||
|
||||
|
||||
### border_color
|
||||
Set the color of the border
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### border_opa
|
||||
Set the opcitiy of the border. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### border_width
|
||||
Set hte width of the border. Only pixel values can be used.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### border_side
|
||||
Set ony which side(s) the border should be drawn. The possible values are `LV_BORDER_SIDE_NONE/TOP/BOTTOM/LEFT/RIGHT/INTERNAL`. OR-ed calues an be used as well, e.g. `LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_LEFT`.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### border_post
|
||||
Sets wheter the the border should be drawn before or after the children ar drawn. `true`: after children, `false`: before children
|
||||
<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>
|
||||
|
||||
|
||||
## Text
|
||||
TODO
|
||||
|
||||
|
||||
### text_color
|
||||
Sets the color of the text.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### text_opa
|
||||
Set the opacity of the text. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### text_font
|
||||
Set the font of the text (a pointer `lv_font_t *`).
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### text_letter_space
|
||||
Set the letter space in pixels
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### text_line_space
|
||||
Set the line space in pixels.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### text_decor
|
||||
Set decoration for the text. The possible values are `LV_TEXT_DECOR_NONE/UNDERLINE/STRIKETHROUGH`. OR-ed values can be used as well.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### text_align
|
||||
Set how to align the lines of the text. Note that it doesn't align the object itself, only the lines inside the object. The possible values are `LV_TEXT_ALIGN_LEFT/CENTER/RIGHT/AUTO`. `LV_TEXT_ALIGN_AUTO` detect the text base direction and uses left or right alignment accordingly
|
||||
<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>
|
||||
|
||||
|
||||
## Image
|
||||
TODO
|
||||
|
||||
|
||||
### img_opa
|
||||
Set the opacity of an image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### img_recolor
|
||||
Set color to mixt to the image.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### img_recolor_opa
|
||||
Set the intensity of the color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
|
||||
<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>
|
||||
|
||||
|
||||
## Outline
|
||||
TODO
|
||||
|
||||
|
||||
### outline_width
|
||||
Set the width of the outline in pixels.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### outline_color
|
||||
Set the color of the outline.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### outline_opa
|
||||
Set the opacity of the outline. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### outline_pad
|
||||
Set the padding of the outline, i.e. the gap between object and the outline.
|
||||
<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>
|
||||
|
||||
|
||||
## Shadow
|
||||
TODO
|
||||
|
||||
|
||||
### shadow_width
|
||||
Set the width of the shadow in pixels. The value should be >= 0.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### shadow_ofs_x
|
||||
Set an offset on the shadow in pixels in X direction.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### shadow_ofs_y
|
||||
Set an offset on the shadow in pixels in Y direction.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### shadow_spread
|
||||
Make the shadow calcuation to use a larger or smaller rectangle as base. The value can be in pixel t make the area larger/smaller
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### shadow_color
|
||||
Set the color of the shadow
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### shadow_opa
|
||||
Set the opacity of the shadow. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
|
||||
<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>
|
||||
|
||||
|
||||
## Line
|
||||
TODO
|
||||
|
||||
|
||||
### line_width
|
||||
Set the width of the lines in pixel.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### line_dash_width
|
||||
Set the width of dashes in pixel. Note that dash works only on horizontal and vertical lines
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### line_dash_gap
|
||||
Set the gap between dashes in pixel. Note that dash works only on horizontal and vertical lines
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### line_rounded
|
||||
Make the end points of the lines rounded. `true`: rounded, `false`: perpandicular line ending
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### line_color
|
||||
Set the color fo the lines.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### line_opa
|
||||
Set the opacity of the lines.
|
||||
<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>
|
||||
|
||||
|
||||
## Arc
|
||||
TODO
|
||||
|
||||
|
||||
### arc_width
|
||||
Set the width (ticjkness) of the arcs in pixel.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### arc_rounded
|
||||
Make the end points of the arcs rounded. `true`: rounded, `false`: perpandicular line ending
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### arc_color
|
||||
Set the color of the arc.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### arc_opa
|
||||
Set the opacity of the arcs.
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
### arc_img_src
|
||||
Set an image from which the arc will be masked out. It's useful to display complex effects on the arcs. Can be a pointer to `lv_img_dsc_t` or a path to a file
|
||||
<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>
|
||||
|
318
fr3092_lvglcode/lvgl/docs/overview/style.md
Normal file
318
fr3092_lvglcode/lvgl/docs/overview/style.md
Normal file
@ -0,0 +1,318 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/style.md
|
||||
```
|
||||
# Styles
|
||||
|
||||
*Styles* are used to set the appearance of the objects. Styles in lvgl are heavily inspired by CSS. The concept in nutshell is the following:
|
||||
- A style is an `lv_style_t` variable which can hold properties, for example border width, text color and so on. It's similar to a `class` in CSS.
|
||||
- Styles can be assigned to objects to change their appearance. During the assignment the target part (*pseudo element* in CSS) and target state (*pseudo class*) can be specified.
|
||||
For example add `style_blue` to the knob of a slider when it's in pressed state.
|
||||
- The same style can be used by any number of objects.
|
||||
- Styles can be cascaded which means multiple styles can be assigned to an object and each style can have different properties.
|
||||
Therefore not all properties have to be specified in style. LVLG will look for a property until a style defines it or use a default if it's not spefied by any of the styles.
|
||||
For example `style_btn` can result in a default gray button and `style_btn_red` can add only a `background-color=red` to overwrite the background color.
|
||||
- Later added styles have higher precedence. It means if a property is specified in two styles the later added will be used.
|
||||
- Some properties (e.g. text color) can be inherited from the parent(s) if it's not specified in the object.
|
||||
- Objects can have local styles that have higher precedence than "normal" styles.
|
||||
- Unlike CSS (where pseudo-classes describe different states, e.g. `:focus`), in LVGL a property is assigned to a given state.
|
||||
- Transitions can be applied when the object changes state.
|
||||
|
||||
|
||||
## States
|
||||
The objects can be in the combination of the following states:
|
||||
- `LV_STATE_DEFAULT` (0x0000) Normal, released state
|
||||
- `LV_STATE_CHECKED` (0x0001) Toggled or checked state
|
||||
- `LV_STATE_FOCUSED` (0x0002) Focused via keypad or encoder or clicked via touchpad/mouse
|
||||
- `LV_STATE_FOCUS_KEY` (0x0004) Focused via keypad or encoder but not via touchpad/mouse
|
||||
- `LV_STATE_EDITED` (0x0008) Edit by an encoder
|
||||
- `LV_STATE_HOVERED` (0x0010) Hovered by mouse (not supported now)
|
||||
- `LV_STATE_PRESSED` (0x0020) Being pressed
|
||||
- `LV_STATE_SCROLLED` (0x0040) Being scrolled
|
||||
- `LV_STATE_DISABLED` (0x0080) Disabled state
|
||||
- `LV_STATE_USER_1` (0x1000) Custom state
|
||||
- `LV_STATE_USER_2` (0x2000) Custom state
|
||||
- `LV_STATE_USER_3` (0x4000) Custom state
|
||||
- `LV_STATE_USER_4` (0x8000) Custom state
|
||||
|
||||
The combination states the object can be focused and pressed at the same time. It represented as `LV_STATE_FOCUSED | LV_STATE_PRESSED`.
|
||||
|
||||
The style can be added to any state and state combination.
|
||||
For example, setting a different background color for default and pressed state.
|
||||
If a property is not defined in a state the best matching state's property will be used. Typically it means the property with `LV_STATE_DEFAULT` state.˛
|
||||
If the property is not set even for the default state the default value will be used. (See later)
|
||||
|
||||
But what does the "best matching state's property" really means?
|
||||
States have a precedence which is shown by their value (see in the above list). A higher value means higher precedence.
|
||||
To determine which state's property to use let's use an example. Let's see the background color is defined like this:
|
||||
- `LV_STATE_DEFAULT`: white
|
||||
- `LV_STATE_PRESSED`: gray
|
||||
- `LV_STATE_FOCUSED`: red
|
||||
|
||||
1. By the default the object is in default state, so it's a simple case: the property is perfectly defined in the object's current state as white.
|
||||
2. When the object is pressed there are 2 related properties: default with white (default is related to every state) and pressed with gray.
|
||||
The pressed state has 0x0020 precedence which is higher than the default state's 0x0000 precedence, so gray color will be used.
|
||||
3. When the object is focused the same thing happens as in pressed state and red color will be used. (Focused state has higher precedence than default state).
|
||||
4. When the object is focused and pressed both gray and red would work, but the pressed state has higher precedence than focused so gray color will be used.
|
||||
5. It's possible to set e.g rose color for `LV_STATE_PRESSED | LV_STATE_FOCUSED`.
|
||||
In this case, this combined state has 0x0020 + 0x0002 = 0x0022 precedence, which higher than the pressed states precedence so rose color would be used.
|
||||
6. When the object is in checked state there is no property to set the background color for this state. So in lack of a better option, the object remains white from the default state's property.
|
||||
|
||||
Some practical notes:
|
||||
- The precedence (value) of states is quite intuitive and it's something the user would expect naturally. E.g. if an object is focused, the user still want to see if it's pressed, therefore pressed state has a higher precedence.
|
||||
If the focused state had higher precedence it would overwrite the pressed color.
|
||||
- If you want to set a property for all state (e.g. red background color) just set it for the default state. If the object can't find a property for its current state it will fall back to the default state's property.
|
||||
- Use ORed states to describe the properties for complex cases. (E.g. pressed + checked + focused)
|
||||
- It might be a good idea to use different style elements for different states.
|
||||
For example, finding background colors for released, pressed, checked + pressed, focused, focused + pressed, focused + pressed + checked, etc states is quite difficult.
|
||||
Instead, for example, use the background color for pressed and checked states and indicate the focused state with a different border color.
|
||||
|
||||
## Cascading styles
|
||||
It's not required to set all the properties in one style. It's possible to add more styles to an object and let the later added style to modify or extend appearance.
|
||||
For example, create a general gray button style and create a new for red buttons where only the new background color is set.
|
||||
|
||||
It's the same concept when in CSS all the used classes are listed like `<div class=".btn .btn-red">`.
|
||||
|
||||
The later added styles have higher precedence over the earlier ones. So in the gray/red button example above, the normal button style should be added first and the red style second.
|
||||
However, the precedence coming from states are still taken into account.
|
||||
So let's examine the following case:
|
||||
- the basic button style defines dark-gray color for default state and light-gray color pressed state
|
||||
- the red button style defines the background color as red only in the default state
|
||||
|
||||
In this case, when the button is released (it's in default state) it will be red because a perfect match is found in the lastly added style (red style).
|
||||
When the button is pressed the light-gray color is a better match because it describes the current state perfectly, so the button will be light-gray.
|
||||
|
||||
## Inheritance
|
||||
Some properties (typically that are related to texts) can be inherited from the parent object's styles.
|
||||
Inheritance is applied only if the given property is not set in the object's styles (even in default state).
|
||||
In this case, if the property is inheritable, the property's value will be searched in the parents too until an object can tell a value for the property. The parents will use their own state to tell the value.
|
||||
So if a button is pressed, and the text color comes from here, the pressed text color will be used.
|
||||
|
||||
|
||||
## Parts
|
||||
Objects can have *parts* which can have their own styles.
|
||||
|
||||
The following predefined parts exist in LVGL:
|
||||
- `LV_PART_MAIN` A background like rectangle*/
|
||||
- `LV_PART_SCROLLBAR` The scrollbar(s)
|
||||
- `LV_PART_INDICATOR` Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox
|
||||
- `LV_PART_KNOB` Like a handle to grab to adjust the value*/
|
||||
- `LV_PART_SELECTED` Indicate the currently selected option or section
|
||||
- `LV_PART_ITEMS` Used if the widget has multiple similar elements (e.g. tabel cells)*/
|
||||
- `LV_PART_TICKS` Ticks on scales e.g. for a chart or meter
|
||||
- `LV_PART_CURSOR` Mark a specific place e.g. text area's or chart's cursor
|
||||
- `LV_PART_CUSTOM_FIRST` Custom parts can be added from here.
|
||||
|
||||
|
||||
For example a [Slider](/widgets/core/slider) has three parts:
|
||||
- Background
|
||||
- Indiactor
|
||||
- Knob
|
||||
|
||||
It means the all three parts of the slider can have their own styles. See later how to add style styles to objects and parts.
|
||||
|
||||
## Initialize styles and set/get properties
|
||||
|
||||
Styles are stored in `lv_style_t` variables. Style variables should be `static`, global or dynamically allocated.
|
||||
In other words they can not be local variables in functions which are destroyed when the function exists.
|
||||
Before using a style it should be initialized with `lv_style_init(&my_style)`.
|
||||
After initializing the style properties can be set or added to it.
|
||||
|
||||
Property set functions looks like this: `lv_style_set_<property_name>(&style, <value>);` For example:
|
||||
```c
|
||||
static lv_style_t style_btn;
|
||||
lv_style_init(&style_btn);
|
||||
lv_style_set_bg_color(&style_btn, lv_color_grey());
|
||||
lv_style_set_bg_opa(&style_btn, LV_OPA_50);
|
||||
lv_style_set_border_width(&style_btn, 2);
|
||||
lv_style_set_border_color(&style_btn, lv_color_black());
|
||||
|
||||
static lv_style_t style_btn_red;
|
||||
lv_style_init(&style_btn_red);
|
||||
lv_style_set_bg_color(&style_btn_red, lv_color_red());
|
||||
lv_style_set_bg_opa(&style_btn_red, LV_OPA_COVER);
|
||||
```
|
||||
|
||||
To remove a property use:
|
||||
|
||||
```c
|
||||
lv_style_remove_prop(&style, LV_STYLE_BG_COLOR);
|
||||
```
|
||||
|
||||
To get a properties value from style:
|
||||
```c
|
||||
lv_style_value_t v;
|
||||
lv_res_t res = lv_style_rget_prop(&style, LV_STYLE_BG_COLOR, &v);
|
||||
if(res == LV_RES_OK) { /*Found*/
|
||||
do_something(v.color);
|
||||
}
|
||||
```
|
||||
|
||||
`lv_style_value_t` has 3 fields:
|
||||
- `num` for integer, boolean and opacity properties
|
||||
- `color` for color properties
|
||||
- `ptr` for pointer properties
|
||||
|
||||
To reset a style (free all its data) use
|
||||
```c
|
||||
lv_style_reset(&style);
|
||||
```
|
||||
|
||||
## Add and remove styles to a widget
|
||||
A style on its own not that useful. It should be assigned to an object to take its effect.
|
||||
|
||||
### Add styles
|
||||
To add a style to an object use `lv_obj_add_style(obj, &style, <selector>)`. `<selector>` is an OR-ed value of parts and state to which the style should be added. Some examples:
|
||||
- `LV_PART_MAIN | LV_STATE_DEFAULT`
|
||||
- `LV_STATE_PRESSED`: The main part in pressed state. `LV_PART_MAIN` can be omitted
|
||||
- `LV_PART_SCROLLBAR`: The scrollbar part in the default state. `LV_STATE_DEFAULT` can be omitted.
|
||||
- `LV_PART_SCROLLBAR | LV_STATE_SCROLLED`: The scrollbar part when the object is being scrolled
|
||||
- `0` Same as `LV_PART_MAIN | LV_STATE_DEFAULT`.
|
||||
- `LV_PART_INDICATOR | LV_STATE_PRESSED | LV_STATE_CHECKED` The indicator part when the object is pressed and checked at the same time.
|
||||
|
||||
Using `lv_obj_add_style`:
|
||||
```c
|
||||
lv_obj_add_style(btn, &style_btn, 0); /*Default button style*/
|
||||
lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); /*Overwrite only a some colors to red when pressed*/
|
||||
```
|
||||
|
||||
### Remove styles
|
||||
To remove all styles from an object use `lv_obj_remove_style_all(obj)`.
|
||||
|
||||
To remove specific styles use `lv_obj_remove_style(obj, style, selector)`. This function will remove `style` only if the `selector` matches with the `selector` used in `lv_obj_add_style`.
|
||||
`style` can be `NULL` to check only the `selector` and remove all matching styles. The `selector` can use the `LV_STATE_ANY` and `LV_PART_ANY` values to remove the style with any state or part.
|
||||
|
||||
|
||||
### Report style changes
|
||||
If a style which is already assigned to object changes (i.e. a property is added or changed) the objects using that style should be notified. There are 3 options to do this:
|
||||
1. If you know that the changed properties can be applied by a simple redraw (e.g. color or opacity changes) just call `lv_obj_invalidate(obj)` or `lv_obj_invalideate(lv_scr_act())`.
|
||||
2. If more complex style properties were changed or added, and you know which object(s) are affected by that style call `lv_obj_refresh_style(obj, part, property)`.
|
||||
To refresh all parts and properties use `lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY)`.
|
||||
3. No make LVGL check all object whether they use the style and refresh them call `lv_obj_report_style_change(&style)`. If `style` is `NULL` all object's will be notified about the style change.
|
||||
|
||||
### Get a property's value on an object
|
||||
To get a final value of property - considering cascading, inheritance, local styles and transitions (see below) - get functions like this can be used:
|
||||
`lv_obj_get_style_<property_name>(obj, <part>)`.
|
||||
These functions uses the object's current state and if no better candidate returns a default value.
|
||||
For example:
|
||||
```c
|
||||
lv_color_t color = lv_obj_get_style_bg_color(btn, LV_PART_MAIN);
|
||||
```
|
||||
|
||||
## Local styles
|
||||
Besides "normal" styles, the objects can store local styles too. This concept is similar to inline styles in CSS (e.g. `<div style="color:red">`) with some modification.
|
||||
|
||||
So local styles are like normal styles but they can't be shared among other objects. If used, local styles are allocated automatically, and freed when the object is deleted.
|
||||
They are useful to add local customization to the object.
|
||||
|
||||
Unlike in CSS, in LVGL local styles can be assigned to states (*pseudo-classes*) and parts (pseudo-elements).
|
||||
|
||||
To set a local property use functions like `lv_obj_set_style_local_<property_name>(obj, <value>, <selector>);`
|
||||
For example:
|
||||
```c
|
||||
lv_obj_set_style_local_bg_color(slider, lv_color_red(), LV_PART_INDICATOR | LV_STATE_FOCUSED);
|
||||
```
|
||||
## Properties
|
||||
For the full list of style properties click [here](/overview/style-props).
|
||||
|
||||
### Typical background properties
|
||||
In the documentation of the widgets you will see sentences like "The widget use the typical background properties". The "typical background properties" are the ones related to:
|
||||
- Background
|
||||
- Border
|
||||
- Outline
|
||||
- Shadow
|
||||
- Padding
|
||||
- Width and height transformation
|
||||
- X and Y translation
|
||||
|
||||
|
||||
## Transitions
|
||||
By default, when an object changes state (e.g. it's pressed) the new properties from the new state are set immediately. However, with transitions it's possible to play an animation on state change.
|
||||
For example, on pressing a button its background color can be animated to the pressed color over 300 ms.
|
||||
|
||||
The parameters of the transitions are stored in the styles. It's possible to set
|
||||
- the time of the transition
|
||||
- the delay before starting the transition
|
||||
- the animation path (also known as timing or easing function)
|
||||
- the properties to animate
|
||||
|
||||
The transition properties can be defined for each state. For example, setting 500 ms transition time in default state will mean that when the object goes to default state 500 ms transition time will be applied.
|
||||
Setting 100 ms transition time in the pressed state will mean a 100 ms transition time when going to presses state.
|
||||
So this example configuration will result in fast going to presses state and slow going back to default.
|
||||
|
||||
To describe a transition an `lv_transition_dsc_t` variable needs to initialized and added to a style:
|
||||
```c
|
||||
/*Only its pointer is saved so must static, global or dynamically allocated */
|
||||
static const lv_style_prop_t trans_props[] = {
|
||||
LV_STYLE_BG_OPA, LV_STYLE_BG_COLOR,
|
||||
0, /*End marker*/
|
||||
};
|
||||
|
||||
static lv_style_transition_dsc_t trans1;
|
||||
lv_style_transition_dsc_init(&trans1, trans_props, lv_anim_path_ease_out, duration_ms, delay_ms);
|
||||
|
||||
lv_style_set_transition(&style1, &trans1);
|
||||
```
|
||||
|
||||
## Color filter
|
||||
TODO
|
||||
|
||||
|
||||
## Themes
|
||||
Themes are a collection of styles. If there is an active theme LVGL applies it on the every created widget.
|
||||
It gives a default appearance to UI which can be modified by adding further styles.
|
||||
|
||||
Every display can have a different theme. For example a colorful theme on a TFT and monochrome theme on a secondary monochrome display.
|
||||
|
||||
To set a theme for a display 2 steps are required:
|
||||
1. Initialize a theme
|
||||
2. Assign the initialized theme to a display.
|
||||
|
||||
Theme initialization functions can have different prototype. This example shows how to set the "default" theme:
|
||||
```c
|
||||
lv_theme_t * th = lv_theme_default_init(display, /*Use the DPI, size, etc from this display*/
|
||||
LV_COLOR_PALETTE_BLUE, LV_COLOR_PALETTE_CYAN, /*Primary and secondary palette*/
|
||||
false, /*Light or dark mode*/
|
||||
&lv_font_montserrat_10, &lv_font_montserrat_14, &lv_font_montserrat_18); /*Small, normal, large fonts*/
|
||||
|
||||
lv_disp_set_theme(display, th); /*Assign the theme to the display*/
|
||||
```
|
||||
|
||||
|
||||
The themes can be enabled in `lv_conf.h`. If the default theme is enabled by `LV_USE_THEME_DEFAULT 1` LVGL automatically initializes and sets it when a display is created.
|
||||
|
||||
### Extending themes
|
||||
|
||||
Built-in themes can be extended.
|
||||
If a custom theme is created a parent theme can be selected. The parent theme's styles will be added before the custom theme's styles.
|
||||
Any number of themes can be chained this way. E.g. default theme -> custom theme -> dark theme.
|
||||
|
||||
`lv_theme_set_parent(new_theme, base_theme)` extends the `base_theme` with the `new_theme`.
|
||||
|
||||
There is an example for it below.
|
||||
|
||||
## Examples
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/styles/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_style.h
|
||||
:project: lvgl
|
||||
|
||||
.. doxygenfile:: lv_theme.h
|
||||
:project: lvgl
|
||||
|
||||
.. doxygenfile:: lv_obj_style_gen.h
|
||||
:project: lvgl
|
||||
|
||||
.. doxygenfile:: lv_style_gen.h
|
||||
:project: lvgl
|
||||
|
||||
|
||||
```
|
102
fr3092_lvglcode/lvgl/docs/overview/timer.md
Normal file
102
fr3092_lvglcode/lvgl/docs/overview/timer.md
Normal file
@ -0,0 +1,102 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/overview/timer.md
|
||||
```
|
||||
# Timers
|
||||
|
||||
LVGL has a built-in timer system. You can register a function to have it be called periodically. The timers are handled and called in `lv_timer_handler()`, which needs to be called periodically every few milliseconds.
|
||||
See [Porting](/porting/task-handler) for more information.
|
||||
|
||||
The timers are non-preemptive, which means a timer cannot interrupt another timer. Therefore, you can call any LVGL related function in a timer.
|
||||
|
||||
|
||||
## Create a timer
|
||||
To create a new timer, use `lv_timer_create(timer_cb, period_ms, user_data)`. It will create an `lv_timer_t *` variable, which can be used later to modify the parameters of the timer.
|
||||
`lv_timer_create_basic()` can also be used. It allows you to create a new timer without specifying any parameters.
|
||||
|
||||
A timer callback should have `void (*lv_timer_cb_t)(lv_timer_t *);` prototype.
|
||||
|
||||
For example:
|
||||
```c
|
||||
void my_timer(lv_timer_t * timer)
|
||||
{
|
||||
/*Use the user_data*/
|
||||
uint32_t * user_data = timer->user_data;
|
||||
printf("my_timer called with user data: %d\n", *user_data);
|
||||
|
||||
/*Do something with LVGL*/
|
||||
if(something_happened) {
|
||||
something_happened = false;
|
||||
lv_btn_create(lv_scr_act(), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
static uint32_t user_data = 10;
|
||||
lv_timer_t * timer = lv_timer_create(my_timer, 500, &user_data);
|
||||
|
||||
```
|
||||
|
||||
## Ready and Reset
|
||||
|
||||
`lv_timer_ready(timer)` makes the timer run on the next call of `lv_timer_handler()`.
|
||||
|
||||
`lv_timer_reset(timer)` resets the period of a timer. It will be called again after the defined period of milliseconds has elapsed.
|
||||
|
||||
|
||||
## Set parameters
|
||||
You can modify some parameters of the timers later:
|
||||
- `lv_timer_set_cb(timer, new_cb)`
|
||||
- `lv_timer_set_period(timer, new_period)`
|
||||
|
||||
## Repeat count
|
||||
|
||||
You can make a timer repat only a given times with `lv_timer_set_repeat_count(timer, count)`. The timer will automatically be deleted after being called the defined times. Set the count to `-1` to repeat infinitly.
|
||||
|
||||
|
||||
## Measure idle time
|
||||
|
||||
You can get the idle percentage time of `lv_timer_handler` with `lv_timer_get_idle()`. Note that, it doesn't measure the idle time of the overall system, only `lv_timer_handler`.
|
||||
It can be misleading if you use an operating system and call `lv_timer_handler` in an timer, as it won't actually measure the time the OS spends in an idle thread.
|
||||
|
||||
## Asynchronous calls
|
||||
|
||||
In some cases, you can't do an action immediately. For example, you can't delete an object because something else is still using it or you don't want to block the execution now.
|
||||
For these cases, `lv_async_call(my_function, data_p)` can be used to make `my_function` be called on the next call of `lv_timer_handler`. `data_p` will be passed to function when it's called.
|
||||
Note that, only the pointer of the data is saved so you need to ensure that the variable will be "alive" while the function is called. It can be *static*, global or dynamically allocated data.
|
||||
|
||||
For example:
|
||||
```c
|
||||
void my_screen_clean_up(void * scr)
|
||||
{
|
||||
/*Free some resources related to `scr`*/
|
||||
|
||||
/*Finally delete the screen*/
|
||||
lv_obj_del(scr);
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
/*Do somethings with the object on the current screen*/
|
||||
|
||||
/*Delete screen on next call of `lv_timer_handler`, so not now.*/
|
||||
lv_async_call(my_screen_clean_up, lv_scr_act());
|
||||
|
||||
/*The screen is still valid so you can do other things with it*/
|
||||
|
||||
```
|
||||
|
||||
If you just want to delete an object, and don't need to clean anything up in `my_screen_cleanup`, you could just use `lv_obj_del_async`, which will delete the object on the next call to `lv_timer_handler`.
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_timer.h
|
||||
:project: lvgl
|
||||
|
||||
.. doxygenfile:: lv_async.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
Reference in New Issue
Block a user