mirror of
https://github.com/lvgl/lvgl.git
synced 2024-11-23 17:53:45 +08:00
docs(all) Proofread, fix typos and add clarifications in confusing areas (#2528)
Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
parent
715d580d8c
commit
7d9fe20a0e
@ -27,6 +27,7 @@
|
||||
- fix(draw) false assertion error in lv_draw_mask caused by wrong pointer
|
||||
- fix(color) Bad cast in lv_color_mix() caused UB with 16bpp or less
|
||||
- fix(examples) don't compile assets unless needed
|
||||
- docs(all) Proofread, fix typos and add clarifications in confusing areas
|
||||
|
||||
## v8.0.2 (16.07.2021)
|
||||
- fix(theme) improve button focus of keyboard
|
||||
|
@ -19,7 +19,7 @@ LVGL can be installed via the Arduino IDE Library Manager or as a .ZIP library.
|
||||
## Set up drivers
|
||||
|
||||
To get started it's recommended to use [TFT_eSPI](https://github.com/Bodmer/TFT_eSPI) library as a TFT driver to simplify testing.
|
||||
To make it work setup `TFT_eSPI` according to your TFT display type via editing either
|
||||
To make it work, setup `TFT_eSPI` according to your TFT display type via editing either
|
||||
- `User_Setup.h`
|
||||
- or by selecting a configuration in the `User_Setup_Select.h`
|
||||
|
||||
@ -27,7 +27,7 @@ Both files are located in `TFT_eSPI` library's folder.
|
||||
|
||||
## Configure LVGL
|
||||
|
||||
LVGL has its own configuration file called `lv_conf.h`. When LVGL is installed the followings needs to be done to configure it:
|
||||
LVGL has its own configuration file called `lv_conf.h`. When LVGL is installed, follow these configuration steps:
|
||||
1. Go to directory of the installed Arduino libraries
|
||||
2. Go to `lvgl` and copy `lv_conf_template.h` as `lv_conf.h` into the Arduino Libraries directory next to the `lvgl` library folder.
|
||||
3. Open `lv_conf.h` and change the first `#if 0` to `#if 1`
|
||||
@ -46,9 +46,9 @@ Most of the examples are available in the [`lvgl/examples`](https://github.com/l
|
||||
|
||||
## Debugging and logging
|
||||
|
||||
In case of trouble LVGL can display debug information.
|
||||
In the `LVGL_Arduino.ino` example there is `my_print` method, which allow to send this debug information to the serial interface.
|
||||
To enable this feature you have to edit `lv_conf.h` file and enable logging in the section `log settings`:
|
||||
LVGL can display debug information in case of trouble.
|
||||
In the `LVGL_Arduino.ino` example there is a `my_print` method, which sends this debug information to the serial interface.
|
||||
To enable this feature you have to edit the `lv_conf.h` file and enable logging in the section `log settings`:
|
||||
|
||||
```c
|
||||
/*Log settings*/
|
||||
@ -64,5 +64,5 @@ To enable this feature you have to edit `lv_conf.h` file and enable logging in t
|
||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
```
|
||||
|
||||
After enabling the log module and setting LV_LOG_LEVEL accordingly the output log is sent to the `Serial` port @ 115200 bps.
|
||||
After enabling the log module and setting LV_LOG_LEVEL accordingly, the output log is sent to the `Serial` port @ 115200 bps.
|
||||
|
||||
|
@ -20,7 +20,7 @@ ESP-IDF v4 framework is the suggested version to use.
|
||||
|
||||
### Get LVGL
|
||||
|
||||
You are suggested to add LVGL as a "component". This component can be located inside a directory named "components" on your project root directory.
|
||||
It is suggested that you add LVGL as a "component" to your project. This component can be located inside a directory named "components" in the project root directory.
|
||||
|
||||
When your project is a git repository you can include LVGL as a git submodule:
|
||||
|
||||
@ -30,11 +30,11 @@ git submodule add https://github.com/lvgl/lvgl.git components/lvgl
|
||||
|
||||
The above command will clone LVGL's main repository into the `components/lvgl` directory. LVGL includes a `CMakeLists.txt` file that sets some configuration options so you can use LVGL right away.
|
||||
|
||||
When you are ready to configure LVGL launch the configuration menu with `idf.py menuconfig` on your project root directory, go to `Component config` and then `LVGL configuration`.
|
||||
When you are ready to configure LVGL, launch the configuration menu with `idf.py menuconfig` on your project root directory, go to `Component config` and then `LVGL configuration`.
|
||||
|
||||
## Use lvgl_esp32_drivers in your project
|
||||
|
||||
You are suggested to add `lvgl_esp32_drivers` as a "component". This component can be located inside a directory named "components" on your project root directory.
|
||||
You can also add `lvgl_esp32_drivers` as a "component". This component can be located inside a directory named "components" on your project root directory.
|
||||
|
||||
When your project is a git repository you can include `lvgl_esp32_drivers` as a git submodule:
|
||||
|
||||
|
@ -14,7 +14,7 @@ Using Micropython, you can write Python3 code and run it even on a bare metal ar
|
||||
- **Compact** - Fits and runs within just 256k of code space and 16k of RAM. No OS is needed, although you can also run it with an OS, if you want.
|
||||
- **Compatible** - Strives to be as compatible as possible with normal Python (known as CPython).
|
||||
- **Versatile** - Supports many architectures (x86, x86-64, ARM, ARM Thumb, Xtensa).
|
||||
- **Interactive** - No need for the compile-flash-boot cycle. With the REPL (interactive prompt) you can type commands and execute them immediately, run scripts etc.
|
||||
- **Interactive** - No need for the compile-flash-boot cycle. With the REPL (interactive prompt) you can type commands and execute them immediately, run scripts, etc.
|
||||
- **Popular** - Many platforms are supported. The user base is growing bigger. Notable forks: [MicroPython](https://github.com/micropython/micropython), [CircuitPython](https://github.com/adafruit/circuitpython), [MicroPython_ESP32_psRAM_LoBo](https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo)
|
||||
- **Embedded Oriented** - Comes with modules specifically for embedded systems, such as the [machine module](https://docs.micropython.org/en/latest/library/machine.html#classes) for accessing low-level hardware (I/O pins, ADC, UART, SPI, I2C, RTC, Timers etc.)
|
||||
|
||||
@ -35,7 +35,7 @@ In Micropython it's just **`Change code` > `Run`** ! You can even run commands i
|
||||
- Fast prototyping GUI.
|
||||
- Shortening the cycle of changing and fine-tuning the GUI.
|
||||
- Modelling the GUI in a more abstract way by defining reusable composite objects, taking advantage of Python's language features such as Inheritance, Closures, List Comprehension, Generators, Exception Handling, Arbitrary Precision Integers and others.
|
||||
- Make LVGL accessible to a larger audience. No need to know C in order to create a nice GUI on an embedded system.
|
||||
- Make LVGL accessible to a larger audience. No need to know C to create a nice GUI on an embedded system.
|
||||
This goes well with [CircuitPython vision](https://learn.adafruit.com/welcome-to-circuitpython/what-is-circuitpython). CircuitPython was designed with education in mind, to make it easier for new or unexperienced users to get started with embedded development.
|
||||
- Creating tools to work with LVGL at a higher level (e.g. drag-and-drop designer).
|
||||
|
||||
|
@ -45,10 +45,10 @@ Using LVGL, Linux and NuttX you can reduce this process and just test everything
|
||||
|
||||
## How to get started with NuttX and LVGL?
|
||||
|
||||
There are many boards in the NuttX mainline (https://github.com/apache/incubator-nuttx) with support for LVGL.
|
||||
Let's use the [STM32F429IDISCOVERY](https://www.st.com/en/evaluation-tools/32f429idiscovery.html) as example because it is a very popular board.
|
||||
There are many boards in the [NuttX mainline](https://github.com/apache/incubator-nuttx) with support for LVGL.
|
||||
Let's use the [STM32F429IDISCOVERY](https://www.st.com/en/evaluation-tools/32f429idiscovery.html) as an example because it is a very popular board.
|
||||
|
||||
### First you need to install the pre-requisite on your system
|
||||
### First you need to install the pre-requisites on your system
|
||||
|
||||
Let's use the [Windows Subsystem for Linux](https://acassis.wordpress.com/2018/01/10/how-to-build-nuttx-on-windows-10/)
|
||||
|
||||
|
@ -14,9 +14,7 @@ configured with LVGL (and with PXP support if module is present), no additional
|
||||
work is required.
|
||||
|
||||
## Adding HW acceleration for NXP iMX RT platforms using PXP (PiXel Pipeline) engine for existing projects
|
||||
Several drawing features in LVGL can be offloaded to PXP engine. In order to use CPU time while PXP
|
||||
is running, RTOS is required to block the LVGL drawing thread and switch to another task, or simply to
|
||||
idle task, where CPU could be suspended to save power.
|
||||
Several drawing features in LVGL can be offloaded to the PXP engine. The CPU is available for other operations while the PXP is running. An RTOS is required to block the LVGL drawing thread and switch to another task or suspend the CPU for power savings.
|
||||
|
||||
#### Features supported:
|
||||
- RGB565 color format
|
||||
@ -59,13 +57,13 @@ idle task, where CPU could be suspended to save power.
|
||||
- fsl_cache.c, fsl_cache.h: CPU cache handling functions
|
||||
|
||||
#### Advanced configuration:
|
||||
- Implementation depends on multiple OS-specific functions. Structure `lv_nxp_pxp_cfg_t` with callback pointers is used
|
||||
as a parameter for `lv_gpu_nxp_pxp_init()` function. Default implementation for FreeRTOS and baremetal is provided in lv_gpu_nxp_osa.c
|
||||
- Implementation depends on multiple OS-specific functions. The struct `lv_nxp_pxp_cfg_t` with callback pointers is used
|
||||
as a parameter for the `lv_gpu_nxp_pxp_init()` function. Default implementation for FreeRTOS and baremetal is provided in lv_gpu_nxp_osa.c
|
||||
- `pxp_interrupt_init()`: Initialize PXP interrupt (HW setup, OS setup)
|
||||
- `pxp_interrupt_deinit()`: Deinitialize PXP interrupt (HW setup, OS setup)
|
||||
- `pxp_run()`: Start PXP job. Use OS-specific mechanism to block drawing thread. PXP must finish drawing before leaving this function.
|
||||
- There are configurable area thresholds which are used to decide whether the area will be processed by CPU, or by PXP. Areas smaller than
|
||||
defined value will be processed by CPU, areas bigger than the threshold will be processed by PXP. These thresholds may be defined as a
|
||||
- There are configurable area thresholds which are used to decide whether the area will be processed by CPU, or by PXP. Areas smaller than a
|
||||
defined value will be processed by CPU and those bigger than the threshold will be processed by PXP. These thresholds may be defined as
|
||||
preprocessor variables. Default values are defined lv_gpu/lv_gpu_nxp_pxp.h
|
||||
- `GPU_NXP_PXP_BLIT_SIZE_LIMIT`: size threshold for image BLIT, BLIT with color keying, and BLIT with recolor (OPA > LV_OPA_MAX)
|
||||
- `GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT`: size threshold for image BLIT and BLIT with color keying with transparency (OPA < LV_OPA_MAX)
|
||||
|
@ -5,13 +5,13 @@
|
||||
# Simulator on PC
|
||||
|
||||
|
||||
You can try out LVGL **using only your PC** (i.e. without any development boards). LVGL will run on a simulator environment on the PC where anyone can write and experiment the real LVGL applications.
|
||||
You can try out LVGL **using only your PC** (i.e. without any development boards). LVGL will run on a simulator environment on the PC where anyone can write and experiment with real LVGL applications.
|
||||
|
||||
Using the simulator on the PC has the following advantages:
|
||||
- Hardware independent - Write code, run it on the PC and see the result on the PC monitor.
|
||||
Using the simulator on a PC has the following advantages:
|
||||
- Hardware independent - Write code, run it on the PC and see the result on a monitor.
|
||||
- Cross-platform - Any Windows, Linux or macOS system can run the PC simulator.
|
||||
- Portability - the written code is portable, which means you can simply copy it when using an embedded hardware.
|
||||
- Easy Validation - The simulator is also very useful to report bugs because it means common platform for every user. So it's a good idea to reproduce a bug in the simulator and use the code snippet in the [Forum](https://forum.lvgl.io).
|
||||
- Portability - The written code is portable, which means you can simply copy it when migrating to embedded hardware.
|
||||
- Easy Validation - The simulator is also very useful to report bugs because it provides a common platform for every user. So it's a good idea to reproduce a bug in the simulator and use that code snippet in the [Forum](https://forum.lvgl.io).
|
||||
|
||||
## Select an IDE
|
||||
|
||||
@ -23,8 +23,8 @@ The simulator is ported to various IDEs (Integrated Development Environments). C
|
||||
- [VSCode with SDL driver](https://github.com/lvgl/lv_sim_vscode_sdl): Recommended on Linux and Mac
|
||||
- [PlatformIO with SDL driver](https://github.com/lvgl/lv_platformio): Recommended on Linux and Mac
|
||||
|
||||
You can use any IDE for the development but, for simplicity, the configuration for Eclipse CDT is what we'll focus on in this tutorial.
|
||||
The following section describes the set-up guide of Eclipse CDT in more details.
|
||||
You can use any IDE for development but, for simplicity, the configuration for Eclipse CDT is what we'll focus on in this tutorial.
|
||||
The following section describes the set-up guide of Eclipse CDT in more detail.
|
||||
|
||||
**Note: If you are on Windows, it's usually better to use the Visual Studio or CodeBlocks projects instead. They work out of the box without requiring extra steps.**
|
||||
|
||||
@ -34,11 +34,11 @@ The following section describes the set-up guide of Eclipse CDT in more details.
|
||||
|
||||
[Eclipse CDT](https://eclipse.org/cdt/) is a C/C++ IDE.
|
||||
|
||||
Eclipse is a Java based software therefore be sure **Java Runtime Environment** is installed on your system.
|
||||
Eclipse is a Java-based tool so be sure **Java Runtime Environment** is installed on your system.
|
||||
|
||||
On Debian-based distros (e.g. Ubuntu): `sudo apt-get install default-jre`
|
||||
|
||||
Note: If you are using other distros, then please refer and install 'Java Runtime Environment' suitable to your distro.
|
||||
Note: If you are using other distros, then please install a 'Java Runtime Environment' suitable to your distro.
|
||||
Note: If you are using macOS and get a "Failed to create the Java Virtual Machine" error, uninstall any other Java JDK installs and install Java JDK 8u. This should fix the problem.
|
||||
|
||||
You can download Eclipse's CDT from: [https://www.eclipse.org/cdt/downloads.php](https://www.eclipse.org/cdt/downloads.php). Start the installer and choose *Eclipse CDT* from the list.
|
||||
@ -80,7 +80,7 @@ You can find the latest one on [GitHub](https://github.com/lvgl/lv_sim_eclipse_s
|
||||
|
||||
### Add the pre-configured project to Eclipse CDT
|
||||
|
||||
Run Eclipse CDT. It will show a dialogue about the **workspace path**. Before accepting the path, check that path and copy (and unzip) the downloaded pre-configured project there. After that, you can accept the workspace path. Of course you can modify this path but, in that case copy the project to the corresponding location.
|
||||
Run Eclipse CDT. It will show a dialogue about the **workspace path**. Before accepting the path, check that path and copy (and unzip) the downloaded pre-configured project there. After that, you can accept the workspace path. Of course you can modify this path but in that case copy the project to the corresponding location.
|
||||
|
||||
Close the start-up window and go to **File->Import** and choose **General->Existing project into Workspace**. **Browse the root directory** of the project and click **Finish**
|
||||
|
||||
@ -91,8 +91,8 @@ On **Windows** you have to do two additional things:
|
||||
|
||||
### Compile and Run
|
||||
|
||||
Now you are ready to run LVGL on your PC. Click on the Hammer Icon on the top menu bar to Build the project. If you have done everything right, then you will not get any errors. Note that on some systems additional steps might be required to "see" SDL 2 from Eclipse but, in most cases the configuration in the downloaded project is enough.
|
||||
Now you are ready to run LVGL on your PC. Click on the Hammer Icon on the top menu bar to Build the project. If you have done everything right, then you will not get any errors. Note that on some systems additional steps might be required to "see" SDL 2 from Eclipse but in most cases the configuration in the downloaded project is enough.
|
||||
|
||||
After a success build, click on the Play button on the top menu bar to run the project. Now a window should appear in the middle of your screen.
|
||||
After a successful build, click on the Play button on the top menu bar to run the project. Now a window should appear in the middle of your screen.
|
||||
|
||||
Now you are ready to use LVGL and begin development on your PC.
|
||||
|
@ -90,11 +90,11 @@ For a more detailed guide go to the [Porting](/porting/index) section.
|
||||
|
||||
The graphical elements like Buttons, Labels, Sliders, Charts etc. are called objects or widgets. Go to [Widgets](/widgets/index) to see the full list of available widgets.
|
||||
|
||||
Every object has a parent object where it is created. For example if a label is created on a button, the button is the parent of label.
|
||||
Every object has a parent object where it is created. For example, if a label is created on a button, the button is the parent of label.
|
||||
|
||||
The child object moves with the parent and if the parent is deleted the children will be deleted too.
|
||||
|
||||
Children can be visible only on their parent. In other words, the parts of the children outside the parent are clipped.
|
||||
Children can be visible only within their parent's bounding area. In other words, the parts of the children outside the parent are clipped.
|
||||
|
||||
A Screen is the "root" parent. You can have any number of screens.
|
||||
|
||||
@ -114,7 +114,7 @@ lv_obj_set_y(btn1, 10);
|
||||
lv_obj_set_size(btn1, 200, 50);
|
||||
```
|
||||
|
||||
The widgets have type specific parameters too which can be set by `lv_<widget_type>_set_<parameter_name>(obj, <value>)` functions. For example:
|
||||
Along with the basic attributes, widgets can have type specific parameters which are set by `lv_<widget_type>_set_<parameter_name>(obj, <value>)` functions. For example:
|
||||
```c
|
||||
lv_slider_set_value(slider1, 70, LV_ANIM_ON);
|
||||
```
|
||||
@ -125,7 +125,7 @@ To see the full API visit the documentation of the widgets or the related header
|
||||
|
||||
### Events
|
||||
Events are used to inform the user that something has happened with an object.
|
||||
You can assign one or more callbacks to an object which will be called if the object is clicked, released, dragged, being deleted etc.
|
||||
You can assign one or more callbacks to an object which will be called if the object is clicked, released, dragged, being deleted, etc.
|
||||
|
||||
A callback is assigned like this:
|
||||
|
||||
@ -140,14 +140,14 @@ void btn_event_cb(lv_event_t * e)
|
||||
}
|
||||
```
|
||||
|
||||
Instead of `LV_EVENT_CLICKED` `LV_EVENT_ALL` can be used too to call the callback for any event.
|
||||
`LV_EVENT_ALL` can be used instead of `LV_EVENT_CLICKED` to invoke the callback for any event.
|
||||
|
||||
From `lv_event_t * e` the current event code can be retrieved with
|
||||
From `lv_event_t * e` the current event code can be retrieved with:
|
||||
```c
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
```
|
||||
|
||||
The object that triggered the event can be retrieved with
|
||||
The object that triggered the event can be retrieved with:
|
||||
```c
|
||||
lv_obj_t * obj = lv_event_get_target(e);
|
||||
```
|
||||
@ -155,15 +155,15 @@ lv_obj_t * obj = lv_event_get_target(e);
|
||||
To learn all features of the events go to the [Event overview](/overview/event) section.
|
||||
|
||||
### Parts
|
||||
Widgets might be built from one or more *parts*. For example a button has only one part called `LV_PART_MAIN`.
|
||||
Widgets might be built from one or more *parts*. For example, a button has only one part called `LV_PART_MAIN`.
|
||||
However, a [Slider](/widgets/core/slider) has `LV_PART_MAIN`, `LV_PART_INDICATOR` and `LV_PART_KNOB`.
|
||||
|
||||
By using parts you can apply different styles to different parts. (See below)
|
||||
By using parts you can apply different styles to sub-elements of a widget. (See below)
|
||||
|
||||
To learn which parts are used by which object read the widgets' documentation.
|
||||
Read the widgets' documentation to learn which parts each uses.
|
||||
|
||||
### States
|
||||
The objects can be in a combination of the following states:
|
||||
LVGL objects can be in a combination 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
|
||||
@ -174,21 +174,21 @@ The objects can be in a combination of the following states:
|
||||
- `LV_STATE_SCROLLED` Being scrolled
|
||||
- `LV_STATE_DISABLED` Disabled
|
||||
|
||||
For example, if you press an object it will automatically go to `LV_STATE_FOCUSED` and `LV_STATE_PRESSED` state and when you release it, the `LV_STATE_PRESSED` state will be removed.
|
||||
|
||||
To check if an object is in a given state use `lv_obj_has_state(obj, LV_STATE_...)`. It will return `true` if the object is in that state at that time.
|
||||
For example, if you press an object it will automatically go to the `LV_STATE_FOCUSED` and `LV_STATE_PRESSED` states and when you release it the `LV_STATE_PRESSED` state will be removed while focus remains active.
|
||||
|
||||
To manually add or remove states use
|
||||
To check if an object is in a given state use `lv_obj_has_state(obj, LV_STATE_...)`. It will return `true` if the object is currently in that state.
|
||||
|
||||
To manually add or remove states use:
|
||||
```c
|
||||
lv_obj_add_state(obj, LV_STATE_...);
|
||||
lv_obj_clear_state(obj, LV_STATE_...);
|
||||
```
|
||||
|
||||
### Styles
|
||||
Styles contains properties such as background color, border width, font, etc. to describe the appearance of the objects.
|
||||
A style instance contains properties such as background color, border width, font, etc. that describe the appearance of objects.
|
||||
|
||||
The styles are `lv_style_t` variables. Only their pointer is saved in the objects, so they need to be static or global.
|
||||
Before using a style it needs to be initialized with `lv_style_init(&style1)`. After that properties can be added. For example:
|
||||
Styles are represented with `lv_style_t` variables. Only their pointer is saved in the objects so they need to be defined as static or global.
|
||||
Before using a style it needs to be initialized with `lv_style_init(&style1)`. After that, properties can be added to configure the style. For example:
|
||||
```
|
||||
static lv_style_t style1;
|
||||
lv_style_init(&style1);
|
||||
@ -198,7 +198,7 @@ lv_style_set_border_width(&style1, 2))
|
||||
See the full list of properties [here](/overview/style.html#properties).
|
||||
|
||||
|
||||
The styles are assigned to an object's part and state. For example to *"Use this style on the slider's indicator when the slider is pressed"*:
|
||||
Styles are assigned using the ORed combination of an object's part and state. For example to use this style on the slider's indicator when the slider is pressed:
|
||||
```c
|
||||
lv_obj_add_style(slider1, &style1, LV_PART_INDICATOR | LV_STATE_PRESSED);
|
||||
```
|
||||
@ -219,7 +219,7 @@ lv_obj_add_style(btn1, &style1, 0); /*Equal to LV_PART_MAIN | LV_STATE_DEFAULT*/
|
||||
```
|
||||
|
||||
|
||||
The styles can be cascaded (similarly to CSS). It means you can add more styles to a part of an object.
|
||||
Styles can be cascaded (similarly to CSS). It means you can add more styles to a part of an object.
|
||||
For example `style_btn` can set a default button appearance, and `style_btn_red` can overwrite the background color to make the button red:
|
||||
```c
|
||||
lv_obj_add_style(btn1, &style_btn, 0);
|
||||
@ -227,13 +227,13 @@ lv_obj_add_style(btn1, &style1_btn_red, 0);
|
||||
```
|
||||
|
||||
|
||||
If a property is not set on for the current state the style with `LV_STATE_DEFAULT` will be used. If the property is not defined even in the default state a default value is used.
|
||||
If a property is not set on for the current state, the style with `LV_STATE_DEFAULT` will be used. A default value is used if the property is not defined in the default state.
|
||||
|
||||
Some properties (typically the text-related ones) can be inherited. It means if a property is not set in an object it will be searched in its parents too.
|
||||
Some properties (typically the text-related ones) can be inherited. This means if a property is not set in an object it will be searched for in its parents too.
|
||||
For example, you can set the font once in the screen's style and all text on that screen will inherit it by default.
|
||||
|
||||
|
||||
Local style properties also can be added to the objects. It creates a style which resides inside the object and which is used only by the object:
|
||||
Local style properties also can be added to objects. This creates a style which resides inside the object and is used only by the object:
|
||||
```c
|
||||
lv_obj_set_style_bg_color(slider1, lv_color_hex(0x2080bb), LV_PART_INDICATOR | LV_STATE_PRESSED);
|
||||
```
|
||||
@ -242,10 +242,10 @@ To learn all the features of styles see the [Style overview](/overview/style) se
|
||||
|
||||
|
||||
### Themes
|
||||
Themes are the default styles of the objects.
|
||||
The styles from the themes are applied automatically when the objects are created.
|
||||
|
||||
You can select the theme to use in `lv_conf.h`.
|
||||
Themes are the default styles for objects. Styles from a theme are applied automatically when objects are created.
|
||||
|
||||
The theme for your application is a compile time configuration set in `lv_conf.h`.
|
||||
|
||||
## Examples
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
# Introduction
|
||||
|
||||
LVGL (Light and Versatile Graphics Library) is a free and open-source graphics library providing everything you need to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and a low memory footprint.
|
||||
LVGL (Light and Versatile Graphics Library) is a free and open-source graphics library providing everything you need to create an embedded GUI with easy-to-use graphical elements, beautiful visual effects and a low memory footprint.
|
||||
|
||||
|
||||
## Key features
|
||||
@ -17,29 +17,29 @@ LVGL (Light and Versatile Graphics Library) is a free and open-source graphics l
|
||||
- Fully customizable graphic elements with CSS-like styles
|
||||
- Hardware independent: use with any microcontroller or display
|
||||
- Scalable: able to operate with little memory (64 kB Flash, 16 kB RAM)
|
||||
- OS, external memory and GPU supported but not required
|
||||
- OS, external memory and GPU are supported but not required
|
||||
- Single frame buffer operation even with advanced graphic effects
|
||||
- Written in C for maximal compatibility (C++ compatible)
|
||||
- Simulator to start embedded GUI design on a PC without embedded hardware
|
||||
- Binding to MicroPython
|
||||
- Tutorials, examples, themes for rapid GUI design
|
||||
- Documentation is available online and PDF
|
||||
- Documentation is available online and as PDF
|
||||
- Free and open-source under MIT license
|
||||
|
||||
## Requirements
|
||||
Basically, every modern controller (which is able to drive a display) is suitable to run LVGL. The minimal requirements are:
|
||||
Basically, every modern controller which is able to drive a display is suitable to run LVGL. The minimal requirements are:
|
||||
<ul>
|
||||
<li> 16, 32 or 64 bit microcontroller or processor</li>
|
||||
<li>> 16 MHz clock speed is recommended</li>
|
||||
<li> Flash/ROM: > 64 kB for the very essential components (> 180 kB is recommended)</li>
|
||||
<li> RAM:
|
||||
<ul>
|
||||
<li> Static RAM usage: ~2 kB depending on the used features and objects types</li>
|
||||
<li> Static RAM usage: ~2 kB depending on the used features and object types</li>
|
||||
<li> Stack: > 2kB (> 8 kB is recommended)</li>
|
||||
<li> Dynamic data (heap): > 4 KB (> 32 kB is recommended if using several objects).
|
||||
Set by <em>LV_MEM_SIZE</em> in <em>lv_conf.h</em>. </li>
|
||||
<li> Display buffer: > <em>"Horizontal resolution"</em> pixels (> 10 × <em>"Horizontal resolution"</em> is recommended) </li>
|
||||
<li> One frame buffer in the MCU or in external display controller</li>
|
||||
<li> One frame buffer in the MCU or in an external display controller</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li> C99 or newer compiler</li>
|
||||
@ -52,7 +52,7 @@ Basically, every modern controller (which is able to drive a display) is suita
|
||||
|
||||
## License
|
||||
The LVGL project (including all repositories) is licensed under [MIT license](https://github.com/lvgl/lvgl/blob/master/LICENCE.txt).
|
||||
It means you can use it even in commercial projects.
|
||||
This means you can use it even in commercial projects.
|
||||
|
||||
It's not mandatory but we highly appreciate it if you write a few words about your project in the [My projects](https://forum.lvgl.io/c/my-projects/10) category of the forum or a private message to [lvgl.io](https://lvgl.io/#contact).
|
||||
|
||||
@ -85,16 +85,16 @@ The core repositories follow the rules of [Semantic versioning](https://semver.o
|
||||
Tags like `vX.Y.Z` are created for every release.
|
||||
|
||||
### Release cycle
|
||||
- Bugfixes: Released on demand even weekly
|
||||
- Bug fixes: Released on demand even weekly
|
||||
- Minor releases: Every 3-4 months
|
||||
- Major releases: Approximatelly yearly
|
||||
- Major releases: Approximately yearly
|
||||
|
||||
### Branches
|
||||
The core repositories have at least the following branches:
|
||||
- `master` latest version, patches are merged directly here.
|
||||
- `release/vX.Y` stable versions of the minor releases
|
||||
- `fix/some-description` temporal branches for bug fixes
|
||||
- `feat/some-description` temporal branches for features
|
||||
- `fix/some-description` temporary branches for bug fixes
|
||||
- `feat/some-description` temporary branches for features
|
||||
|
||||
|
||||
### Changelog
|
||||
@ -103,7 +103,7 @@ The changes are recorded in [CHANGELOG.md](/CHANGELOG).
|
||||
|
||||
### Version support
|
||||
Before v8 every minor release of major releases is supported for 1 year.
|
||||
From v8 every minor release is supported for 1 year.
|
||||
Starting from v8, every minor release is supported for 1 year.
|
||||
|
||||
| Version | Release date | Support end | Active |
|
||||
|---------|--------------|-------------|--------|
|
||||
@ -119,24 +119,24 @@ From v8 every minor release is supported for 1 year.
|
||||
You can ask questions in the forum: [https://forum.lvgl.io/](https://forum.lvgl.io/).
|
||||
|
||||
We use [GitHub issues](https://github.com/lvgl/lvgl/issues) for development related discussion.
|
||||
So you should use them only if your question or issue is tightly related to the development of the library.
|
||||
You should use them only if your question or issue is tightly related to the development of the library.
|
||||
|
||||
### Is my MCU/hardware supported?
|
||||
Every MCU which is capable of driving a display via Parallel port, SPI, RGB interface or anything else and fulfills the [Requirements](#requirements) is supported by LLVGL.
|
||||
Every MCU which is capable of driving a display via parallel port, SPI, RGB interface or anything else and fulfills the [Requirements](#requirements) is supported by LVGL.
|
||||
|
||||
This includes:
|
||||
- "Common" MCUs like STM32F, STM32H, NXP Kinetis, LPC, iMX, dsPIC33, PIC32 etc.
|
||||
- Bluetooth, GSM, Wi-Fi modules like Nordic NRF and Espressif ESP32
|
||||
- Linux with frame buffer device such as /dev/fb0. This includes Single-board computers like the Raspberry Pi
|
||||
- And anything else with a strong enough MCU and a periphery to drive a display
|
||||
- Anything else with a strong enough MCU and a peripheral to drive a display
|
||||
|
||||
### Is my display supported?
|
||||
LVGL needs just one simple driver function to copy an array of pixels into a given area of the display.
|
||||
If you can do this with your display then you can use that display with LVGL.
|
||||
If you can do this with your display then you can use it with LVGL.
|
||||
|
||||
Some examples of the supported display types:
|
||||
- TFTs with 16 or 24 bit color depth
|
||||
- Monitors with HDMI port
|
||||
- Monitors with an HDMI port
|
||||
- Small monochrome displays
|
||||
- Gray-scale displays
|
||||
- even LED matrices
|
||||
@ -147,7 +147,7 @@ See the [Porting](/porting/display) section to learn more.
|
||||
### Nothing happens, my display driver is not called. What have I missed?
|
||||
Be sure you are calling `lv_tick_inc(x)` in an interrupt and `lv_timer_handler()` in your main `while(1)`.
|
||||
|
||||
Learn more in the [Tick](/porting/tick) and [Task handler](/porting/task-handler) section.
|
||||
Learn more in the [Tick](/porting/tick) and [Task handler](/porting/task-handler) sections.
|
||||
|
||||
### Why is the display driver called only once? Only the upper part of the display is refreshed.
|
||||
Be sure you are calling `lv_disp_flush_ready(drv)` at the end of your "*display flush callback*".
|
||||
@ -178,35 +178,31 @@ a.y2 = a.y1 + BUF_H - 1;
|
||||
my_flush_cb(NULL, &a, buf);
|
||||
```
|
||||
|
||||
### Why I see nonsense colors on the screen?
|
||||
Probably LVGL's color format is not compatible with your displays color format. Check `LV_COLOR_DEPTH` in *lv_conf.h*.
|
||||
### Why do I see nonsense colors on the screen?
|
||||
Probably LVGL's color format is not compatible with your display's color format. Check `LV_COLOR_DEPTH` in *lv_conf.h*.
|
||||
|
||||
If you are using 16-bit colors with SPI (or other byte-oriented interface) probably you need to set `LV_COLOR_16_SWAP 1` in *lv_conf.h*.
|
||||
If you are using 16-bit colors with SPI (or another byte-oriented interface) you probably need to set `LV_COLOR_16_SWAP 1` in *lv_conf.h*.
|
||||
It swaps the upper and lower bytes of the pixels.
|
||||
|
||||
### How to speed up my UI?
|
||||
- Turn on compiler optimization and enable cache if your MCU has
|
||||
- Turn on compiler optimization and enable cache if your MCU has it
|
||||
- Increase the size of the display buffer
|
||||
- Use 2 display buffers and flush the buffer with DMA (or similar periphery) in the background
|
||||
- Increase the clock speed of the SPI or Parallel port if you use them to drive the display
|
||||
- If your display has SPI port consider changing to a model with parallel because it has much higher throughput
|
||||
- Keep the display buffer in the internal RAM (not in external SRAM) because LVGL uses it a lot and it should have a small access time
|
||||
- Use two display buffers and flush the buffer with DMA (or similar peripheral) in the background
|
||||
- Increase the clock speed of the SPI or parallel port if you use them to drive the display
|
||||
- If your display has a SPI port consider changing to a model with a parallel interface because it has much higher throughput
|
||||
- Keep the display buffer in internal RAM (not in external SRAM) because LVGL uses it a lot and it should have a fast access time
|
||||
|
||||
### How to reduce flash/ROM usage?
|
||||
You can disable all the unused features (such as animations, file system, GPU etc.) and object types in *lv_conf.h*.
|
||||
|
||||
If you are using GCC you can add
|
||||
- `-fdata-sections -ffunction-sections` compiler flags
|
||||
- `--gc-sections` linker flag
|
||||
|
||||
to remove unused functions and variables from the final binary
|
||||
If you are using GCC you can add `-fdata-sections -ffunction-sections` compiler flags and `--gc-sections` linker flag to remove unused functions and variables from the final binary.
|
||||
|
||||
### How to reduce the RAM usage
|
||||
- Lower the size of the *Display buffer*
|
||||
- Reduce `LV_MEM_SIZE` in *lv_conf.h*. This memory used when you create objects like buttons, labels, etc.
|
||||
- To work with lower `LV_MEM_SIZE` you can create the objects only when required and deleted them when they are not required anymore
|
||||
- Reduce `LV_MEM_SIZE` in *lv_conf.h*. This memory is used when you create objects like buttons, labels, etc.
|
||||
- To work with lower `LV_MEM_SIZE` you can create objects only when required and delete them when they are not needed anymore
|
||||
|
||||
### How to work with an operating system?
|
||||
|
||||
To work with an operating system where tasks can interrupt each other (preemptive) you should protect LVGL related function calls with a mutex.
|
||||
To work with an operating system where tasks can interrupt each other (preemptively) you should protect LVGL related function calls with a mutex.
|
||||
See the [Operating system and interrupts](/porting/os) section to learn more.
|
||||
|
@ -5,13 +5,13 @@
|
||||
# Animations
|
||||
|
||||
You can automatically change the value of a variable between a start and an end value using animations.
|
||||
The animation will happen by periodically calling an "animator" function with the corresponding value parameter.
|
||||
Animation will happen by periodically calling an "animator" function with the corresponding value parameter.
|
||||
|
||||
The *animator* functions have the following prototype:
|
||||
```c
|
||||
void func(void * var, lv_anim_var_t value);
|
||||
```
|
||||
This prototype is compatible with the majority of the *set* functions of LVGL. For example `lv_obj_set_x(obj, value)` or `lv_obj_set_width(obj, value)`
|
||||
This prototype is compatible with the majority of the property *set* functions in LVGL. For example `lv_obj_set_x(obj, value)` or `lv_obj_set_width(obj, value)`
|
||||
|
||||
|
||||
## Create an animation
|
||||
@ -31,7 +31,7 @@ lv_anim_init(&a);
|
||||
/*Set the "animator" function*/
|
||||
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t) lv_obj_set_x);
|
||||
|
||||
/*Set the "animator" function*/
|
||||
/*Set target of the animation*/
|
||||
lv_anim_set_var(&a, obj);
|
||||
|
||||
/*Length of the animation [ms]*/
|
||||
@ -49,25 +49,25 @@ 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.*/
|
||||
/*Set a callback to indicate when the animation is ready (idle).*/
|
||||
lv_anim_set_ready_cb(&a, ready_cb);
|
||||
|
||||
/*Set a callback to call when animation is started (after delay).*/
|
||||
/*Set a callback to indicate when the 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);
|
||||
/*When ready, play the animation backward with this duration. Default is 0 (disabled) [ms]*/
|
||||
lv_anim_set_playback_time(&a, time);
|
||||
|
||||
/*Delay before playback. Default is 0 (disabled) [ms]*/
|
||||
lv_anim_set_playback_delay(&a, wait_time);
|
||||
lv_anim_set_playback_delay(&a, delay);
|
||||
|
||||
/*Number of repetitions. Default is 1. LV_ANIM_REPEAT_INFINIT for infinite repetition*/
|
||||
lv_anim_set_repeat_count(&a, wait_time);
|
||||
/*Number of repetitions. Default is 1. LV_ANIM_REPEAT_INFINITE for infinite repetition*/
|
||||
lv_anim_set_repeat_count(&a, cnt);
|
||||
|
||||
/*Delay before repeat. Default is 0 (disabled) [ms]*/
|
||||
lv_anim_set_repeat_delay(&a, wait_time);
|
||||
lv_anim_set_repeat_delay(&a, delay);
|
||||
|
||||
/*true (default): apply the start vale immediately, false: apply start vale after delay when then anim. really starts. */
|
||||
/*true (default): apply the start value immediately, false: apply start value after delay when the anim. really starts. */
|
||||
lv_anim_set_early_apply(&a, true/false);
|
||||
|
||||
/* START THE ANIMATION
|
||||
@ -77,55 +77,54 @@ 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.
|
||||
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 and `lv_anim_start()` will remove any existing animations for such a pair.
|
||||
|
||||
## Animation path
|
||||
|
||||
You can determinate the path of animation. The most simple case is linear, meaning the current value between *start* and *end* is changed with fixed steps.
|
||||
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:
|
||||
You can control the path of an animation. The most simple case is linear, meaning the current value between *start* and *end* is changed with fixed steps.
|
||||
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 path 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 at the end
|
||||
- `lv_anim_path_ease_in_out` slow at the beginning and end
|
||||
- `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 set the animation time. But in some cases, setting the animation speed is more practical.
|
||||
By default, you set the animation time directly. But in some cases, setting 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 yield 5000 milliseconds. For example, in case of `lv_obj_set_x` *unit* is pixels so *20* means *20 px/sec* speed.
|
||||
The speed is interpreted in _unit/sec_ dimension. For example, `lv_anim_speed_to_time(20,0,100)` will yield 5000 milliseconds. For example, in the case of `lv_obj_set_x` *unit* is pixels so *20* means *20 px/sec* speed.
|
||||
|
||||
## Delete animations
|
||||
|
||||
You can delete an animation with `lv_anim_del(var, func)` if you provide the animated variable and its animator function.
|
||||
|
||||
## Timeline
|
||||
Timeline is a collection of multiple Animations, which makes it easy to create complex composite animations.
|
||||
A timeline is a collection of multiple animations which makes it easy to create complex composite animations.
|
||||
|
||||
Firstly, create the animation element, but don’t call `lv_anim_start()`.
|
||||
Firstly, create an animation element but don’t call `lv_anim_start()`.
|
||||
|
||||
Secondly, create an animation timeline object, by calling `lv_anim_timeline_create()`.
|
||||
Secondly, create an animation timeline object by calling `lv_anim_timeline_create()`.
|
||||
|
||||
Thirdly, add animation elements to the animation timeline, by calling `lv_anim_timeline_add(at, start_time, &a)`. `start_time` is the start time of the animation on the timeline. Note that `start_time` will override the value of `delay`.
|
||||
Thirdly, add animation elements to the animation timeline by calling `lv_anim_timeline_add(at, start_time, &a)`. `start_time` is the start time of the animation on the timeline. Note that `start_time` will override the value of `delay`.
|
||||
|
||||
Finally, call `lv_anim_timeline_start(at)` to start the animation timeline.
|
||||
|
||||
It supports forward and backward playback of the entire animation group, using `lv_anim_timeline_set_reverse(at, reverse)`.
|
||||
|
||||
Call the `lv_anim_timeline_stop(at)` to stop the animation timeline.
|
||||
Call `lv_anim_timeline_stop(at)` to stop the animation timeline.
|
||||
|
||||
Call the `lv_anim_timeline_set_progress(at, progress)` function to set the state of the object corresponding to the progress of the timeline.
|
||||
Call `lv_anim_timeline_set_progress(at, progress)` function to set the state of the object corresponding to the progress of the timeline.
|
||||
|
||||
Call the `lv_anim_timeline_get_playtime(at)` function to get the total duration of the entire animation timeline.
|
||||
Call `lv_anim_timeline_get_playtime(at)` function to get the total duration of the entire animation timeline.
|
||||
|
||||
Call the `lv_anim_timeline_get_reverse(at)` function to get whether to reverse the animation timeline.
|
||||
Call `lv_anim_timeline_get_reverse(at)` function to get whether to reverse the animation timeline.
|
||||
|
||||
Call the `lv_anim_timeline_del(at)` function to delete the animation timeline.
|
||||
Call `lv_anim_timeline_del(at)` function to delete the animation timeline.
|
||||
|
||||
![](/misc/anim-timeline.png "timeline diagram")
|
||||
|
||||
|
@ -6,14 +6,14 @@
|
||||
|
||||
The color module handles all color-related functions like changing color depth, creating colors from hex code, converting between color depths, mixing colors, etc.
|
||||
|
||||
`lv_color_t` is used to store a color, its fields are set according to `LV_COLOR_DEPTH` in `lv_conf.h`. (See below)
|
||||
The type `lv_color_t` is used to store a color. Its fields are set according to `LV_COLOR_DEPTH` in `lv_conf.h`. (See below)
|
||||
|
||||
You may set `LV_COLOR_16_SWAP` in `lv_conf.h` to swap the bytes of *RGB565* colors. You may need this to 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.
|
||||
You may set `LV_COLOR_16_SWAP` in `lv_conf.h` to swap bytes of *RGB565* colors. You may need this when sending 16-bit colors via a byte-oriented interface like SPI. As 16-bit numbers are stored in little-endian format (lower byte at 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.
|
||||
|
||||
## Creating colors
|
||||
|
||||
### RGB
|
||||
Create colors from Red, Green and Blue channel values
|
||||
Create colors from Red, Green and Blue channel values:
|
||||
```c
|
||||
//All channels are 0-255
|
||||
lv_color_t c = lv_color_make(red, green, blue);
|
||||
@ -26,7 +26,7 @@ lv_color_t c = lv_color_hex3(0x123);
|
||||
```
|
||||
|
||||
### HSV
|
||||
Create colors from Hue, Saturation and Value values
|
||||
Create colors from Hue, Saturation and Value values:
|
||||
|
||||
```c
|
||||
//h = 0..359, s = 0..100, v = 0..100
|
||||
@ -41,7 +41,7 @@ lv_color_hsv_t c_hsv = lv_color_to_hsv(color);
|
||||
```
|
||||
|
||||
### Palette
|
||||
LVGL includes [material design's palette](https://vuetifyjs.com/en/styles/colors/#material-colors). In this all color have a main as well as four darker and five lighter variants.
|
||||
LVGL includes [Material Design's palette](https://vuetifyjs.com/en/styles/colors/#material-colors) of colors. In this system all named colors have a nominal main color as well as four darker and five lighter variants.
|
||||
|
||||
The names of the colors are as follows:
|
||||
- `LV_PALETTE_RED`
|
||||
@ -83,7 +83,7 @@ lv_color_t c = lv_color_darken(lv_color_t c, lv_opa_t lvl);
|
||||
lv_color_t c = lv_color_change_lightness(lv_color_t c, lv_opa_t lvl);
|
||||
|
||||
|
||||
// Mix 2 colors with a given ratio 0: full c2, 255: full c1, 128: half c1 and half c2
|
||||
// Mix two colors with a given ratio 0: full c2, 255: full c1, 128: half c1 and half c2
|
||||
lv_color_t c = lv_color_mix(c1, c2, ratio);
|
||||
```
|
||||
|
||||
@ -91,15 +91,15 @@ lv_color_t c = lv_color_mix(c1, c2, ratio);
|
||||
`lv_color_white()` and `lv_color_black()` return `0xFFFFFF` and `0x000000` respectively.
|
||||
|
||||
## Opacity
|
||||
To describe opacity the `lv_opa_t` type is created as a wrapper to `uint8_t`. Some defines are also introduced:
|
||||
To describe opacity the `lv_opa_t` type is created from `uint8_t`. Some special purpose defines are also introduced:
|
||||
|
||||
- `LV_OPA_TRANSP` Value: 0, means the opacity makes the color completely transparent
|
||||
- `LV_OPA_TRANSP` Value: 0, means no opacity making 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_20 ... OPA_80` follow logically
|
||||
- `LV_OPA_90` Value: 229, means the color near completely covers
|
||||
- `LV_OPA_COVER` Value: 255, means the color completely covers
|
||||
- `LV_OPA_COVER` Value: 255, means the color completely covers (full opacity)
|
||||
|
||||
You can also use the `LV_OPA_*` defines in `lv_color_mix()` as a *ratio*.
|
||||
You can also use the `LV_OPA_*` defines in `lv_color_mix()` as a mixing *ratio*.
|
||||
|
||||
|
||||
## Color types
|
||||
@ -109,8 +109,8 @@ The following variable types are defined by the color module:
|
||||
- `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` depending on current color depth setting
|
||||
- `lv_color_int_t` `uint8_t`, `uint16_t` or `uint32_t` depending on color depth setting. Used to build color arrays from plain numbers.
|
||||
- `lv_color_t` Equal to `lv_color1/8/16/24_t` depending on the configured color depth setting
|
||||
- `lv_color_int_t` `uint8_t`, `uint16_t` or `uint32_t` depending on the 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 four fields:
|
||||
@ -124,7 +124,7 @@ You can set the current color depth in *lv_conf.h*, by setting the `LV_COLOR_DEP
|
||||
|
||||
|
||||
### 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:
|
||||
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 to map a converted color back into a structure:
|
||||
|
||||
```c
|
||||
lv_color_t c;
|
||||
|
@ -5,9 +5,10 @@
|
||||
# Positions, sizes, and layouts
|
||||
|
||||
## Overview
|
||||
Similarly to many other parts of LVGL, the concept of setting the coordinates was inspired by CSS. By no means a complete implementation of the standard but subsets of CSS were implemented (sometimes with minor adjustments).
|
||||
In shorts this means:
|
||||
- the set coordinates (size, position, layouts, etc.) are stored in styles
|
||||
Similarly to many other parts of LVGL, the concept of setting the coordinates was inspired by CSS. LVGL has by no means a complete implementation of CSS but a comparable subset is implemented (sometimes with minor adjustments).
|
||||
|
||||
In short this means:
|
||||
- Explicitly set coordinates are stored in styles (size, position, layouts, etc.)
|
||||
- support min-width, max-width, min-height, max-height
|
||||
- have pixel, percentage, and "content" units
|
||||
- x=0; y=0 coordinate means the top-left corner of the parent plus the left/top padding plus border width
|
||||
@ -15,8 +16,8 @@ In shorts this means:
|
||||
- a subset of flexbox and grid layouts are supported
|
||||
|
||||
### Units
|
||||
- pixel: Simply a position in pixels. A simple integer always means 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))`
|
||||
- pixel: Simply a position in pixels. An integer always means pixels. E.g. `lv_obj_set_x(btn, 10)`
|
||||
- percentage: The percentage of the size of the object or its parent (depending on the property). `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. It's similar to `auto` in CSS. E.g. `lv_obj_set_width(btn, LV_SIZE_CONTENT)`.
|
||||
|
||||
### Boxing model
|
||||
@ -25,11 +26,11 @@ 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.
|
||||
- content: the content area which is the size of the bounding box reduced by the border width and padding.
|
||||
|
||||
![The box models of LVGL: The content area is smaller than the bounding box with the padding and border width](/misc/boxmodel.png)
|
||||
|
||||
The border is drawn inside the bounding box. Inside the border LVGL keeps "padding size" to place the children.
|
||||
The border is drawn inside the bounding box. Inside the border LVGL keeps a "padding margin" when placing an object's children.
|
||||
|
||||
The outline is drawn outside the bounding box.
|
||||
|
||||
@ -40,16 +41,16 @@ This section describes special cases in which LVGL's behavior might be unexpecte
|
||||
LVGL doesn't recalculate all the coordinate changes immediately. This is done 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 coordinate of an object and the coordinates were just changed LVGL needs to be forced to recalculate the coordinates.
|
||||
In other words, if you need to get the coordinate of an object and the coordinates were just changed, LVGL needs to be forced to recalculate the coordinates.
|
||||
To do this call `lv_obj_update_layout(obj)`.
|
||||
|
||||
|
||||
The size and position might depend on the parent or layout. Therefore `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.
|
||||
As it's described in the [Using styles](#using-styles) section, coordinates can also be set via style properties.
|
||||
To be more precise, under the hood every style coordinate related property is stored as a style 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 be aware of that. If the style(s) of an object are removed by
|
||||
This is an internal mechanism and doesn't matter much as you use LVGL. However, there is one case in which you need to be aware of the implementation. If the style(s) of an object are removed by
|
||||
```c
|
||||
lv_obj_remove_style_all(obj)
|
||||
```
|
||||
@ -75,19 +76,19 @@ lv_obj_set_size(obj2, 200, 100);
|
||||
## Position
|
||||
|
||||
### Simple way
|
||||
To simple set the x and y coordinates of an object use
|
||||
To simply set the x and y coordinates of an object use:
|
||||
```c
|
||||
lv_obj_set_x(obj, 10);
|
||||
lv_obj_set_x(obj, 10); //Separate...
|
||||
lv_obj_set_y(obj, 20);
|
||||
lv_obj_set_pos(obj, 10, 20); //Or in one function
|
||||
```
|
||||
|
||||
By default, 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 pixels padding on every side, the above code will place `obj` at (15, 25) because the content area starts after the padding.
|
||||
For example if the parent has five pixels of padding on every side the above code will place `obj` at (15, 25) because the content area starts after the padding.
|
||||
|
||||
If percentage values are calculated from the parents content area size.
|
||||
Percentage values are calculated from the parent's content area size.
|
||||
```c
|
||||
lv_obj_set_x(btn, lv_pct(10)); //x = 10 % of parant content area width
|
||||
lv_obj_set_x(btn, lv_pct(10)); //x = 10 % of parent content area width
|
||||
```
|
||||
|
||||
### Align
|
||||
@ -121,14 +122,14 @@ lv_obj_center(obj);
|
||||
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.
|
||||
If the parent's size changes, the set alignment and position of the children is updated automatically.
|
||||
|
||||
The functions introduced above align the object to its parent. However, it's also possible to align an object to an arbitrary object.
|
||||
The functions introduced above align the object to its parent. However, it's also possible to align an object to an arbitrary reference 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 the reference object:
|
||||
Besides the alignments options above, the following can be used to align an object outside the reference object:
|
||||
|
||||
- `LV_ALIGN_OUT_TOP_LEFT`
|
||||
- `LV_ALIGN_OUT_TOP_MID`
|
||||
@ -148,14 +149,14 @@ For example to align a label above a button and center the label horizontally:
|
||||
lv_obj_align_to(label, btn, LV_ALIGN_OUT_TOP_MID, 0, -10);
|
||||
```
|
||||
|
||||
Note 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.
|
||||
Note that, unlike with `lv_obj_align()`, `lv_obj_align_to()` can not realign the object if its coordinates or the reference object's coordinates change.
|
||||
|
||||
## 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_width(obj, 200); //Separate...
|
||||
lv_obj_set_height(obj, 100);
|
||||
lv_obj_set_size(obj, 200, 100); //Or in one function
|
||||
```
|
||||
@ -163,14 +164,14 @@ 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 the size of its children.
|
||||
Note that only children on the right and bottom will be considered and children on the top and left remain cropped. This limitation makes the behavior more predictable.
|
||||
The size settings support a special value: `LV_SIZE_CONTENT`. It means the object's size in the respective direction will be set to the size of its children.
|
||||
Note that only children on the right and bottom sides will be considered and children on the top and left remain cropped. This limitation makes the behavior more predictable.
|
||||
|
||||
Objects with `LV_OBJ_FLAG_HIDDEN` or `LV_OBJ_FLAG_FLOATING` will be ignored by the `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.
|
||||
The above functions set the size of an object's bounding box but the size of the content area can be set as well. This means an object's bounding box will be enlarged with the addition of padding.
|
||||
```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
|
||||
@ -188,11 +189,11 @@ lv_coord_t content_h = lv_obj_get_content_height(obj);
|
||||
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 object.
|
||||
|
||||
However, using styles as to set the coordinates has some great advantages:
|
||||
However, using styles to set the coordinates has some great advantages:
|
||||
- It makes it easy to set the width/height/etc. for several objects together. E.g. 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`.
|
||||
- The values can be partially 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 depending on 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.
|
||||
|
||||
|
||||
@ -207,14 +208,14 @@ 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.
|
||||
However, to keep the LVGL 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.
|
||||
Now you want to move a button up a little when it's pressed.
|
||||
|
||||
One way to achieve this is setting a new Y coordinate for pressed state:
|
||||
One way to achieve this is by setting a new Y coordinate for the pressed state:
|
||||
```c
|
||||
static lv_style_t style_normal;
|
||||
lv_style_init(&style_normal);
|
||||
@ -234,7 +235,7 @@ 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:
|
||||
This 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. Translations can be used to solve this:
|
||||
```c
|
||||
static lv_style_t style_normal;
|
||||
lv_style_init(&style_normal);
|
||||
@ -258,17 +259,17 @@ 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 translation is applied after the layouts are calculated. Therefore, even the layouted objects' position can be translated.
|
||||
The translation is applied after the layouts are calculated. Therefore, even laid out objects' position can be translated.
|
||||
|
||||
The translation actually moves the object. It means it makes the scrollbars and `LV_SIZE_CONTENT` sized objects react to the position change.
|
||||
The translation actually moves the object. That means it makes the scrollbars and `LV_SIZE_CONTENT` sized objects react to 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 are added on both sides of the object. This means 10 px transformed width makes the object 2x10 pixel wider.
|
||||
Similarly to position, an object's size can be changed relative to the current size as well.
|
||||
The transformed width and height are added on both sides of the object. This means a 10 px transformed width makes the object 2x10 pixels 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.
|
||||
Unlike position translation, the size transformation doesn't make the object "really" larger. In other words scrollbars, layouts, and `LV_SIZE_CONTENT` will not react to the transformed size.
|
||||
Hence, size transformation is "only" a visual effect.
|
||||
|
||||
This code enlarges a button when it's pressed:
|
||||
```c
|
||||
@ -281,7 +282,7 @@ 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 than these values.
|
||||
Similarly to CSS, LVGL also supports `min-width`, `max-width`, `min-height` and `max-height`. These are limits preventing an object's size from becoming smaller/larger than 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;
|
||||
@ -292,7 +293,7 @@ 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.
|
||||
Percentage values can be used as well which are relative to the size of the parent's content area.
|
||||
```c
|
||||
static lv_style_t style_max_height;
|
||||
lv_style_init(&style_max_height);
|
||||
@ -309,8 +310,8 @@ Layouts can update the position and size of an object's children. They can be us
|
||||
|
||||
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.
|
||||
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 further settings of the parent and children see the documentation of the given layout.
|
||||
|
||||
### Built-in layout
|
||||
LVGL comes with two very powerful layouts:
|
||||
@ -320,10 +321,10 @@ LVGL comes with two very powerful layouts:
|
||||
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.
|
||||
There are some flags that can be used on objects to affect how they behave with layouts:
|
||||
- `LV_OBJ_FLAG_HIDDEN` Hidden objects are ignored in 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.
|
||||
- `LV_OBJ_FLAG_FLOATING` Same as `LV_OBJ_FLAG_IGNORE_LAYOUT` but the object with `LV_OBJ_FLAG_FLOATING` will be ignored in `LV_SIZE_CONTENT` calculations.
|
||||
|
||||
These flags can be added/removed with `lv_obj_add/clear_flag(obj, FLAG);`
|
||||
|
||||
@ -341,7 +342,7 @@ 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" */
|
||||
/*Will be called automatically if it's required to reposition/resize the children of "obj" */
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -4,12 +4,12 @@
|
||||
```
|
||||
# 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.
|
||||
``` important:: The basic concept of a *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 have the same color depth (as defined in `LV_COLOR_DEPTH`).
|
||||
In LVGL you can have multiple displays, each with their own driver and objects. The only limitation is that every display needs to have the 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.
|
||||
@ -22,26 +22,26 @@ Why would you want multi-display support? Here are some examples:
|
||||
- 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 (and only) display is used.
|
||||
Using more displays can be useful but in most cases it's not required. Therefore, the whole concept of multi-display handling is completely hidden if you register only one display.
|
||||
By default, the last created (and only) display is used.
|
||||
|
||||
`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 most recently 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)).
|
||||
`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 most recently created (default) display.
|
||||
If you pass `NULL` as `disp` parameter to display related functions the default display will usually be used.
|
||||
E.g. `lv_disp_trig_activity(NULL)` will trigger a user activity on the default display. (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 the other display too.
|
||||
To mirror the image of a display to another display, you don't need to use multi-display support. Just transfer the buffer received in `drv.flush_cb` to the other display too.
|
||||
|
||||
### Split image
|
||||
You can create a larger display from smaller ones. You can create it as below:
|
||||
You can create a larger virtual display from an array of 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.
|
||||
3. Send the buffer's content to each real display with the truncated area.
|
||||
|
||||
## Screens
|
||||
|
||||
Every display has its own set of [screens](overview/object#screen-the-most-basic-parent) and the object on the screens.
|
||||
Every display has its own set of [screens](overview/object#screen-the-most-basic-parent) and the objects on each screen.
|
||||
|
||||
Be sure not to confuse displays and screens:
|
||||
|
||||
@ -49,27 +49,27 @@ Be sure not to confuse displays and screens:
|
||||
* **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's size is always equal to its display and their origin is (0;0). Therefore, a screen's 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).
|
||||
A screen can be created from any object type but the two most typical types are [Base object](/widgets/obj) and [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 another screen to copy it.
|
||||
To create a screen, use `lv_obj_t * scr = lv_<type>_create(NULL, copy)`. `copy` can be an existing screen copied into the new screen.
|
||||
|
||||
To load a screen, use `lv_scr_load(scr)`. To get the active screen, use `lv_scr_act()`. These functions work on the default display. If you want 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).
|
||||
To load a screen, use `lv_scr_load(scr)`. To get the active screen, use `lv_scr_act()`. These functions work on the default display. If you want to specify which display to work on, use `lv_disp_get_scr_act(disp)` and `lv_disp_load_scr(disp, scr)`. A 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.
|
||||
Usually, the opacity of the screen is `LV_OPA_COVER` to provide a solid background for its children. If this is 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 and display) could be used to create for example OSD menus where a video is played on a lower layer, and a menu is overlayed on an upper layer.
|
||||
|
||||
To handle transparent displays special (slower) color mixing algorithms need to be used by LVGL so this feature needs to enabled with `LV_COLOR_SCREEN_TRANSP` in `lv_conf.h`.
|
||||
To handle transparent displays, special (slower) color mixing algorithms need to be used by LVGL so this feature needs to enabled with `LV_COLOR_SCREEN_TRANSP` in `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 255 where there are solid objects.
|
||||
|
||||
In summary, to enable transparent screen and displays to create OSD menu-like UIs:
|
||||
In summary, to enable transparent screens and displays for OSD menu-like UIs:
|
||||
- Enable `LV_COLOR_SCREEN_TRANSP` in `lv_conf.h`
|
||||
- Be sure to use `LV_COLOR_DEPTH 32`
|
||||
- Set the screen's 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)`
|
||||
@ -79,22 +79,22 @@ In summary, to enable transparent screen and displays to create OSD menu-like UI
|
||||
|
||||
### 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**).
|
||||
A user's inactivity time 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 lowest inactivity time among all displays will be returned (**NULL isn't just 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.
|
||||
Every display has a background color, 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)`;
|
||||
The 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 a path to a file or a 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 be filled with `bg_color`.
|
||||
The display background image is a path to a file or a pointer to an `lv_img_dsc_t` variable (converted image data) to be used as wallpaper. It can be set with `lv_disp_set_bg_image(disp, &my_img)`;
|
||||
If a background image is configured the background won't be 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.
|
||||
The `disp` parameter of these functions can be `NULL` to select the default display.
|
||||
|
||||
|
||||
|
||||
|
@ -6,20 +6,20 @@
|
||||
|
||||
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.
|
||||
However, it can 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, that buffer is copied to the screen.
|
||||
The basic concept is to not draw directly onto the display but rather to first draw on an internal draw buffer. When a drawing (rendering) is ready that buffer is copied to the display.
|
||||
|
||||
The draw buffer can be smaller than the screen's size. LVGL will simply render in "tiles" that fit into the given draw buffer.
|
||||
The draw buffer can be smaller than a display'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 .
|
||||
This approach has two main advantages compared to directly drawing to the display:
|
||||
1. It avoids flickering while the layers of the UI are drawn. For example, if LVGL drew directly onto 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:
|
||||
Note that this concept is different from "traditional" double buffering where there are two display 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.
|
||||
The main difference is that with LVGL you don't have to store two frame buffers (which usually requires external RAM) but only smaller draw buffer(s) that can easily fit into internal RAM.
|
||||
|
||||
|
||||
## Mechanism of screen refreshing
|
||||
@ -27,63 +27,63 @@ The main difference is that with LVGL you don't have to store 2 frame buffers (w
|
||||
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, an animation happened, etc.
|
||||
1. Something happens in the UI which requires redrawing. For example, a button is pressed, a chart is changed, 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*.
|
||||
- Objects on other screens are not added.
|
||||
3. In every `LV_DISP_DEF_REFR_PERIOD` (set in `lv_conf.h`) the following happens:
|
||||
- LVGL checks the invalid areas and joins those that are adjacent or intersecting.
|
||||
- Takes the first joined area, if it's smaller than the *draw buffer*, then simply renders 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.
|
||||
- Repeat the same with remaining 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 that it's not required to draw the screen under the button too.
|
||||
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 necessary to redraw the display under the rest of 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.
|
||||
3. **Double buffering** - `flush_cb` should only swap the addresses of the frame buffers.
|
||||
|
||||
## 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, but you might find interesting to know how drawing works under hood.
|
||||
To use LVGL it's not required to know about the mechanisms described here but you might find interesting to know how drawing works under hood.
|
||||
Knowing about masking comes in handy if you want to customize drawing.
|
||||
|
||||
To learn masking let's see the steps of drawing first.
|
||||
To learn about masking let's see 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`). This gives us the parameters for drawing, for example the colors, widths, opacity, fonts, radius, etc.
|
||||
1. **Prepare the draw descriptors** Create a draw descriptor from an object's styles (e.g. `lv_draw_rect_dsc_t`). This gives us the parameters for drawing, for example 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 will render 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 in the draw function. (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.
|
||||
3. **Create masks** If the shape is very simple and doesn't require masks, go to #5. Otherwise, create the required masks in the draw function. (e.g. a rounded rectangle mask)
|
||||
4. **Calculate all the added mask** It composites opacity 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.) and opacity are handled.
|
||||
5. **Blend a color or image** During blending, masking (make some pixels transparent or opaque), blending modes (additive, subtractive, etc.) and color/image 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_LINE` Removes a side from a line (top, bottom, left or right). `lv_draw_line` uses four instances of it.
|
||||
Essentially, every (skew) line is bounded with four line masks forming a rectangle.
|
||||
- `LV_DRAW_MASK_TYPE_RADIUS` Removes the inner or outer corners of a rectangle with a radiused transition. It's also used to create circles by setting the radius to large value (`LV_RADIUS_CIRCLE`)
|
||||
- `LV_DRAW_MASK_TYPE_ANGLE` Removes a circlular 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
|
||||
- `LV_DRAW_MASK_TYPE_MAP` The mask is stored in a bitmap array and the necessary parts are applied
|
||||
|
||||
Masks are used to create almost every basic primitive:
|
||||
- **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.
|
||||
- **letters** Create a mask from the letter and draw a rectangle with the letter's color using the mask.
|
||||
- **line** Created from four "line masks" to mask out the left, right, top and bottom part of the line to get a perfectly perpendicular perimeter.
|
||||
- **rounded rectangle** A mask is created real-time to add a radius to the corners.
|
||||
- **clip corner** To clip overflowing content (usually children) on rounded corners, a rounded rectangle mask is also applied.
|
||||
- **rectangle border** Same as a rounded rectangle but the inner part is masked out too.
|
||||
- **arc drawing** A circular 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.
|
||||
|
||||
### Using masks
|
||||
|
||||
Every mask type has a related parameter to describe the mask's data. The following parameter types exist:
|
||||
Every mask type has a related parameter structure to describe the mask's data. The following parameter types exist:
|
||||
- `lv_draw_mask_line_param_t`
|
||||
- `lv_draw_mask_radius_param_t`
|
||||
- `lv_draw_mask_angle_param_t`
|
||||
@ -93,7 +93,7 @@ Every mask type has a related parameter to describe the mask's data. The followi
|
||||
1. Initialize a mask parameter with `lv_draw_mask_<type>_init`. See `lv_draw_mask.h` for the whole API.
|
||||
2. Add the mask parameter to the draw engine with `int16_t mask_id = lv_draw_mask_add(¶m, ptr)`. `ptr` can be any pointer to identify the mask, (`NULL` if unused).
|
||||
3. Call the draw functions
|
||||
4. Remove the mask from the draw engine with `lv_draw_mask_remove_id(mask_id)` of `lv_draw_mask_remove_custom(ptr)`.
|
||||
4. Remove the mask from the draw engine with `lv_draw_mask_remove_id(mask_id)` or `lv_draw_mask_remove_custom(ptr)`.
|
||||
5. Free the parameter with `lv_draw_mask_free_param(¶m)`.
|
||||
|
||||
A parameter can be added and removed any number of times, but it needs to be freed when not required anymore.
|
||||
@ -101,18 +101,18 @@ A parameter can be added and removed any number of times, but it needs to be fre
|
||||
`lv_draw_mask_add` saves only the pointer of the mask so the parameter needs to be valid while in use.
|
||||
|
||||
## Hook drawing
|
||||
Although widgets can be very well customized by styles there might be cases when something really custom is required.
|
||||
Although widgets can be easily customized by styles there might be cases when something more custom is required.
|
||||
To ensure a great level of flexibility LVGL sends a lot of events during drawing with parameters that tell 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.
|
||||
Some fields of these parameters can be modified to draw something else or any custom drawing operations 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 every button, and you can for example tell LVGL to use different colors on a specific button or to manually draw an image on some buttons.
|
||||
A good use case for this 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 every button and you can, for example, tell LVGL to use different colors on a specific button or to manually draw an image on some buttons.
|
||||
|
||||
Below each of these events are described in detail.
|
||||
Each of these events is described in detail below.
|
||||
|
||||
### Main drawing
|
||||
|
||||
These events are related to the actual drawing of the object. E.g. drawing of buttons, texts, etc. happens here.
|
||||
These events are related to the actual drawing of an object. E.g. the 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 a limited area.
|
||||
|
||||
@ -122,16 +122,16 @@ Sent before starting to draw an object. This is a good place to add masks manual
|
||||
|
||||
#### 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.
|
||||
The actual drawing of an 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`.
|
||||
Called when the main drawing is finished. You can draw anything here as well and it's also a good place to remove any 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.
|
||||
Post drawing events are called when all the children of an object are drawn. For example LVGL use the post drawing phase to draw scrollbars because they should be above all of the children.
|
||||
|
||||
`lv_event_get_clip_area(event)` can be used to get the current clip area.
|
||||
|
||||
@ -145,15 +145,15 @@ The actual drawing should happen 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.
|
||||
Called when post drawing has finished. If 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 that LVGL is planning to use for drawing.
|
||||
This allows changing the parts on a very low level with masks, extra drawing, or changing the parameters that 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.
|
||||
To see which fields are set for a widget refer to the widget's documentation.
|
||||
|
||||
`lv_obj_draw_part_t` has the following fields:
|
||||
|
||||
@ -172,8 +172,8 @@ lv_draw_arc_dsc_t * arc_dsc; // A draw descriptor that can be modified to
|
||||
|
||||
// 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.
|
||||
const lv_point_t * p1; // A point calculated during drawing. E.g. a point of a chart or the center of an arc.
|
||||
const lv_point_t * p2; // A point calculated during drawing. E.g. a point of a 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.
|
||||
@ -188,7 +188,7 @@ Start the drawing of a part. This is a good place to modify the draw descriptors
|
||||
|
||||
#### LV_EVENT_DRAW_PART_END
|
||||
|
||||
Finish the drawing of a part. This is a good place to draw extra content on the part, or remove the masks added in `LV_EVENT_DRAW_PART_BEGIN`.
|
||||
Finish the drawing of a part. This is a good place to draw extra content on the part or remove masks added in `LV_EVENT_DRAW_PART_BEGIN`.
|
||||
|
||||
### Others
|
||||
|
||||
@ -197,28 +197,28 @@ Finish the drawing of a part. This is a good place to draw extra content on the
|
||||
This event is used to check whether an object fully covers an area or not.
|
||||
|
||||
`lv_event_get_cover_area(event)` returns a 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 cover the area
|
||||
- `LV_COVER_RES_COVER` the area is fully covered by the object
|
||||
- `LV_COVER_RES_NOT_COVER` the area is not covered by the object
|
||||
- `LV_COVER_RES_MASKED` there is a mask on the object, so it does not fully cover the area
|
||||
|
||||
Here are some reasons why an object would be unable to fully cover an area:
|
||||
- It's simply not fully in area
|
||||
- It has a radius
|
||||
- It has not 100% background opacity
|
||||
- It doesn't have 100% background opacity
|
||||
- It's an ARGB or chroma keyed image
|
||||
- It does not have normal blending mode. In this case LVGL needs to know the colors under the object to do the blending properly
|
||||
- It does not have normal blending mode. In this case LVGL needs to know the colors under the object to apply blending properly
|
||||
- It's a text, etc
|
||||
|
||||
In short if for any reason the area below the object is visible than it doesn't cover that area.
|
||||
In short if for any reason the area below an object is visible than the object 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 the widget can't know about it.
|
||||
You need to check only the drawing you have added. The existing properties known by a widget are handled in its 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 the widget won't know about it.
|
||||
|
||||
#### LV_EVENT_REFR_EXT_DRAW_SIZE
|
||||
|
||||
If you need to draw outside a widget, LVGL needs to know about it to provide the extra space for drawing.
|
||||
If you need to draw outside a widget, LVGL needs to know about it to provide extra space for drawing.
|
||||
Let's say you create an event which 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 simply set the required draw area with `lv_event_set_ext_draw_size(e, size)`.
|
||||
|
@ -25,7 +25,7 @@ static void my_event_cb(lv_event_t * event)
|
||||
}
|
||||
```
|
||||
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.
|
||||
`LV_EVENT_ALL` can be used to receive all 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.
|
||||
|
||||
@ -45,7 +45,7 @@ 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*.
|
||||
Other objects can use the same *event callback*.
|
||||
|
||||
|
||||
## Remove event(s) from an object
|
||||
@ -65,33 +65,33 @@ All objects (such as Buttons/Labels/Sliders etc.) regardless their type receive
|
||||
|
||||
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.
|
||||
*Custom events* are added by the user and 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_PRESSED` An object has been pressed
|
||||
- `LV_EVENT_PRESSING` An object is being pressed (called continuously while pressing)
|
||||
- `LV_EVENT_PRESS_LOST` An object is still being pressed but slid cursor/finger off of the object
|
||||
- `LV_EVENT_SHORT_CLICKED` An object was pressed for a short period of time, then released. Not called if scrolled.
|
||||
- `LV_EVENT_LONG_PRESSED` An 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 did not scroll (regardless of long press)
|
||||
- `LV_EVENT_RELEASED` Called in every case when the object has been released
|
||||
- `LV_EVENT_SCROLL_BEGIN` Scrolling begins. The event parameter is `NULL` or an `lv_anim_t *` with the scroll animation descriptor to modify if required.
|
||||
- `LV_EVENT_CLICKED` Called on release if an object did not scroll (regardless of long press)
|
||||
- `LV_EVENT_RELEASED` Called in every case when an object has been released
|
||||
- `LV_EVENT_SCROLL_BEGIN` Scrolling begins. The event parameter is `NULL` or an `lv_anim_t *` with a scroll animation descriptor that can be modified if required.
|
||||
- `LV_EVENT_SCROLL_END` Scrolling ends.
|
||||
- `LV_EVENT_SCROLL` The object was scrolled
|
||||
- `LV_EVENT_SCROLL` An 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 unfocused
|
||||
- `LV_EVENT_LEAVE` The object is unfocused but still selected
|
||||
- `LV_EVENT_KEY` A key is sent to an object. Get the key with `lv_indev_get_key(lv_indev_get_act());`
|
||||
- `LV_EVENT_FOCUSED` An object is focused
|
||||
- `LV_EVENT_DEFOCUSED` An object is unfocused
|
||||
- `LV_EVENT_LEAVE` An object is unfocused 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_COVER_CHECK` Check if an 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 an object (e.g. for a shadow). The event parameter is `lv_coord_t *` to store the size. Only overwrite it 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
|
||||
@ -111,7 +111,7 @@ The following event codes exist:
|
||||
|
||||
### 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_INSERT` Text is being inserted into 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
|
||||
@ -120,7 +120,7 @@ The following event codes exist:
|
||||
### 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)`
|
||||
They can be sent to any object with `lv_event_send(obj, MY_EVENT_1, &some_data)`
|
||||
|
||||
## Sending events
|
||||
|
||||
@ -135,7 +135,7 @@ 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:
|
||||
`LV_EVENT_REFRESH` is a special event because it's designed to let the user 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)
|
||||
@ -143,17 +143,17 @@ lv_event_send(mbox, LV_EVENT_VALUE_CHANGED, &btn_id);
|
||||
|
||||
## 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 gotten from it:
|
||||
`lv_event_t` is the only parameter passed to the event callback and it contains all data about the event. The following values can be gotten 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_target(e)` get the object to which an event was sent
|
||||
- `lv_event_get_original_target(e)` get the object to which an event was 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.
|
||||
If `lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE)` is enabled all events will be sent to an object's parent too. If the parent also has `LV_OBJ_FLAG_EVENT_BUBBLE` enabled the event will be sent to its parent 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.
|
||||
|
||||
|
@ -5,17 +5,17 @@
|
||||
# File system
|
||||
|
||||
LVGL has a 'File system' abstraction module that enables you to attach any type of file system.
|
||||
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"`.
|
||||
A file system is identified by an assigned drive letter.
|
||||
For example, if an SD card is associated with the letter `'S'`, a file can be reached using `"S:path/to/file.txt"`.
|
||||
|
||||
## Ready to use drivers
|
||||
The [lv_fs_if](https://github.com/lvgl/lv_fs_if) repository contains ready to use drivers using POSIX, standard C and [FATFS](http://elm-chan.org/fsw/ff/00index_e.html) API.
|
||||
The [lv_fs_if](https://github.com/lvgl/lv_fs_if) repository contains prepared drivers using POSIX, standard C and the [FATFS](http://elm-chan.org/fsw/ff/00index_e.html) API.
|
||||
See its [README](https://github.com/lvgl/lv_fs_if#readme) for the details.
|
||||
|
||||
## Add a driver
|
||||
## Adding a driver
|
||||
|
||||
### Registering a driver
|
||||
To add a driver, `lv_fs_drv_t` needs to be initialized like below. `lv_fs_drv_t` needs to be static, global or dynamically allocated and not a local variable.
|
||||
To add a driver, a `lv_fs_drv_t` needs to be initialized like below. The `lv_fs_drv_t` needs to be static, global or dynamically allocated and not a local variable.
|
||||
```c
|
||||
static lv_fs_drv_t drv; /*Needs to be static or global*/
|
||||
lv_fs_drv_init(&drv); /*Basic initialization*/
|
||||
@ -50,9 +50,9 @@ The prototype of `open_cb` looks like this:
|
||||
void * (*open_cb)(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
|
||||
```
|
||||
|
||||
`path` is path after the driver letter (e.g. "S:path/to/file.txt" -> "path/to/file.txt"). `mode` can be `LV_FS_MODE_WR` or `LV_FS_MODE_RD` to open for write or read.
|
||||
`path` is the path after the drive letter (e.g. "S:path/to/file.txt" -> "path/to/file.txt"). `mode` can be `LV_FS_MODE_WR` or `LV_FS_MODE_RD` to open for writes or reads.
|
||||
|
||||
The return value is a pointer the *file object* the describes the opened file or `NULL` if there were any issues (e.g. the file wasn't found).
|
||||
The return value is a pointer to a *file object* that describes the opened file or `NULL` if there were any issues (e.g. the file wasn't found).
|
||||
The returned file object will be passed to other file system related callbacks. (see below)
|
||||
|
||||
### Other callbacks
|
||||
@ -61,9 +61,9 @@ The other callbacks are quite similar. For example `write_cb` looks like this:
|
||||
lv_fs_res_t (*write_cb)(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
|
||||
```
|
||||
|
||||
As `file_p` LVGL passes the return value of `open_cb`, `buf` is the data to write, `btw` is the Bytes To Write, `bw` is the actually written bytes.
|
||||
For `file_p`, LVGL passes the return value of `open_cb`, `buf` is the data to write, `btw` is the Bytes To Write, `bw` is the actually written bytes.
|
||||
|
||||
For a template to the callbacks see [lv_fs_template.c](https://github.com/lvgl/lvgl/blob/master/examples/porting/lv_port_fs_template.c).
|
||||
For a template of these callbacks see [lv_fs_template.c](https://github.com/lvgl/lvgl/blob/master/examples/porting/lv_port_fs_template.c).
|
||||
|
||||
|
||||
## Usage example
|
||||
@ -82,9 +82,9 @@ 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*
|
||||
*The mode in `lv_fs_open` can be `LV_FS_MODE_WR` to open for writes only 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.
|
||||
This example shows how to read a directory's content. It's up to the driver how to mark directories in the result but it can be a good practice to insert a `'/'` in front of each directory name.
|
||||
```c
|
||||
lv_fs_dir_t dir;
|
||||
lv_fs_res_t res;
|
||||
@ -110,9 +110,9 @@ while(1) {
|
||||
lv_fs_dir_close(&dir);
|
||||
```
|
||||
|
||||
## Use drivers for images
|
||||
## Use drives for images
|
||||
|
||||
[Image](/widgets/core/img) objects can be opened from files too (besides variables stored in the flash).
|
||||
[Image](/widgets/core/img) objects can be opened from files too (besides variables stored in the compiled program).
|
||||
|
||||
To use files in image widgets the following callbacks are required:
|
||||
- open
|
||||
|
@ -4,16 +4,16 @@
|
||||
```
|
||||
# Fonts
|
||||
|
||||
In LVGL fonts are collections of bitmaps and other information required to render the images of the letters (glyph).
|
||||
In LVGL fonts are collections of bitmaps and other information required to render images of individual letters (glyph).
|
||||
A font is stored in a `lv_font_t` variable and can be set in a 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).
|
||||
Fonts have a **bpp (bits per pixel)** property. It shows how many bits are used to describe a pixel in a 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 values mean better quality).
|
||||
|
||||
The *bpp* also affects the required memory size to store the font. For example, *bpp = 4* makes the font nearly 4 times larger compared to *bpp = 1*.
|
||||
The *bpp* property also affects the amount of memory needed to store a font. For example, *bpp = 4* makes a font nearly four times larger compared to *bpp = 1*.
|
||||
|
||||
## Unicode support
|
||||
|
||||
@ -30,7 +30,7 @@ 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.
|
||||
There are several built-in fonts in different sizes, which can be enabled in `lv_conf.h` with *LV_FONT_...* defines.
|
||||
### Normal fonts
|
||||
Containing all the ASCII characters, the degree symbol (U+00B0), the bullet symbol (U+2022) and the built-in symbols (see below).
|
||||
- `LV_FONT_MONTSERRAT_12` 12 px font
|
||||
@ -55,9 +55,9 @@ Containing all the ASCII characters, the degree symbol (U+00B0), the bullet symb
|
||||
|
||||
### 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_MONTSERRAT_28_COMPRESSED` Same as normal 28 px font but stored as a [compressed font](#compress-fonts) with 3 bpp
|
||||
- `LV_FONT_DEJAVU_16_PERSIAN_HEBREW` 16 px font with normal range + Hebrew, Arabic, Persian letters and all their forms
|
||||
- `LV_FONT_SIMSUN_16_CJK`16 px font with normal range + 1000 most common CJK radicals
|
||||
- `LV_FONT_SIMSUN_16_CJK`16 px font with normal range plus 1000 of the 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
|
||||
|
||||
@ -70,12 +70,12 @@ In addition to the ASCII range, the following symbols are also added to the buil
|
||||
|
||||
![](/misc/symbols.png "Built-in Symbols in LVGL")
|
||||
|
||||
The symbols can be used as:
|
||||
The symbols can be used singly as:
|
||||
```c
|
||||
lv_label_set_text(my_label, LV_SYMBOL_OK);
|
||||
```
|
||||
|
||||
Or with together with strings:
|
||||
Or with together with strings (compile time string concatenation):
|
||||
```c
|
||||
lv_label_set_text(my_label, LV_SYMBOL_OK "Apply");
|
||||
```
|
||||
@ -88,7 +88,7 @@ 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.
|
||||
Most languages use a Left-to-Right (LTR for short) writing direction, however some languages (such as Hebrew, Persian or Arabic) use 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:
|
||||
|
||||
@ -97,94 +97,94 @@ LVGL not only supports RTL texts but supports mixed (a.k.a. bidirectional, BiDi)
|
||||
BiDi support is 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.
|
||||
However, in LVGL, the base direction is not only applied to labels. It's a general property which can be set for every object.
|
||||
If not set then it will be inherited from the parent.
|
||||
This means it's enough to set the base direction of a 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.
|
||||
The default base direction for screens 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:
|
||||
To set an object's base direction use `lv_obj_set_base_dir(obj, base_dir)`. The possible base directions 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)
|
||||
- `LV_BIDI_DIR_INHERIT`: Inherit base direction from the parent (or a default value 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
|
||||
- `lv_tabview`: Displays tabs from right to left
|
||||
- `lv_checkbox`: Shows the box on the right
|
||||
- `lv_btnmatrix`: Shows buttons from right to left
|
||||
- `lv_list`: Shows icons on the right
|
||||
- `lv_dropdown`: Aligns 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.
|
||||
There are some special rules to display Arabic and Persian characters: the *form* of a character depends on its position in the text.
|
||||
A different form of the same letter needs to be used if is isolated, at start, middle or end positions. Besides these, some conjunction rules should also be taken into account.
|
||||
|
||||
LVGL supports to apply these rules if `LV_USE_ARABIC_PERSIAN_CHARS` is enabled.
|
||||
LVGL supports 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) don't support this feature.
|
||||
- Only displaying text is supported (e.g. on labels), text inputs (e.g. text area) don't support this feature.
|
||||
- Static text (i.e. const) is not processed. E.g. texts set by `lv_label_set_text()` will be "Arabic processed" but `lv_lable_set_text_static()` won't.
|
||||
- Text get functions (e.g. `lv_label_get_text()`) will return the processed text.
|
||||
- Text get functions (e.g. `lv_label_get_text()`) will return the processed text.
|
||||
|
||||
### Subpixel rendering
|
||||
|
||||
Subpixel rendering allows for tripling the horizontal resolution by rendering on Red, Green and Blue channel instead of pixel level. This takes advantage of the position of physical color channels of each pixel, resulting in higher quality letter anti-aliasing. Learn more [here](https://en.wikipedia.org/wiki/Subpixel_rendering).
|
||||
Subpixel rendering allows for tripling the horizontal resolution by rendering anti-aliased edges on Red, Green and Blue channels instead of at pixel level granularity. This takes advantage of the position of physical color channels of each pixel, resulting in higher quality letter anti-aliasing. Learn more [here](https://en.wikipedia.org/wiki/Subpixel_rendering).
|
||||
|
||||
For subpixel rendering the fonts need to be generated with special settings:
|
||||
For subpixel rendering, the fonts need to be generated 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.
|
||||
- In the command line tool use `--lcd` flag. Note that the generated font needs about three 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, LVGL assumes `RGB` order, however this can be swapped by setting `LV_SUBPX_BGR 1` in *lv_conf.h*.
|
||||
|
||||
### Compress fonts
|
||||
The bitmaps of the fonts can be compressed by
|
||||
### Compressed fonts
|
||||
The bitmaps of fonts can be compressed by
|
||||
- ticking the `Compressed` check box in the online converter
|
||||
- not passing `--no-compress` flag to the offline converter (compression is applied by default)
|
||||
- not passing the `--no-compress` flag to the offline converter (compression is applied 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
|
||||
Compression is more effective with larger fonts and higher bpp. However, it's about 30% slower to render compressed fonts.
|
||||
Therefore it's recommended to compress only the largest fonts of a 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 the performance cost is smaller.
|
||||
|
||||
## Add new font
|
||||
## Add a 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.
|
||||
3. If you want to create something like the built-in fonts (Montserrat font and symbols) but in a different size and/or ranges, you can use the `built_in_font_gen.py` script in `lvgl/scripts/built_in_font` folder.
|
||||
(This requires Python and `lv_font_conv` to be installed)
|
||||
|
||||
To declare the font in a file, use `LV_FONT_DECLARE(my_font_name)`.
|
||||
To declare a 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*.
|
||||
To make 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 the [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.
|
||||
1. Search for a symbol on [https://fontawesome.com](https://fontawesome.com). For example the [USB symbol](https://fontawesome.com/icons/usb?style=brands). Copy its Unicode ID which is `0xf287` in this case.
|
||||
2. Open the [Online font converter](https://lvgl.io/tools/fontconverter). 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);`.
|
||||
5. Convert the font and copy the generated source code 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 use `LV_FONT_DECLARE(my_font_name);`.
|
||||
|
||||
**Using the symbol**
|
||||
1. Convert the Unicode value to UTF8, for example 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"`
|
||||
2. Create a `define` string 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 at 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.
|
||||
## Load a font at run-time
|
||||
`lv_font_load` can be used to load a font from a file. The font needs to have a special binary format. (Not TTF or WOFF).
|
||||
Use [lv_font_conv](https://github.com/lvgl/lv_font_conv/) with the `--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.
|
||||
Note that to load a font [LVGL's filesystem](/overview/file-system) needs to be enabled and a driver must be added.
|
||||
|
||||
Example
|
||||
```c
|
||||
@ -200,13 +200,12 @@ lv_font_free(my_font);
|
||||
|
||||
## Add a new font engine
|
||||
|
||||
LVGL's font interface is designed to be very flexible.
|
||||
But even so you don't need to use LVGL's internal font engine: 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.
|
||||
LVGL's font interface is designed to be very flexible but, even so, you can add your own font engine in place of LVGL's internal one.
|
||||
For example, you can 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:
|
||||
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;
|
||||
|
@ -4,15 +4,15 @@
|
||||
```
|
||||
# Images
|
||||
|
||||
An image can be a file or variable which stores the bitmap itself and some metadata.
|
||||
An image can be a file or a 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 variable in internal memory (RAM or ROM)
|
||||
- as a file
|
||||
|
||||
### Variables
|
||||
The images stored internally in a variable are composed mainly of an `lv_img_dsc_t` structure with the following fields:
|
||||
Images stored internally in a variable are 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)
|
||||
@ -25,22 +25,22 @@ The images stored internally in a variable are composed mainly of an `lv_img_dsc
|
||||
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.
|
||||
To deal with files you need to add a storage *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 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.
|
||||
Images stored as files are not linked into the resulting executable, and must be read into RAM before being drawn. As a result, they are not as resource-friendly as images linked at compile time. However, they are easier to replace without needing to rebuild 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_TRUE_COLOR_CHROMA_KEYED** Like `LV_IMG_CF_TRUE_COLOR` but if a pixel has the `LV_COLOR_TRANSP` color (set in *lv_conf.h*) it 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).
|
||||
- **LV_IMG_CF_ALPHA_1/2/4/8BIT** **Only stores the Alpha value with 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 that can be altered.
|
||||
|
||||
The bytes of the `LV_IMG_CF_TRUE_COLOR` images are stored in the following order.
|
||||
The bytes of `LV_IMG_CF_TRUE_COLOR` images are stored in the following order.
|
||||
|
||||
For 32-bit color depth:
|
||||
- Byte 0: Blue
|
||||
@ -60,8 +60,8 @@ For 8-bit color depth:
|
||||
|
||||
You can store images in a *Raw* format to indicate that it's not encoded with one of the built-in color formats 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 chroma-keyed as described in `LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED` above.
|
||||
- **LV_IMG_CF_RAW_ALPHA** Indicates that an image has alpha and an alpha byte is added for every pixel.
|
||||
- **LV_IMG_CF_RAW_CHROMA_KEYED** Indicates that an image is chroma-keyed as described in `LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED` above.
|
||||
|
||||
|
||||
## Add and use images
|
||||
@ -73,7 +73,7 @@ You can add images to LVGL in two ways:
|
||||
### Online converter
|
||||
The online Image converter is available here: https://lvgl.io/tools/imageconverter
|
||||
|
||||
Adding an image to LVGL via online converter is easy.
|
||||
Adding an image to LVGL via the 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.
|
||||
@ -81,9 +81,9 @@ Adding an image to LVGL via online converter is easy.
|
||||
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 the generated C arrays (variables), 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:
|
||||
In the 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)
|
||||
@ -132,11 +132,11 @@ As you can see in the [Color formats](#color-formats) section, LVGL supports sev
|
||||
|
||||
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:
|
||||
An 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.
|
||||
- **open** open an image: either store a decoded image or set it to `NULL` to indicate the image can be read line-by-line.
|
||||
- **read** if *open* didn't fully open an image this function should give some decoded data (max 1 line) from a given position.
|
||||
- **close** close an 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 decoders until it finds one which can open the image, i.e. one which knows that format.
|
||||
|
||||
@ -144,15 +144,15 @@ The `LV_IMG_CF_TRUE_COLOR_...`, `LV_IMG_INDEXED_...` and `LV_IMG_ALPHA_...` form
|
||||
|
||||
### 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 chroma-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.
|
||||
The easiest way to create a custom image is to use the online image converter and select `Raw`, `Raw with alpha` or `Raw with chroma-keyed` format. It will just take every byte of the binary file you uploaded and write it as an 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.
|
||||
`header.cf` will be `LV_IMG_CF_RAW`, `LV_IMG_CF_RAW_ALPHA` or `LV_IMG_CF_RAW_CHROMA_KEYED` accordingly. You should choose the correct format according to your needs: a fully opaque image, using an alpha channel or using a chroma key.
|
||||
|
||||
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.
|
||||
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 the [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).
|
||||
The `LV_IMG_CF_USER_ENCODED_...` formats are not known by the library and 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*.
|
||||
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 images only in *True color* format (or *Raw* but ultimately it will be in *True color* format).
|
||||
The `LV_IMG_CF_USER_ENCODED_...` formats are not known by the library and therefore they should be decoded to one of the known formats from the [Color formats](#color-formats) section.
|
||||
It's possible to decode an 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.
|
||||
|
||||
@ -256,8 +256,8 @@ So in summary:
|
||||
- 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 the entire 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.
|
||||
If the format is known, but you don't want to decode the entire image (e.g. no memory for it), set `dsc->img_data = NULL` and use `read_line` to get the pixel data.
|
||||
- In `decoder_close` you should free all allocated resources.
|
||||
- `decoder_read` is optional. Decoding the whole image requires extra memory and some computational overhead.
|
||||
However, it 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.
|
||||
@ -265,7 +265,7 @@ To indicate that the *line read* function should be used, set `dsc->img_data = N
|
||||
|
||||
### 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()`.
|
||||
LVGL will use registered image decoders automatically if you try and draw a raw image (i.e. using the `lv_img` object) but you can use them manually too. Create an `lv_img_decoder_dsc_t` variable to describe the decoding session and call `lv_img_decoder_open()`.
|
||||
|
||||
```c
|
||||
|
||||
@ -287,32 +287,32 @@ Continuously decoding a PNG image or loading images from a slow external memory
|
||||
|
||||
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.
|
||||
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. Image caching may not be worth it if you have a deeply embedded target which decodes small images from a relatively fast storage medium.
|
||||
|
||||
### 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 number of cache entries can be defined with `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 the images. Instead, the library will close one of the cached images (to free space).
|
||||
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.)
|
||||
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 control it.)
|
||||
|
||||
Every cache entry has a *"life"* value. Every time an image opening happens through the cache, the *life* value of all entries is decreased to make them older.
|
||||
Every cache entry has a *"life"* value. Every time an image is opened through the cache, the *life* value of all entries is decreased to make them older.
|
||||
When a cached image is used, its *life* value is increased by the *time to open* value to make it more alive.
|
||||
|
||||
If there is no more space in the cache, the entry with the smallest life value will be closed.
|
||||
If there is no more space in the cache, the entry with the lowest life value 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 open.
|
||||
Note that a cached image might continuously consume memory. For example, if three PNG images are cached, they will consume memory while they are open.
|
||||
|
||||
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.
|
||||
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 from cache.
|
||||
|
||||
To do this, use `lv_img_cache_invalidate_src(&my_png)`. If `NULL` is passed as a parameter, the whole cache will be cleaned.
|
||||
|
||||
|
@ -34,16 +34,16 @@ 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.
|
||||
You can fully control the user interface without a touchpad or mouse by using a keypad or encoder(s). It works similar to the *TAB* key on the PC to select an element in an application or a web page.
|
||||
|
||||
### Groups
|
||||
|
||||
The objects, you want to control with keypad or encoder, need 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.
|
||||
Objects you want to control with a keypad or encoder need 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.
|
||||
You need to associate an input device with a group. An input device can send key events to only one group but a group can receive data from more than one input device.
|
||||
|
||||
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)`.
|
||||
|
||||
@ -65,34 +65,34 @@ There are some predefined keys which have special meaning:
|
||||
- **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.
|
||||
In your `read_cb` function, you should translate some of your keys to these special keys to support navigation in a group and interact with selected objects.
|
||||
|
||||
Usually, it's enough to use only `LV_KEY_LEFT/RIGHT` because most of the objects can be fully controlled with them.
|
||||
Usually, it's enough to use only `LV_KEY_LEFT/RIGHT` because most objects can be fully controlled with them.
|
||||
|
||||
With an encoder, you should use only `LV_KEY_LEFT`, `LV_KEY_RIGHT`, and `LV_KEY_ENTER`.
|
||||
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" and hence it is difficult to navigate using the default options. *Navigate* and *Edit* are created to avoid this problem with the encoders.
|
||||
Since a keypad has plenty of keys, it's easy to navigate between objects and edit them using the keypad. But encoders have a limited number of "keys" and hence it is difficult to navigate using the default options. *Navigate* and *Edit* modes are used to avoid this problem with 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.
|
||||
In *Navigate* mode, an encoder's `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.
|
||||
In *Edit* mode, `LV_KEY_NEXT/PREV` is usually used to modify an 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.
|
||||
Usually, an object which cannot be pressed (like a [Slider](/widgets/core/slider)) leaves *Edit* mode upon a short click. But with objects where a short click has meaning (e.g. [Button](/widgets/core/btn)), a long press is required.
|
||||
|
||||
#### Default group
|
||||
Interactive widgets - such as buttons, checkboxes, sliders, etc. - can be automatically added to a default group.
|
||||
Just create a group with `lv_group_t * g = lv_group_create();` and set the default group with `lv_group_set_default(g);`
|
||||
|
||||
Don't forget to assign the input device(s) to the default group with ` lv_indev_set_group(my_indev, g);`.
|
||||
Don't forget to assign one or more input devices to the default group with ` lv_indev_set_group(my_indev, g);`.
|
||||
|
||||
### 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 an object is focused either by clicking it via touchpad or focused via an encoder or keypad it goes to the `LV_STATE_FOCUSED` state. Hence, focused styles will be applied to 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.
|
||||
If an object switches to edit mode it enters the `LV_STATE_FOCUSED | LV_STATE_EDITED` states so these style properties will be shown.
|
||||
|
||||
For a more detailed description read the [Style](https://docs.lvgl.io/v7/en/html/overview/style.html) section.
|
||||
|
||||
|
@ -9,10 +9,10 @@
|
||||
|
||||
By default, LVGL draws new objects on top of old objects.
|
||||
|
||||
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.
|
||||
For example, assume we add a button to a parent object named button1 and then another button named button2. Then button1 (along with its child object(s)) will be in the background and can be covered by button2 and its children.
|
||||
|
||||
|
||||
![](/misc/layers.png "Creating graphical objects in Littlev Graphics Library")
|
||||
![](/misc/layers.png "Creating graphical objects in LVGL")
|
||||
|
||||
```c
|
||||
/*Create a screen*/
|
||||
@ -21,7 +21,7 @@ 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_btn_set_fit(btn1, true, true); /*Enable automatically setting the size according to 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*/
|
||||
@ -40,20 +40,21 @@ lv_obj_del(label2);
|
||||
|
||||
## Bring to the foreground
|
||||
|
||||
There are 4 explicit way to bring an object to the foreground:
|
||||
- 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.
|
||||
- Use `lv_obj_move_to_index(obj, index)` to set the index of the object in its parent.
|
||||
- Use `lv_obj_swap(obj1, obj2)` to swap the relative position of two objects.
|
||||
- When `lv_obj_set_parent(obj, new_parent)` is used, `obj` will be on the foreground on the `new_parent`.
|
||||
There are four explicit ways to bring an object to the foreground:
|
||||
- Use `lv_obj_move_foreground(obj)` to bring an object to the foreground. Similarly, use `lv_obj_move_background(obj)` to move it to the background.
|
||||
- Use `lv_obj_move_up(obj)` to move an object one position up in the hierarchy, Similarly, use `lv_obj_move_down(obj)` to move an object one position down in the hierarchy.
|
||||
- Use `lv_obj_swap(obj1, obj2)` to swap the relative layer position of two objects.
|
||||
- When `lv_obj_set_parent(obj, new_parent)` is used, `obj` will be on the foreground of the `new_parent`.
|
||||
|
||||
|
||||
## Top and sys layers
|
||||
|
||||
LVGL uses two special layers named as `layer_top` and `layer_sys`.
|
||||
LVGL uses two special layers named `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.
|
||||
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 clicks and acts as a modal.
|
||||
```c
|
||||
lv_obj_add_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE);
|
||||
```
|
||||
|
||||
The `layer_sys` is also used for similar purposes on LVGL. For example, it places the mouse cursor above all layers to be sure it's always visible.
|
||||
The `layer_sys` is also used for similar purposes in LVGL. For example, it places the mouse cursor above all layers to be sure it's always visible.
|
||||
|
@ -54,11 +54,11 @@ The API of the widgets is described in their [Documentation](/widgets/index) but
|
||||
### 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.
|
||||
There is no limitation for the type of the parent but there are objects which are typically a parent (e.g. button) or a child (e.g. label).
|
||||
|
||||
### Moving together
|
||||
|
||||
If the position of the parent changes the children will move with the parent.
|
||||
If the position of a parent changes, the children will move along with it.
|
||||
Therefore, all positions are relative to the parent.
|
||||
|
||||
![](/misc/par_child1.png "Objects are moving together 1")
|
||||
@ -83,7 +83,7 @@ lv_obj_set_pos(parent, 50, 50); /*Move the parent. The child will move with it.*
|
||||
|
||||
### Visibility only on the parent
|
||||
|
||||
If a child is partially or fully out of its parent then the parts outside will not be visible.
|
||||
If a child is partially or fully outside of its parent then the parts outside will not be visible.
|
||||
|
||||
![](/misc/par_child3.png "A graphical object is visible on its parent")
|
||||
|
||||
@ -93,7 +93,7 @@ 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.
|
||||
In LVGL, objects can be created and deleted dynamically at run time. It means only the currently created (existing) objects consume RAM.
|
||||
|
||||
This allows for the creation of a screen just when a button is clicked to open it, and for deletion of screens when a new screen is loaded.
|
||||
|
||||
@ -101,7 +101,7 @@ UIs can be created based on the current environment of the device. For example o
|
||||
|
||||
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>);
|
||||
lv_obj_t * lv_<widget>_create(lv_obj_t * parent, <other parameters if any>);
|
||||
```
|
||||
|
||||
Typically, the create functions only have a *parent* parameter telling them on which object to create the new widget.
|
||||
@ -116,7 +116,7 @@ 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 perform the deletion on the next call of `lv_timer_handler()`.
|
||||
If for any reason you can't delete the object immediately you can use `lv_obj_del_async(obj)` which will perform the deletion on the next call of `lv_timer_handler()`.
|
||||
This is useful e.g. if you want to delete the parent of an object in the child's `LV_EVENT_DELETE` handler.
|
||||
|
||||
You can remove all the children of an object (but not the object itself) using `lv_obj_clean(obj)`.
|
||||
@ -148,8 +148,8 @@ 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()`).
|
||||
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*.
|
||||
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 there with `lv_indev_set_cursor()`).
|
||||
|
||||
The `lv_layer_top()` and `lv_layer_sys()` functions return pointers to the top and system layers respectively.
|
||||
|
||||
@ -158,11 +158,11 @@ 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
|
||||
A new screen can be loaded with animation by 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.
|
||||
|
||||
@ -170,7 +170,7 @@ The new screen will become active (returned by `lv_scr_act()`) when the animatio
|
||||
|
||||
### 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)`.
|
||||
The *default display* is the last registered display with `lv_disp_drv_register`. You can also 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.
|
||||
|
||||
@ -178,22 +178,22 @@ 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 scrollbar parts but a [Slider](/widgets/core/slider) uses the main, the indicator and the knob parts.
|
||||
The widgets are built from multiple parts. For example a [Base object](/widgets/obj) uses the main and scrollbar parts but a [Slider](/widgets/core/slider) uses the main, indicator and 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_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_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. table cells)*/
|
||||
- `LV_PART_ITEMS` Used if the widget has multiple similar elements (e.g. table 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.
|
||||
The main purpose of parts is to allow styling the "components" of the widgets.
|
||||
They are described in more detail in the [Style overview](/overview/style) section.
|
||||
|
||||
## States
|
||||
The object can be in a combination of the following states:
|
||||
@ -211,7 +211,7 @@ The object can be in a combination of the following states:
|
||||
- `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.
|
||||
The states are usually automatically changed by the library as the userinteracts qith an object (presses, releases, focuses, etc.).
|
||||
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 OR-ed state values can be used as well. E.g. `lv_obj_add_state(obj, part, LV_STATE_PRESSED | LV_PRESSED_CHECKED)`.
|
||||
@ -219,4 +219,4 @@ In both cases OR-ed state values can be used as well. E.g. `lv_obj_add_state(obj
|
||||
To learn more about the states read the related section of the [Style overview](/overview/style).
|
||||
|
||||
## Snapshot
|
||||
A snapshot image could be generated for an object together with its children. Check details in [Snapshot](/others/snapshot).
|
||||
A snapshot image can be generated for an object together with its children. Check details in [Snapshot](/others/snapshot).
|
||||
|
@ -5,22 +5,22 @@
|
||||
# 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.
|
||||
In LVGL scrolling works very intuitively: if an object is outside of its parent content area (the size without padding), 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 object can either be scrolled either horizontally or vertically in one stroke; diagonal scrolling is not possible.
|
||||
The object can either be scrolled horizontally or vertically in one stroke; diagonal scrolling is not possible.
|
||||
|
||||
### Scrollbar
|
||||
|
||||
#### Mode
|
||||
The scrollbars are displayed according to the set `mode`. The following `mode`s exist:
|
||||
Scrollbars are displayed according to a configured `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_ACTIVE` Show scroll bars while a 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.
|
||||
`lv_obj_set_scrollbar_mode(obj, LV_SCROLLBAR_MODE_...)` sets the scrollbar mode on an object.
|
||||
|
||||
|
||||
#### Styling
|
||||
@ -35,12 +35,12 @@ 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.
|
||||
An object goes to the `LV_STATE_SCROLLED` state while it's being scrolled. This allows adding different styles 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_style_set_bg_color(&style_blue, lv_color_blue());
|
||||
|
||||
...
|
||||
|
||||
@ -49,7 +49,7 @@ lv_obj_add_style(obj, &style_blue, LV_STATE_SCROLLED | LV_PART_SCROLLBAR);
|
||||
|
||||
If the base direction of the `LV_PART_SCROLLBAR` is RTL (`LV_BASE_DIR_RTL`) the vertical scrollbar will be placed on the left.
|
||||
Note that, the `base_dir` style property is inherited. Therefore, it can be set directly on the `LV_PART_SCROLLBAR` part of an object
|
||||
or on the obejct's or any parent's main part to make scrollbar inherit the base direction.
|
||||
or on the object's or any parent's main part to make a scrollbar inherit the base direction.
|
||||
|
||||
### Events
|
||||
The following events are related to scrolling:
|
||||
@ -63,16 +63,16 @@ TODO
|
||||
|
||||
## Features of scrolling
|
||||
|
||||
Besides, managing "normal" scrolling there are many interesting and useful additional features too.
|
||||
Besides, managing "normal" scrolling there are many interesting and useful additional features.
|
||||
|
||||
|
||||
### 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.
|
||||
Non-scrollable objects can still propagate the scrolling (chain) to their parents.
|
||||
|
||||
The direction in which scrolling can happen can be controlled by `lv_obj_set_scroll_dir(obj, LV_DIR_...)`.
|
||||
The direction in which scrolling happens 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
|
||||
@ -86,33 +86,33 @@ 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. its content has reached the bottom most position) the scrolling is propagated to its parent. If the parent can be scrolled in that direction than it will be scrolled instead.
|
||||
It propagates to the grandparent and grand-grandparents too.
|
||||
If an object can't be scrolled further (e.g. its content has reached the bottom-most position) additional scrolling is propagated to its parent. If the parent can be scrolled in that direction than it will be scrolled instead.
|
||||
It continues propagating to the grandparent and grand-grandparents as well.
|
||||
|
||||
The propagation on scrolling is 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 the object was thrown and scrolling slows down smoothly.
|
||||
When the user scrolls an object and releases it, LVGL can emulate inertial momentum for the scrolling. It's like the object was thrown and 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.
|
||||
Normally an object can't be scrolled past the extremeties of its content. 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.
|
||||
However, with `LV_OBJ_FLAG_SCROLL_ELASTIC` a fancy effect is 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 released the content scrolled in it will be animated back to the valid position.
|
||||
|
||||
### Snapping
|
||||
The children of an object can be snapped according to specific rules when scrolling ends. Children can be made snappable individually with the `LV_OBJ_FLAG_SNAPPABLE` flag.
|
||||
|
||||
The object can align the snapped children in 4 ways:
|
||||
An object can align snapped children in four 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
|
||||
- `LV_SCROLL_SNAP_START` Align the children to the left/top side of a scrolled object
|
||||
- `LV_SCROLL_SNAP_END` Align the children to the right/bottom side of a scrolled object
|
||||
- `LV_SCROLL_SNAP_CENTER` Align the children to the center of a scrolled object
|
||||
|
||||
The alignment can be set with `lv_obj_set_scroll_snap_x/y(obj, LV_SCROLL_SNAP_...)`:
|
||||
Snap alignment is set with `lv_obj_set_scroll_snap_x/y(obj, LV_SCROLL_SNAP_...)`:
|
||||
|
||||
Under the hood the following happens:
|
||||
1. User scrolls an object and releases the screen
|
||||
@ -122,34 +122,34 @@ Under the hood the following happens:
|
||||
|
||||
### Scroll one
|
||||
The "scroll one" feature tells LVGL to allow scrolling only one snappable child at a time.
|
||||
So this requires to make the children snappable and set a scroll snap alignment different from `LV_SCROLL_SNAP_NONE`.
|
||||
This requires making the children snappable and setting 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.
|
||||
Imagine that there a lot of objects in a group that are on a scrollable object. Pressing the "Tab" button focuses the next object but it might be outside the visible area of the scrollable object.
|
||||
If the "scroll on focus" feature is enabled LVGL will automatically scroll objects to bring their children into view.
|
||||
The scrolling happens recursively therefore even nested scrollable objects are handled properly.
|
||||
The object will be scrolled into view even if it's on a different page of a tabview.
|
||||
|
||||
## Scroll manually
|
||||
The following API functions allow to manually scroll objects:
|
||||
The following API functions allow manual scrolling of 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
|
||||
- `lv_obj_scroll_to_y(obj, y, LV_ANIM_ON/OFF)` scroll to bring the given coordinate to the top 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.
|
||||
In short, self size establishes the size of an object's 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.
|
||||
This means not only the children can make an object scrollable but a larger self size will 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
|
||||
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);
|
||||
|
@ -1,11 +1,11 @@
|
||||
# Style properties
|
||||
|
||||
## Size and position
|
||||
Properties related to size, position, alignment and layout of the objects.
|
||||
Properties related to size, position, alignment and layout of objects.
|
||||
|
||||
|
||||
### 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.
|
||||
Sets the width of an 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> widget dependent</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -38,7 +38,7 @@ Sets a maximal width. Pixel and percentage values can be used. Percentage values
|
||||
|
||||
|
||||
### 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.
|
||||
Sets the height of an 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> widget dependent</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -71,7 +71,7 @@ Sets a maximal height. Pixel and percentage values can be used. Percentage value
|
||||
|
||||
|
||||
### 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.
|
||||
Set the X coordinate of an object considering the current `align` mode. 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>
|
||||
@ -82,7 +82,7 @@ Set the X coordinate of the object considering the set `align`. Pixel and percen
|
||||
|
||||
|
||||
### 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.
|
||||
Set the Y coordinate of an object considering the current `align` mode. 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>
|
||||
@ -104,7 +104,7 @@ Set the alignment which tells from which point of the parent the X and Y coordin
|
||||
|
||||
|
||||
### 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.
|
||||
Make an 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>
|
||||
@ -115,7 +115,7 @@ Make the object wider on both sides with this value. Pixel and percentage (with
|
||||
|
||||
|
||||
### 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.
|
||||
Make an 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>
|
||||
@ -126,7 +126,7 @@ Make the object higher on both sides with this value. Pixel and percentage (with
|
||||
|
||||
|
||||
### 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.
|
||||
Move an 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>
|
||||
@ -137,7 +137,7 @@ Move the object with this value in X direction. Applied after layouts, aligns an
|
||||
|
||||
|
||||
### 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.
|
||||
Move an 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>
|
||||
@ -148,7 +148,7 @@ Move the object with this value in Y direction. Applied after layouts, aligns an
|
||||
|
||||
|
||||
### transform_zoom
|
||||
Zoom image-like objects. Multiplied with the zoom set on the object. The value 256 (or `LV_IMG_ZOOM_NONE`) means normal size, 128 half size, 512 double size, and so on
|
||||
Zoom 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 (Q8.8 or Q24.8 fixed-point format)
|
||||
<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>
|
||||
@ -169,7 +169,7 @@ Zoom image-like objects. Multiplied with the zoom set on the object. The value 2
|
||||
|
||||
|
||||
## Padding
|
||||
Properties to describe spacing between the parent's sides and the children and among the children. Very similar to the padding properties in HTML.
|
||||
Properties to describe spacing between a parent's sides and among its children. Very similar to the padding properties in HTML.
|
||||
|
||||
|
||||
### pad_top
|
||||
@ -217,7 +217,7 @@ Sets the padding on the right. It makes the content area smaller in this directi
|
||||
|
||||
|
||||
### pad_row
|
||||
Sets the padding between the rows. Used by the layouts.
|
||||
Sets the padding between the rows. Used by 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>
|
||||
@ -228,7 +228,7 @@ Sets the padding between the rows. Used by the layouts.
|
||||
|
||||
|
||||
### pad_column
|
||||
Sets the padding between the columns. Used by the layouts.
|
||||
Sets the padding between the columns. Used by 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>
|
||||
@ -242,7 +242,7 @@ Mixed properties for various purposes.
|
||||
|
||||
|
||||
### radius
|
||||
Set the radius on every corner. The value is interpreted in pixel (>= 0) or `LV_RADIUS_CIRCLE` for max. radius
|
||||
Set a radius on every corner. The value is interpreted in pixels (>= 0) or use `LV_RADIUS_CIRCLE` for the max. possible radius for an object's size
|
||||
<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>
|
||||
@ -253,7 +253,7 @@ Set the radius on every corner. The value is interpreted in pixel (>= 0) or `LV_
|
||||
|
||||
|
||||
### clip_corner
|
||||
Enable to clip the overflowed content on the rounded corner. Can be `true` or `false`.
|
||||
Enable to clip any overflowed content on a 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>
|
||||
@ -264,7 +264,7 @@ Enable to clip the overflowed content on the rounded corner. Can be `true` or `f
|
||||
|
||||
|
||||
### 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.
|
||||
Scale down all opacity values of an 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 (opaque), other numeric values or the constants LV_OPA_10, LV_OPA_20, etc. mean semi-transparency.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_OPA_COVER`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> Yes</li>
|
||||
@ -275,7 +275,7 @@ Scale down all opacity values of the object by this factor. Value 0, `LV_OPA_0`
|
||||
|
||||
|
||||
### color_filter_dsc
|
||||
Mix a color to all colors of the object.
|
||||
Mix a color with all colors of an object.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `NULL`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -286,7 +286,7 @@ Mix a color to all colors of the object.
|
||||
|
||||
|
||||
### color_filter_opa
|
||||
The intensity of mixing of color filter.
|
||||
The intensity of mixing for the color filter.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_OPA_TRANSP`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -297,7 +297,7 @@ The intensity of mixing of color filter.
|
||||
|
||||
|
||||
### anim_time
|
||||
The animation time in milliseconds. Its 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.
|
||||
The animation time in milliseconds. Its meaning is widget specific. E.g. blink time of the cursor on a 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>
|
||||
@ -308,7 +308,7 @@ The animation time in milliseconds. Its meaning is widget specific. E.g. blink t
|
||||
|
||||
|
||||
### anim_speed
|
||||
The animation speed in pixel/sec. Its meaning is widget specific. E.g. scroll speed of label. See the widgets' documentation to learn more.
|
||||
The animation speed in pixels/sec. Its 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>
|
||||
@ -319,7 +319,7 @@ The animation speed in pixel/sec. Its meaning is widget specific. E.g. scroll sp
|
||||
|
||||
|
||||
### transition
|
||||
An initialized `lv_style_transition_dsc_t` to describe a transition.
|
||||
An initialized `lv_style_transition_dsc_t` that describes a transition.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `NULL`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -330,7 +330,7 @@ An initialized `lv_style_transition_dsc_t` to describe a transition.
|
||||
|
||||
|
||||
### blend_mode
|
||||
Describes how to blend the colors to the background. The possible values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`
|
||||
Describes how to blend object colors with the background. The possible values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_BLEND_MODE_NORMAL`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -341,7 +341,7 @@ Describes how to blend the colors to the background. The possible values are `LV
|
||||
|
||||
|
||||
### 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.
|
||||
Set the layout of an object. Its children will be repositioned and resized according to the policies set for the layout. For the possible values see the documentation of 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>
|
||||
@ -352,7 +352,7 @@ Set the layout if the object. The children will be repositioned and resized acco
|
||||
|
||||
|
||||
### base_dir
|
||||
Set the base direction of the object. The possible values are `LV_BIDI_DIR_LTR/RTL/AUTO`.
|
||||
Set the base direction of an object. The possible values are `LV_BIDI_DIR_LTR/RTL/AUTO`.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_BASE_DIR_AUTO`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> Yes</li>
|
||||
@ -362,11 +362,11 @@ Set the base direction of the object. The possible values are `LV_BIDI_DIR_LTR/R
|
||||
|
||||
|
||||
## Background
|
||||
Properties for to describe the background color and image of the objects.
|
||||
Properties to describe the background color and image of objects.
|
||||
|
||||
|
||||
### bg_color
|
||||
Set the background color of the object.
|
||||
Set the background color of an object.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `0xffffff`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -377,7 +377,7 @@ Set the background color of the object.
|
||||
|
||||
|
||||
### 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.
|
||||
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 (opaque), other numeric values or the constants LV_OPA_10, LV_OPA_20, etc. mean semi-transparency.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_OPA_TRANSP`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -399,7 +399,7 @@ Set the gradient color of the background. Used only if `grad_dir` is not `LV_GRA
|
||||
|
||||
|
||||
### bg_grad_dir
|
||||
Set the direction of the gradient of the background. The possible values are `LV_GRAD_DIR_NONE/HOR/VER`.
|
||||
Set the gradient direction for 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> `LV_GRAD_DIR_NONE`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -410,7 +410,7 @@ Set the direction of the gradient of the background. The possible values are `LV
|
||||
|
||||
|
||||
### 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
|
||||
Set the point from which the background color should start for gradients. 0 indicates the 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>
|
||||
@ -421,7 +421,7 @@ Set the point from which the background color should start for gradients. 0 mean
|
||||
|
||||
|
||||
### 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
|
||||
Set the point from which the background's gradient color should start. 0 indicates the 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> 255</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -443,7 +443,7 @@ Set a background image. Can be a pointer to `lv_img_dsc_t`, a path to a file or
|
||||
|
||||
|
||||
### 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.
|
||||
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 (opaque), other numeric values or the constants LV_OPA_10, LV_OPA_20, etc. mean semi-transparency.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_OPA_COVER`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -454,7 +454,7 @@ Set the opacity of the background image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP`
|
||||
|
||||
|
||||
### bg_img_recolor
|
||||
Set a color to mix to the background image.
|
||||
Set a color to mix with the background image.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `0x000000`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -465,7 +465,7 @@ Set a color to mix to the background image.
|
||||
|
||||
|
||||
### 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.
|
||||
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 numeric values or the constants LV_OPA_10, LV_OPA_20, etc. are interpreted proportionally.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_OPA_TRANSP`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -486,11 +486,11 @@ If enabled the background image will be tiled. The possible values are `true` or
|
||||
|
||||
|
||||
## Border
|
||||
Properties to describe the borders
|
||||
Properties to describe object borders
|
||||
|
||||
|
||||
### border_color
|
||||
Set the color of the border
|
||||
Set the color of a border
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `0x000000`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -501,7 +501,7 @@ Set the color of the border
|
||||
|
||||
|
||||
### border_opa
|
||||
Set the opacity 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.
|
||||
Set the opacity of a 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 numeric values or the constants LV_OPA_10, LV_OPA_20, etc. mean semi-transparency.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_OPA_COVER`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -512,7 +512,7 @@ Set the opacity of the border. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means full
|
||||
|
||||
|
||||
### border_width
|
||||
Set the width of the border. Only pixel values can be used.
|
||||
Set the width of a 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>
|
||||
@ -523,7 +523,7 @@ Set the width of the border. Only pixel values can be used.
|
||||
|
||||
|
||||
### 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 values can be used as well, e.g. `LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_LEFT`.
|
||||
Set on which side(s) a border should be drawn. The possible values are `LV_BORDER_SIDE_NONE/TOP/BOTTOM/LEFT/RIGHT/INTERNAL`. OR-ed values can 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> `LV_BORDER_SIDE_NONE`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -534,7 +534,7 @@ Set ony which side(s) the border should be drawn. The possible values are `LV_BO
|
||||
|
||||
|
||||
### border_post
|
||||
Sets whether the border should be drawn before or after the children are drawn. `true`: after children, `false`: before children
|
||||
Sets whether the border should be drawn before or after an object's children are 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>
|
||||
@ -559,7 +559,7 @@ Sets the color of the text.
|
||||
|
||||
|
||||
### 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.
|
||||
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 numeric values or the constants LV_OPA_10, LV_OPA_20, etc. mean semi-transparency.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_OPA_COVER`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> Yes</li>
|
||||
@ -614,7 +614,7 @@ Set decoration for the text. The possible values are `LV_TEXT_DECOR_NONE/UNDERLI
|
||||
|
||||
|
||||
### 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
|
||||
Set how to align lines of 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` detects 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> `LV_TEXT_ALIGN_AUTO`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> Yes</li>
|
||||
@ -624,11 +624,11 @@ Set how to align the lines of the text. Note that it doesn't align the object it
|
||||
|
||||
|
||||
## Image
|
||||
Properties to describe the images
|
||||
Properties to describe images
|
||||
|
||||
|
||||
### 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.
|
||||
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 numeric values or the constants LV_OPA_10, LV_OPA_20, etc. mean semi-transparency.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_OPA_COVER`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -639,7 +639,7 @@ Set the opacity of an image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully
|
||||
|
||||
|
||||
### img_recolor
|
||||
Set color to mix to the image.
|
||||
Set color to mix with an image.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `0x000000`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -650,7 +650,7 @@ Set color to mix to the image.
|
||||
|
||||
|
||||
### 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.
|
||||
Set the intensity of 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 (opaque), other numeric values or the constants LV_OPA_10, LV_OPA_20, etc. mean 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>
|
||||
@ -660,11 +660,11 @@ Set the intensity of the color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` me
|
||||
|
||||
|
||||
## Outline
|
||||
Properties to describe the outline. It's like a border but drawn outside the rectangles.
|
||||
Properties to describe an object's outline. It's like a border but drawn outside the bounding area.
|
||||
|
||||
|
||||
### outline_width
|
||||
Set the width of the outline in pixels.
|
||||
Set the width of an 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>
|
||||
@ -675,7 +675,7 @@ Set the width of the outline in pixels.
|
||||
|
||||
|
||||
### outline_color
|
||||
Set the color of the outline.
|
||||
Set the color of an outline.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `0x000000`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -686,7 +686,7 @@ Set the color of the outline.
|
||||
|
||||
|
||||
### 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.
|
||||
Set the opacity of an outline. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering (opaque), other numeric values or the constants LV_OPA_10, LV_OPA_20, etc. mean semi-transparency.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_OPA_COVER`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -697,7 +697,7 @@ Set the opacity of the outline. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means ful
|
||||
|
||||
|
||||
### outline_pad
|
||||
Set the padding of the outline, i.e. the gap between object and the outline.
|
||||
Set the padding of an outline, i.e. the gap between an object and its 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>
|
||||
@ -707,7 +707,7 @@ Set the padding of the outline, i.e. the gap between object and the outline.
|
||||
|
||||
|
||||
## Shadow
|
||||
Properties to describe the shadow drawn under the rectangles.
|
||||
Properties to describe the shadow drawn under rectangles.
|
||||
|
||||
|
||||
### shadow_width
|
||||
@ -744,7 +744,7 @@ Set an offset on the shadow in pixels in Y direction.
|
||||
|
||||
|
||||
### shadow_spread
|
||||
Make the shadow calculation to use a larger or smaller rectangle as base. The value can be in pixel to make the area larger/smaller
|
||||
Make the shadow calculation use a larger or smaller rectangle as base. The value can be in pixels to 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>
|
||||
@ -766,7 +766,7 @@ Set the color of the shadow
|
||||
|
||||
|
||||
### 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.
|
||||
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 (opaque), other numeric values or the constants LV_OPA_10, LV_OPA_20, etc. mean semi-transparency.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_OPA_COVER`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -780,7 +780,7 @@ Properties to describe line-like objects
|
||||
|
||||
|
||||
### line_width
|
||||
Set the width of the lines in pixel.
|
||||
Set the width of lines 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>
|
||||
@ -791,7 +791,7 @@ Set the width of the lines in pixel.
|
||||
|
||||
|
||||
### line_dash_width
|
||||
Set the width of dashes in pixel. Note that dash works only on horizontal and vertical lines
|
||||
Set the width of dashes in pixels. 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>
|
||||
@ -802,7 +802,7 @@ Set the width of dashes in pixel. Note that dash works only on horizontal and ve
|
||||
|
||||
|
||||
### line_dash_gap
|
||||
Set the gap between dashes in pixel. Note that dash works only on horizontal and vertical lines
|
||||
Set the gap between dashes in pixels. 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>
|
||||
@ -813,7 +813,7 @@ Set the gap between dashes in pixel. Note that dash works only on horizontal and
|
||||
|
||||
|
||||
### line_rounded
|
||||
Make the end points of the lines rounded. `true`: rounded, `false`: perpendicular line ending
|
||||
Make the end points of lines rounded. `true`: rounded, `false`: perpendicular 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>
|
||||
@ -824,7 +824,7 @@ Make the end points of the lines rounded. `true`: rounded, `false`: perpendicula
|
||||
|
||||
|
||||
### line_color
|
||||
Set the color fo the lines.
|
||||
Set the color of lines.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `0x000000`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -835,7 +835,7 @@ Set the color fo the lines.
|
||||
|
||||
|
||||
### line_opa
|
||||
Set the opacity of the lines.
|
||||
Set the opacity of lines.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_OPA_COVER`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -849,7 +849,7 @@ TODO
|
||||
|
||||
|
||||
### arc_width
|
||||
Set the width (thickness) of the arcs in pixel.
|
||||
Set the width (thickness) of arcs 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>
|
||||
@ -860,7 +860,7 @@ Set the width (thickness) of the arcs in pixel.
|
||||
|
||||
|
||||
### arc_rounded
|
||||
Make the end points of the arcs rounded. `true`: rounded, `false`: perpendicular line ending
|
||||
Make the end points of arcs rounded. `true`: rounded, `false`: perpendicular 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>
|
||||
@ -893,7 +893,7 @@ Set the opacity of the arcs.
|
||||
|
||||
|
||||
### 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
|
||||
Set an image from which the arc will be masked out. It's useful to display complex effects on 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> `NULL`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
|
@ -4,17 +4,17 @@
|
||||
```
|
||||
# Styles
|
||||
|
||||
*Styles* are used to set the appearance of the objects. Styles in lvgl are heavily inspired by CSS. The concept in nutshell is as follows:
|
||||
*Styles* are used to set the appearance of objects. Styles in lvgl are heavily inspired by CSS. The concept in a nutshell is as follows:
|
||||
- A style is an `lv_style_t` variable which can hold properties like 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.
|
||||
- Styles can be assigned to objects to change their appearance. Upon assignment, the target part (*pseudo-element* in CSS) and target state (*pseudo class*) can be specified.
|
||||
For example one can 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 specified by any of the styles.
|
||||
- Styles can be cascaded which means multiple styles may be assigned to an object and each style can have different properties.
|
||||
Therefore, not all properties have to be specified in a style. LVGL will search for a property until a style defines it or use a default if it's not specified 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 latter 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.
|
||||
- The most recently added style has higher precedence. This means if a property is specified in two styles the newest style in the object will be used.
|
||||
- Some properties (e.g. text color) can be inherited from a parent(s) if it's not specified in an object.
|
||||
- Objects can also have local styles with 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.
|
||||
|
||||
@ -35,10 +35,10 @@ The objects can be in the combination of the following states:
|
||||
- `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. This is represented as `LV_STATE_FOCUSED | LV_STATE_PRESSED`.
|
||||
An object can be in a combination of states such as being focused and pressed at the same time. This is 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.
|
||||
A style can be added to any state or state combination.
|
||||
For example, setting a different background color for the default and pressed states.
|
||||
If a property is not defined in a state the best matching state's property will be used. Typically this means the property with `LV_STATE_DEFAULT` is used.˛
|
||||
If the property is not set even for the default state the default value will be used. (See later)
|
||||
|
||||
@ -49,17 +49,17 @@ To determine which state's property to use let's take an example. Imagine the ba
|
||||
- `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.
|
||||
1. Initially the object is in the 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 is higher than the pressed state's 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 for lack of a better option, the object remains white from the default state's property.
|
||||
6. When the object is in the checked state there is no property to set the background color for this state. So for 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 will still want to see if it's pressed, therefore pressed state has a higher precedence.
|
||||
- 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 will still want to see if it's pressed, therefore the pressed state has a higher precedence.
|
||||
If the focused state had a higher precedence it would overwrite the pressed color.
|
||||
- If you want to set a property for all states (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)
|
||||
@ -69,14 +69,14 @@ Instead, for example, use the background color for pressed and checked states an
|
||||
|
||||
## 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 have the later added style 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.
|
||||
For example, create a general gray button style and create a new one for red buttons where only the new background color is set.
|
||||
|
||||
This is much like in CSS when used classes are listed like `<div class=".btn .btn-red">`.
|
||||
|
||||
Styles added later have precedence over ones set earlier. 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.
|
||||
However, the precedence of the 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 basic button style defines dark-gray color for the default state and light-gray color for the 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 most recently added style (red).
|
||||
@ -85,23 +85,23 @@ When the button is pressed the light-gray color is a better match because it des
|
||||
## Inheritance
|
||||
Some properties (typically those related to text) 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 specifies a value for the property. The parents will use their own state to determine the value.
|
||||
In this case, if the property is inheritable, the property's value will be searched in the parents until an object specifies a value for the property. The parents will use their own state to determine 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.
|
||||
Objects can be composed of *parts* which may each 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_KNOB` Like a handle to grab to adjust a value
|
||||
- `LV_PART_SELECTED` Indicate the currently selected option or section
|
||||
- `LV_PART_ITEMS` Used if the widget has multiple similar elements (e.g. table cells)*/
|
||||
- `LV_PART_ITEMS` Used if the widget has multiple similar elements (e.g. table 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.
|
||||
- `LV_PART_CUSTOM_FIRST` Custom part identifiers can be added starting from here.
|
||||
|
||||
|
||||
For example a [Slider](/widgets/core/slider) has three parts:
|
||||
@ -109,14 +109,14 @@ For example a [Slider](/widgets/core/slider) has three parts:
|
||||
- Indicator
|
||||
- Knob
|
||||
|
||||
It means all three parts of the slider can have their own styles. See later how to add styles to objects and parts.
|
||||
This means all three parts of the slider can have their own styles. See later how to add 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.
|
||||
In other words they cannot be local variables in functions which are destroyed when the function exits.
|
||||
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.
|
||||
After initializing a style, properties can be added or changed.
|
||||
|
||||
Property set functions looks like this: `lv_style_set_<property_name>(&style, <value>);` For example:
|
||||
```c
|
||||
@ -142,7 +142,7 @@ lv_style_remove_prop(&style, LV_STYLE_BG_COLOR);
|
||||
To get a property's value from a style:
|
||||
```c
|
||||
lv_style_value_t v;
|
||||
lv_res_t res = lv_style_rget_prop(&style, LV_STYLE_BG_COLOR, &v);
|
||||
lv_res_t res = lv_style_get_prop(&style, LV_STYLE_BG_COLOR, &v);
|
||||
if(res == LV_RES_OK) { /*Found*/
|
||||
do_something(v.color);
|
||||
}
|
||||
@ -153,13 +153,13 @@ if(res == LV_RES_OK) { /*Found*/
|
||||
- `color` for color properties
|
||||
- `ptr` for pointer properties
|
||||
|
||||
To reset a style (free all its data) use
|
||||
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 is not that useful, it needs to be assigned to an object to take effect.
|
||||
A style on its own is not that useful. It must be assigned to an object to take 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:
|
||||
@ -173,39 +173,39 @@ To add a style to an object use `lv_obj_add_style(obj, &style, <selector>)`. `<s
|
||||
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*/
|
||||
lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); /*Overwrite only 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.
|
||||
`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 from 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())`.
|
||||
If a style which is already assigned to an 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_invalidate(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. To make LVGL check all objects to see whether they use the style and refresh them when needed call `lv_obj_report_style_change(&style)`. If `style` is `NULL` all objects will be notified about the style change.
|
||||
3. To make LVGL check all objects to see if they use a style and refresh them when needed, call `lv_obj_report_style_change(&style)`. If `style` is `NULL` all objects will be notified about a 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:
|
||||
To get a final value of property - considering cascading, inheritance, local styles and transitions (see below) - property get functions like this can be used:
|
||||
`lv_obj_get_style_<property_name>(obj, <part>)`.
|
||||
These functions use the object's current state and if no better candidate returns a default value.
|
||||
These functions use the object's current state and if no better candidate exists they return 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.
|
||||
In addition to "normal" styles, objects can also store local styles. 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.
|
||||
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 an object.
|
||||
|
||||
Unlike in CSS, in LVGL local styles can be assigned to states (*pseudo-classes*) and parts (*pseudo-elements*).
|
||||
Unlike in CSS, 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:
|
||||
@ -216,7 +216,7 @@ lv_obj_set_style_local_bg_color(slider, lv_color_red(), LV_PART_INDICATOR | LV_S
|
||||
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 uses the typical background properties". The "typical background properties" are the ones related to:
|
||||
In the documentation of the widgets you will see sentences like "The widget uses the typical background properties". These "typical background properties" are the ones related to:
|
||||
- Background
|
||||
- Border
|
||||
- Outline
|
||||
@ -233,12 +233,12 @@ For example, on pressing a button its background color can be animated to the pr
|
||||
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 animation path (also known as the 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 the default state a 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 pressed state.
|
||||
So this example configuration will result in going to pressed state quickly and then going back to default slowly.
|
||||
The transition properties can be defined for each state. For example, setting a 500 ms transition time in the default state means that when the object goes to the default state a 500 ms transition time is applied.
|
||||
Setting a 100 ms transition time in the pressed state causes a 100 ms transition when going to the pressed state.
|
||||
This example configuration results in going to the pressed state quickly and then going back to default slowly.
|
||||
|
||||
To describe a transition an `lv_transition_dsc_t` variable needs to be initialized and added to a style:
|
||||
```c
|
||||
@ -264,11 +264,11 @@ This will give a default appearance to the UI which can then be modified by addi
|
||||
|
||||
Every display can have a different theme. For example, you could have 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:
|
||||
To set a theme for a display, two 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:
|
||||
Theme initialization functions can have different prototypes. 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*/
|
||||
@ -279,12 +279,12 @@ 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.
|
||||
The included themes are 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.
|
||||
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`.
|
||||
|
@ -7,14 +7,14 @@
|
||||
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 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.
|
||||
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. This 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.
|
||||
A timer callback should have a `void (*lv_timer_cb_t)(lv_timer_t *);` prototype.
|
||||
|
||||
For example:
|
||||
```c
|
||||
@ -40,19 +40,19 @@ 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_ready(timer)` makes a 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:
|
||||
You can modify some timer parameters later:
|
||||
- `lv_timer_set_cb(timer, new_cb)`
|
||||
- `lv_timer_set_period(timer, new_period)`
|
||||
|
||||
## Repeat count
|
||||
|
||||
You can make a timer repeat only a given number of times with `lv_timer_set_repeat_count(timer, count)`. The timer will automatically be deleted after being called the defined number of times. Set the count to `-1` to repeat indefinitely.
|
||||
You can make a timer repeat only a given number of times with `lv_timer_set_repeat_count(timer, count)`. The timer will automatically be deleted after it's called the defined number of times. Set the count to `-1` to repeat indefinitely.
|
||||
|
||||
|
||||
## Measure idle time
|
||||
@ -62,8 +62,8 @@ It can be misleading if you use an operating system and call `lv_timer_handler`
|
||||
|
||||
## 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.
|
||||
In some cases, you can't perform 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 call `my_function` on the next invocation of `lv_timer_handler`. `data_p` will be passed to the function when it's called.
|
||||
Note that only the data pointer 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:
|
||||
@ -78,16 +78,16 @@ void my_screen_clean_up(void * scr)
|
||||
|
||||
...
|
||||
|
||||
/*Do somethings with the object on the current screen*/
|
||||
/*Do something with the object on the current screen*/
|
||||
|
||||
/*Delete screen on next call of `lv_timer_handler`, so not now.*/
|
||||
/*Delete screen on next call of `lv_timer_handler`, not right 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`.
|
||||
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
|
||||
|
||||
|
@ -4,14 +4,14 @@
|
||||
```
|
||||
# Display interface
|
||||
|
||||
To register a display for LVGL a `lv_disp_draw_buf_t` and a `lv_disp_drv_t` variable have to be initialized.
|
||||
To register a display for LVGL, a `lv_disp_draw_buf_t` and a `lv_disp_drv_t` variable have to be initialized.
|
||||
- `lv_disp_draw_buf_t` contains internal graphic buffer(s) called draw buffer(s).
|
||||
- `lv_disp_drv_t` contains callback functions to interact with the display and manipulate drawing related things.
|
||||
- `lv_disp_drv_t` contains callback functions to interact with the display and manipulate low level drawing behavior.
|
||||
|
||||
## Draw buffer
|
||||
|
||||
Draw buffer(s) are simple array(s) that LVGL uses to render the screen content.
|
||||
Once rendering is ready the content of the draw buffer is sent to the display using the `flush_cb` function, set in the display driver (see below).
|
||||
Once rendering is ready the content of the draw buffer is sent to the display using the `flush_cb` function set in the display driver (see below).
|
||||
|
||||
A draw buffer can be initialized via a `lv_disp_draw_buf_t` variable like this:
|
||||
```c
|
||||
@ -26,37 +26,37 @@ static lv_color_t buf_2[MY_DISP_HOR_RES * 10];
|
||||
lv_disp_draw_buf_init(&disp_buf, buf_1, buf_2, MY_DISP_HOR_RES*10);
|
||||
```
|
||||
|
||||
Note that `lv_disp_draw_buf_t` needs to be static, global or dynamically allocated and not a local variable destroyed when it goes out of the scope.
|
||||
Note that `lv_disp_draw_buf_t` must be a static, global or dynamically allocated variable. It cannot be a local variable as they are destroyed upon end of scope.
|
||||
|
||||
As you can see the draw buffer can be smaller than the screen. In this case, the larger areas will be redrawn in smaller parts that fit into the draw buffer(s).
|
||||
As you can see above, the draw buffer may be smaller than the screen. In this case, larger areas are redrawn in smaller segments that fit into the draw buffer(s).
|
||||
If only a small area changes (e.g. a button is pressed) then only that area will be refreshed.
|
||||
|
||||
A larger buffer results in better performance but above 1/10 screen sized buffer(s) there is no significant performance improvement.
|
||||
Therefore it's recommended to choose the size of the draw buffer(s) to at least 1/10 screen sized.
|
||||
Therefore it's recommended to choose the size of the draw buffer(s) to be at least 1/10 screen sized.
|
||||
|
||||
If only **one buffer** is used LVGL draws the content of the screen into that draw buffer and sends it to the display.
|
||||
This way LVGL needs to wait until the content of the buffer is sent to the display before drawing something new in it.
|
||||
LVGL then needs to wait until the content of the buffer is sent to the display before drawing something new in it.
|
||||
|
||||
If **two buffers** are used LVGL can draw into one buffer while the content of the other buffer is sent to display in the background.
|
||||
DMA or other hardware should be used to transfer the data to the display to let the MCU draw meanwhile.
|
||||
This way, the rendering and refreshing of the display become parallel.
|
||||
If **two buffers** are used LVGL can draw into one buffer while the content of the other buffer is sent to the display in the background.
|
||||
DMA or other hardware should be used to transfer data to the display so the MCU can continue drawing.
|
||||
This way, the rendering and refreshing of the display become parallel operations.
|
||||
|
||||
In the display driver (`lv_disp_drv_t`) the `full_refresh` bit can be enabled to force LVGL to always redraw the whole screen. This works in both *one buffer* and *two buffers* modes.
|
||||
In the display driver (`lv_disp_drv_t`) enabling the `full_refresh` bit will force LVGL to always redraw the whole screen. This works in both *one buffer* and *two buffers* modes.
|
||||
|
||||
If `full_refresh` is enabled and 2 screen sized draw buffers are provided, LVGL's display handling works like "traditional" double buffering.
|
||||
This means in `flush_cb` only the address of the framebuffer needs to be changed to the provided pointer (`color_p` parameter).
|
||||
This configuration should be used if the MCU has LCD controller periphery and not with an external display controller (e.g. ILI9341 or SSD1963).
|
||||
If `full_refresh` is enabled and two screen sized draw buffers are provided, LVGL's display handling works like "traditional" double buffering.
|
||||
This means the `flush_cb` callback only has to update the address of the framebuffer (`color_p` parameter).
|
||||
This configuration should be used if the MCU has an LCD controller peripheral and not with an external display controller (e.g. ILI9341 or SSD1963) accessed via serial link. The latter will generally be too slow to maintain high frame rates with full screen redraws.
|
||||
|
||||
You can measure the performance of different draw buffer configurations using the [benchmark example](https://github.com/lvgl/lv_demos/tree/master/src/lv_demo_benchmark).
|
||||
|
||||
## Display driver
|
||||
|
||||
Once the buffer initialization is ready a `lv_disp_drv_t` display driver needs to be
|
||||
Once the buffer initialization is ready a `lv_disp_drv_t` display driver needs to be:
|
||||
1. initialized with `lv_disp_drv_init(&disp_drv)`
|
||||
2. its fields need to be set
|
||||
3. it needs to be registered in LVGL with `lv_disp_drv_register(&disp_drv)`
|
||||
|
||||
Note that `lv_disp_drv_t` also needs to be static, global or dynamically allocated and not a local variable destroyed when it goes out of the scope.
|
||||
Note that `lv_disp_drv_t` also needs to be a static, global or dynamically allocated variable.
|
||||
|
||||
### Mandatory fields
|
||||
In the most simple case only the following fields of `lv_disp_drv_t` need to be set:
|
||||
@ -68,19 +68,19 @@ In the most simple case only the following fields of `lv_disp_drv_t` need to be
|
||||
LVGL might render the screen in multiple chunks and therefore call `flush_cb` multiple times. To see if the current one is the last chunk of rendering use `lv_disp_flush_is_last(&disp_drv)`.
|
||||
|
||||
### Optional fields
|
||||
There are some optional data fields:
|
||||
- `color_chroma_key` A color which will be drawn as transparent on chrome keyed images. Set to `LV_COLOR_CHROMA_KEY` by default from `lv_conf.h`.
|
||||
There are some optional display driver data fields:
|
||||
- `color_chroma_key` A color which will be drawn as transparent on chrome keyed images. Set to `LV_COLOR_CHROMA_KEY` from `lv_conf.h` by default.
|
||||
- `anti_aliasing` use anti-aliasing (edge smoothing). Enabled by default if `LV_COLOR_DEPTH` is set to at least 16 in `lv_conf.h`.
|
||||
- `rotated` and `sw_rotate` See the [Rotation](#rotation) section below.
|
||||
- `screen_transp` if `1` the screen itself can have transparency as well. `LV_COLOR_SCREEN_TRANSP` needs to enabled in `lv_conf.h` and requires `LV_COLOR_DEPTH 32`.
|
||||
- `user_data` A custom `void `user data for the driver..
|
||||
- `screen_transp` if `1` the screen itself can have transparency as well. `LV_COLOR_SCREEN_TRANSP` must be enabled in `lv_conf.h` and `LV_COLOR_DEPTH` must be 32.
|
||||
- `user_data` A custom `void` user data for the driver..
|
||||
|
||||
Some other optional callbacks to make easier and more optimal to work with monochrome, grayscale or other non-standard RGB displays:
|
||||
Some other optional callbacks to make it easier and more optimal to work with monochrome, grayscale or other non-standard RGB displays:
|
||||
- `rounder_cb` Round the coordinates of areas to redraw. E.g. a 2x2 px can be converted to 2x8.
|
||||
It can be used if the display controller can refresh only areas with specific height or width (usually 8 px height with monochrome displays).
|
||||
- `set_px_cb` a custom function to write the draw buffer. It can be used to store the pixels more compactly in the draw buffer if the display has a special color format. (e.g. 1-bit monochrome, 2-bit grayscale etc.)
|
||||
This way the buffers used in `lv_disp_draw_buf_t` can be smaller to hold only the required number of bits for the given area size. Note that, rendering with `set_px_cb` is slower than normal rendering.
|
||||
- `monitor_cb` A callback function that tells how many pixels were refreshed in how much time. Called when the last chunk is rendered and sent to the display.
|
||||
This way the buffers used in `lv_disp_draw_buf_t` can be smaller to hold only the required number of bits for the given area size. Note that rendering with `set_px_cb` is slower than normal rendering.
|
||||
- `monitor_cb` A callback function that tells how many pixels were refreshed and in how much time. Called when the last chunk is rendered and sent to the display.
|
||||
- `clean_dcache_cb` A callback for cleaning any caches related to the display.
|
||||
|
||||
LVGL has built-in support to several GPUs (see `lv_conf.h`) but if something else is required these functions can be used to make LVGL use a GPU:
|
||||
@ -170,7 +170,7 @@ LVGL supports rotation of the display in 90 degree increments. You can select wh
|
||||
|
||||
If you select software rotation (`sw_rotate` flag set to 1), LVGL will perform the rotation for you. Your driver can and should assume that the screen width and height have not changed. Simply flush pixels to the display as normal. Software rotation requires no additional logic in your `flush_cb` callback.
|
||||
|
||||
There is a noticeable amount of overhead to performing rotation in software, which is why hardware rotation is also available. In this mode, LVGL draws into the buffer as though your screen now has the width and height inverted. You are responsible for rotating the provided pixels yourself.
|
||||
There is a noticeable amount of overhead to performing rotation in software. Hardware rotation is available to avoid unwanted slow downs. In this mode, LVGL draws into the buffer as if your screen width and height were swapped. You are responsible for rotating the provided pixels yourself.
|
||||
|
||||
The default rotation of your display when it is initialized can be set using the `rotated` flag. The available options are `LV_DISP_ROT_NONE`, `LV_DISP_ROT_90`, `LV_DISP_ROT_180`, or `LV_DISP_ROT_270`. The rotation values are relative to how you would rotate the physical display in the clockwise direction. Thus, `LV_DISP_ROT_90` means you rotate the hardware 90 degrees clockwise, and the display rotates 90 degrees counterclockwise to compensate.
|
||||
|
||||
|
@ -17,7 +17,7 @@ indev_drv.read_cb =... /*See below.*/
|
||||
lv_indev_t * my_indev = lv_indev_drv_register(&indev_drv);
|
||||
```
|
||||
|
||||
`type` can be
|
||||
The `type` member can be:
|
||||
- `LV_INDEV_TYPE_POINTER` touchpad or mouse
|
||||
- `LV_INDEV_TYPE_KEYPAD` keyboard or keypad
|
||||
- `LV_INDEV_TYPE_ENCODER` encoder with left/right turn and push options
|
||||
@ -75,7 +75,7 @@ void keyboard_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
|
||||
```
|
||||
|
||||
### Encoder
|
||||
With an encoder you can do 4 things:
|
||||
With an encoder you can do the following:
|
||||
1. Press its button
|
||||
2. Long-press its button
|
||||
3. Turn left
|
||||
@ -84,8 +84,8 @@ With an encoder you can do 4 things:
|
||||
In short, the Encoder input devices work like this:
|
||||
- By turning the encoder you can focus on the next/previous object.
|
||||
- When you press the encoder on a simple object (like a button), it will be clicked.
|
||||
- If you press the encoder on a complex object (like a list, message box, etc.) the object will go to edit mode whereby turning the encoder you can navigate inside the object.
|
||||
- To leave edit mode press long the button.
|
||||
- If you press the encoder on a complex object (like a list, message box, etc.) the object will go to edit mode whereby you can navigate inside the object by turning the encoder.
|
||||
- To leave edit mode, long press the button.
|
||||
|
||||
|
||||
To use an *Encoder* (similarly to the *Keypads*) the objects should be added to groups.
|
||||
@ -115,7 +115,7 @@ You need to have 3 buttons available:
|
||||
- `LV_KEY_RIGHT` will simulate turning encoder right
|
||||
- other keys will be passed to the focused widget
|
||||
|
||||
If you hold the keys it will simulate encoder click with period specified in `indev_drv.long_press_rep_time`.
|
||||
If you hold the keys it will simulate an encoder advance with period specified in `indev_drv.long_press_rep_time`.
|
||||
|
||||
```c
|
||||
indev_drv.type = LV_INDEV_TYPE_ENCODER;
|
||||
@ -183,14 +183,14 @@ Besides `read_cb` a `feedback_cb` callback can be also specified in `lv_indev_dr
|
||||
|
||||
|
||||
### Associating with a display
|
||||
Every input device is associated with a display. By default, a new input device is added to the lastly created or the explicitly selected (using `lv_disp_set_default()`) display.
|
||||
Every input device is associated with a display. By default, a new input device is added to the last display created or explicitly selected (using `lv_disp_set_default()`).
|
||||
The associated display is stored and can be changed in `disp` field of the driver.
|
||||
|
||||
### Buffered reading
|
||||
By default, LVGL calls `read_cb` periodically. This way there is a chance that some user gestures are missed.
|
||||
By default, LVGL calls `read_cb` periodically. Because of this intermittent polling there is a chance that some user gestures are missed.
|
||||
|
||||
To solve this you can write an event driven driver for your input device that buffers measured data. In `read_cb` you can set the buffered data instead of reading the input device.
|
||||
You can set the `data->continue_reading` flag to tell that LVGL there is more data to read and it should call the `read_cb` again.
|
||||
To solve this you can write an event driven driver for your input device that buffers measured data. In `read_cb` you can report the buffered data instead of directly reading the input device.
|
||||
Setting the `data->continue_reading` flag will tell LVGL there is more data to read and it should call `read_cb` again.
|
||||
|
||||
## Further reading
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
```
|
||||
# Logging
|
||||
|
||||
LVGL has built-in *Log* module to inform the user about what is happening in the library.
|
||||
LVGL has a built-in *Log* module to inform the user about what is happening in the library.
|
||||
|
||||
## Log level
|
||||
To enable logging, set `LV_USE_LOG 1` in `lv_conf.h` and set `LV_LOG_LEVEL` to one of the following values:
|
||||
|
@ -15,21 +15,21 @@ The graphics library itself is the **lvgl** directory which should be copied int
|
||||
|
||||
## Configuration file
|
||||
|
||||
There is a configuration header file for LVGL called **lv_conf.h**. In this you can set the library's basic behavior, disable unused modules and features, adjust the size of memory buffers in compile-time, etc.
|
||||
There is a configuration header file for LVGL called **lv_conf.h**. You modify this header to set the library's basic behavior, disable unused modules and features, adjust the size of memory buffers in compile-time, etc.
|
||||
|
||||
Copy **lvgl/lv_conf_template.h** next to the *lvgl* directory and rename it to *lv_conf.h*. Open the file and change the `#if 0` at the beginning to `#if 1` to enable its content.
|
||||
|
||||
*lv_conf.h* can be copied to another place as well, but then you should add the `LV_CONF_INCLUDE_SIMPLE` define to your compiler options (e.g. `-DLV_CONF_INCLUDE_SIMPLE` for gcc compiler) and set the include path manually.
|
||||
Alternatively, *lv_conf.h* can be copied to another place but then you should add the `LV_CONF_INCLUDE_SIMPLE` define to your compiler options (e.g. `-DLV_CONF_INCLUDE_SIMPLE` for gcc compiler) and set the include path manually.
|
||||
In this case LVGL will attempt to include `lv_conf.h` simply with `#include "lv_conf.h"`.
|
||||
|
||||
In the config file comments explain the meaning of the options. Be sure to set at least `LV_COLOR_DEPTH` according to your display's color depth.
|
||||
Comments in the config file explain the meaning of the options. Be sure to set at least `LV_COLOR_DEPTH` according to your display's color depth.
|
||||
|
||||
## Initialization
|
||||
|
||||
To use the graphics library you have to initialize it and the other components too. The order of the initialization is:
|
||||
To use the graphics library you have to initialize it and setup required components. The order of the initialization is:
|
||||
|
||||
1. Call `lv_init()`.
|
||||
2. Initialize your drivers.
|
||||
3. Register the display and input devices drivers in LVGL. Lear more about [Display](/porting/display) and [Input device](/porting/indev) registration.
|
||||
4. Call `lv_tick_inc(x)` every `x` milliseconds in an interrupt to tell the elapsed time. [Learn more](/porting/tick).
|
||||
3. Register the display and input devices drivers in LVGL. Learn more about [Display](/porting/display) and [Input device](/porting/indev) registration.
|
||||
4. Call `lv_tick_inc(x)` every `x` milliseconds in an interrupt to report the elapsed time to LVGL. [Learn more](/porting/tick).
|
||||
5. Call `lv_timer_handler()` every few milliseconds to handle LVGL related tasks. [Learn more](/porting/task-handler).
|
||||
|
@ -21,7 +21,7 @@ while(1) {
|
||||
}
|
||||
```
|
||||
|
||||
You should also add the below lines to your input device read function to signal a wake-up (press, touch or click etc.) happened:
|
||||
You should also add the following lines to your input device read function to signal a wake-up (press, touch or click etc.) has happened:
|
||||
```c
|
||||
lv_tick_inc(LV_DISP_DEF_REFR_PERIOD); /*Force task execution on wake-up*/
|
||||
timer_start(); /*Restart the timer where lv_tick_inc() is called*/
|
||||
|
@ -12,7 +12,7 @@ You need to call the `lv_tick_inc(tick_period)` function periodically and provid
|
||||
|
||||
With FreeRTOS `lv_tick_inc` can be called in `vApplicationTickHook`.
|
||||
|
||||
On Linux based operating system (e.g. on Raspberry Pi) `lv_tick_inc` can be called in a thread like below:
|
||||
On Linux based operating systems (e.g. on Raspberry Pi) `lv_tick_inc` can be called in a thread like below:
|
||||
```c
|
||||
void * tick_thread (void *args)
|
||||
{
|
||||
|
@ -50,7 +50,7 @@ The change rate is defined in degree/second unit and can be set with `lv_arc_set
|
||||
It's also possible to set the angles of the indicator arc directly with `lv_arc_set_angles(arc, start_angle, end_angle)` function or `lv_arc_set_start/end_angle(arc, start_angle)`.
|
||||
In this case the set "value" and "mode" are ignored.
|
||||
|
||||
In other words, settings angles and values are independent. You should use either value or angle settings. Mixing the two might result in unintended behavior.
|
||||
In other words, the angle and value settings are independent. You should exclusively use one or the other. Mixing the two might result in unintended behavior.
|
||||
|
||||
To make the arc non-adjustable, remove the style of the knob and make the object non-clickable:
|
||||
```c
|
||||
|
@ -23,7 +23,7 @@ Options are passed to the Roller as a string with `lv_roller_set_options(roller,
|
||||
You can select an option manually with `lv_roller_set_selected(roller, id, LV_ANIM_ON/OFF)`, where *id* is the index of an option.
|
||||
|
||||
### Get selected option
|
||||
The get the *index* of the currently selected option use `lv_roller_get_selected(roller)`.
|
||||
To get the *index* of the currently selected option use `lv_roller_get_selected(roller)`.
|
||||
|
||||
`lv_roller_get_selected_str(roller, buf, buf_size)` will copy the name of the selected option to `buf`.
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
## Overview
|
||||
|
||||
A spangroup is the object that is used to display rich text. Different from the label object, `spangroup` can automatically organize text of different fonts, colors, and sizes into the spangroup obj.
|
||||
A spangroup is the object that is used to display rich text. Different from the label object, `spangroup` can render text styled with different fonts, colors, and sizes into the spangroup object.
|
||||
|
||||
## Parts and Styles
|
||||
- `LV_PART_MAIN` The spangroup has only one part.
|
||||
@ -15,7 +15,7 @@ A spangroup is the object that is used to display rich text. Different from the
|
||||
|
||||
### Set text and style
|
||||
|
||||
The spangroup object uses span to describe text and text style. so, first we need to create `span` descriptor using `lv_span_t * span = lv_spangroup_new_span(spangroup)`. Then use `lv_span_set_text(span, "text")` to set text.The style of the modified text is the same as the normal style used, eg:`lv_style_set_text_color(&span->style, lv_palette_main(LV_PALETTE_RED))`.
|
||||
The spangroup object uses span to describe text and text style. so, first we need to create `span` descriptor using `lv_span_t * span = lv_spangroup_new_span(spangroup)`. Then use `lv_span_set_text(span, "text")` to set text. The style of the span is configured as with a normal style object by using its `style` member, eg:`lv_style_set_text_color(&span->style, lv_palette_main(LV_PALETTE_RED))`.
|
||||
|
||||
If spangroup object `mode != LV_SPAN_MODE_FIXED` you must call `lv_spangroup_refr_mode()` after you have modified `span` style(eg:set text, changed the font size, del span).
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
## Overview
|
||||
|
||||
The Tile view is a container object whose elements (called *tiles*) can be arranged in grid form.
|
||||
By swiping the user can navigate between the tiles.
|
||||
A user can navigate between the tiles by swiping.
|
||||
Any direction of swiping can be disabled on the tiles individually to not allow moving from one tile to another.
|
||||
|
||||
If the Tile view is screen sized, the user interface resembles what you may have seen on smartwatches.
|
||||
|
@ -17,7 +17,7 @@ In object-oriented thinking, it is the base class from which all other objects i
|
||||
|
||||
The functions and functionalities of the Base object can be used with other widgets too. For example `lv_obj_set_width(slider, 100)`
|
||||
|
||||
The Base object can be directly used as a simple widget: it's nothing else than a rectangle. In HTML terms, think of it as a `<div>`.
|
||||
The Base object can be directly used as a simple widget: it's nothing more than a rectangle. In HTML terms, think of it as a `<div>`.
|
||||
|
||||
### Coordinates
|
||||
|
||||
@ -30,8 +30,8 @@ The object size can be modified on individual axes with `lv_obj_set_width(obj, n
|
||||
You can set the position relative to the parent with `lv_obj_set_x(obj, new_x)` and `lv_obj_set_y(obj, new_y)`, or both axes at the same time with `lv_obj_set_pos(obj, new_x, new_y)`.
|
||||
|
||||
#### Alignment
|
||||
You can align the object on its parent with `lv_obj_set_align(obj, LV_ALIGN_...)`. After this every x and y setting will be ralitive to the set alignment mode.
|
||||
For example, this will shift the object by 10;20 px from the center of its parent.
|
||||
You can align the object on its parent with `lv_obj_set_align(obj, LV_ALIGN_...)`. After this every x and y setting will be relative to the set alignment mode.
|
||||
For example, this will shift the object by 10;20 px from the center of its parent:
|
||||
```c
|
||||
lv_obj_set_align(obj, LV_ALIGN_CENTER);
|
||||
lv_obj_set_pos(obj, 10, 20);
|
||||
@ -40,7 +40,7 @@ lv_obj_set_pos(obj, 10, 20);
|
||||
lv_obj_align(obj, LV_ALIGN_CENTER, 10, 20);
|
||||
```
|
||||
|
||||
To align one object to another use `lv_obj_align_to(obj_to_align, obj_referece, LV_ALIGN_..., x, y)`
|
||||
To align one object to another use: `lv_obj_align_to(obj_to_align, obj_referece, LV_ALIGN_..., x, y)`
|
||||
|
||||
For example, to align a text below an image: `lv_obj_align_to(text, image, LV_ALIGN_OUT_BOTTOM_MID, 0, 10)`.
|
||||
|
||||
@ -51,21 +51,21 @@ The following align types exist:
|
||||
### Parents and children
|
||||
You can set a new parent for an object with `lv_obj_set_parent(obj, new_parent)`. To get the current parent, use `lv_obj_get_parent(obj)`.
|
||||
|
||||
To get a specific children of a parent use `lv_obj_get_child(parent, idx)`. Some examples for `idx`:
|
||||
- `0` get the child created first child
|
||||
To get a specific child of a parent use `lv_obj_get_child(parent, idx)`. Some examples for `idx`:
|
||||
- `0` get the child created first
|
||||
- `1` get the child created second
|
||||
- `-1` get the child created last
|
||||
|
||||
The children can be iterated lke this
|
||||
The children can be iterated lke this:
|
||||
```c
|
||||
uint32_t i;
|
||||
for(i = 0; i < lv_obj_get_child_cnt(parent); i++) {
|
||||
lv_obj_t * child = lv_obj_get_child(paernt, i);
|
||||
lv_obj_t * child = lv_obj_get_child(parent, i);
|
||||
/*Do something with child*/
|
||||
}
|
||||
```
|
||||
|
||||
`lv_obj_get_index(obj)` returns the index of the object. That is how many younger children its parent has.
|
||||
`lv_obj_get_index(obj)` returns the index of the object in its parent. It is equivalent to the number of younger children in the parent.
|
||||
|
||||
You can bring an object to the foreground or send it to the background with `lv_obj_move_foreground(obj)` and `lv_obj_move_background(obj)`.
|
||||
|
||||
@ -73,10 +73,13 @@ You can change the index of an object in its parent using `lv_obj_move_to_index
|
||||
|
||||
You can swap the position of two objects with `lv_obj_swap(obj1, obj2)`.
|
||||
|
||||
### Screens
|
||||
When you have created a screen like `lv_obj_t * screen = lv_obj_create(NULL)`, you can load it with `lv_scr_load(screen)`. The `lv_scr_act()` function gives you a pointer to the current screen.
|
||||
### Display and Screens
|
||||
|
||||
If you have multiple displays then it's important to know that these functions operate on the most-recently created or on the explicitly selected (with `lv_disp_set_default`) display.
|
||||
At the highest level of the LVGL object hierarchy is the *display* which represents the driver for a display device (physical display or simulator). A display can have one or more screens associated with it. Each screen contains a hierarchy of objects for graphical widgets representing a layout that covers the entire display.
|
||||
|
||||
When you have created a screen like `lv_obj_t * screen = lv_obj_create(NULL)`, you can make it active with `lv_scr_load(screen)`. The `lv_scr_act()` function gives you a pointer to the active screen.
|
||||
|
||||
If you have multiple displays, it's important to know that the screen functions operate on the most recently created display or the one explicitly selected with `lv_disp_set_default`.
|
||||
|
||||
To get an object's screen use the `lv_obj_get_screen(obj)` function.
|
||||
|
||||
@ -86,14 +89,14 @@ To set an event callback for an object, use `lv_obj_add_event_cb(obj, event_cb,
|
||||
|
||||
To manually send an event to an object, use `lv_event_send(obj, LV_EVENT_..., param)`
|
||||
|
||||
Read the [Event overview](/overview/event) to learn more about the events.
|
||||
Read the [Event overview](/overview/event) to learn more about events.
|
||||
|
||||
|
||||
### Styles
|
||||
Be sure to read the [Style overview](/overview/style). Here only the most essential functions are described.
|
||||
|
||||
A new style can be added to an object with `lv_obj_add_style(obj, &new_style, selector)` function.
|
||||
`selector` is a combination of part and state(s). E.g. `LV_PART_SCROLLBAR | LV_STATE_PRESSED`.
|
||||
A new style can be added to an object with the `lv_obj_add_style(obj, &new_style, selector)` function.
|
||||
`selector` is an ORed combination of part and state(s). E.g. `LV_PART_SCROLLBAR | LV_STATE_PRESSED`.
|
||||
|
||||
The base objects use `LV_PART_MAIN` style properties and `LV_PART_SCROLLBAR` with the typical backgroud style properties.
|
||||
|
||||
@ -102,7 +105,7 @@ The base objects use `LV_PART_MAIN` style properties and `LV_PART_SCROLLBAR` wit
|
||||
There are some attributes which can be enabled/disabled by `lv_obj_add/clear_flag(obj, LV_OBJ_FLAG_...)`:
|
||||
|
||||
- `LV_OBJ_FLAG_HIDDEN` Make the object hidden. (Like it wasn't there at all)
|
||||
- `LV_OBJ_FLAG_CLICKABLE` Make the object clickable by the input devices
|
||||
- `LV_OBJ_FLAG_CLICKABLE` Make the object clickable by input devices
|
||||
- `LV_OBJ_FLAG_CLICK_FOCUSABLE` Add focused state to the object when clicked
|
||||
- `LV_OBJ_FLAG_CHECKABLE` Toggle checked state when the object is clicked
|
||||
- `LV_OBJ_FLAG_SCROLLABLE` Make the object scrollable
|
||||
@ -115,8 +118,8 @@ There are some attributes which can be enabled/disabled by `lv_obj_add/clear_fla
|
||||
- `LV_OBJ_FLAG_PRESS_LOCK` Keep the object pressed even if the press slid from the object
|
||||
- `LV_OBJ_FLAG_EVENT_BUBBLE` Propagate the events to the parent too
|
||||
- `LV_OBJ_FLAG_GESTURE_BUBBLE` Propagate the gestures to the parent
|
||||
- `LV_OBJ_FLAG_ADV_HITTEST` Allow performing more accurate hit (click) test. E.g. consider rounded corners.
|
||||
- `LV_OBJ_FLAG_IGNORE_LAYOUT` Make the object position-able by the layouts
|
||||
- `LV_OBJ_FLAG_ADV_HITTEST` Allow performing more accurate hit (click) test. E.g. accounting for rounded corners
|
||||
- `LV_OBJ_FLAG_IGNORE_LAYOUT` Make the object positionable by the layouts
|
||||
- `LV_OBJ_FLAG_FLOATING` Do not scroll the object when the parent scrolls and ignore layout
|
||||
|
||||
- `LV_OBJ_FLAG_LAYOUT_1` Custom flag, free to use by layouts
|
||||
@ -128,20 +131,20 @@ There are some attributes which can be enabled/disabled by `lv_obj_add/clear_fla
|
||||
- `LV_OBJ_FLAG_USER_1` Custom flag, free to use by user
|
||||
- `LV_OBJ_FLAG_USER_2` Custom flag, free to use by user
|
||||
- `LV_OBJ_FLAG_USER_3` Custom flag, free to use by user
|
||||
- `LV_OBJ_FLAG_USER_4` Custom flag, free to use by usersection.
|
||||
- `LV_OBJ_FLAG_USER_4` Custom flag, free to use by user
|
||||
|
||||
Some examples:
|
||||
```c
|
||||
/*Hide on object*/
|
||||
lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
/*Make an obejct non-clickable*/
|
||||
/*Make an object non-clickable*/
|
||||
lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE);
|
||||
```
|
||||
|
||||
### Groups
|
||||
|
||||
Read the [Input devices overview](/overview/indev) to learn more about the *Groups*.
|
||||
Read the [Input devices overview](/overview/indev) to learn more about *Groups*.
|
||||
|
||||
Objects are added to a *group* with `lv_group_add_obj(group, obj)`, and you can use `lv_obj_get_group(obj)` to see which group an object belongs to.
|
||||
|
||||
@ -149,7 +152,7 @@ Objects are added to a *group* with `lv_group_add_obj(group, obj)`, and you can
|
||||
|
||||
|
||||
### Extended click area
|
||||
By default, the objects can be clicked only on their coordinates, however, this area can be extended with `lv_obj_set_ext_click_area(obj, size)`.
|
||||
By default, the objects can be clicked only within their bounding area. However, this can be extended with `lv_obj_set_ext_click_area(obj, size)`.
|
||||
|
||||
## Events
|
||||
- `LV_EVENT_VALUE_CHANGED` when the `LV_OBJ_FLAG_CHECKABLE` flag is enabled and the object clicked (on transition to/from the checked state)
|
||||
|
Loading…
Reference in New Issue
Block a user