2023-04-27 06:42:02 -06:00
========
Displays
========
: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
***** ***** ***** ***** *** *
2023-12-13 21:23:08 +01:00
In LVGL you can have multiple displays, each with their own driver,
widgets and color depth.
Creating more displays is easy: just use :cpp:func: `lv_display_create` and
add set the buffer and the `` flush_cb `` . When you create the UI, use
:cpp:expr: `lv_display_set_default(disp)` to tell the library on which display to
2023-04-27 06:42:02 -06:00
create objects.
Why would you want multi-display support? Here are some examples:
- Have a "normal" TFT display with local UI and create "virtual" screens on VNC
on demand. (You need to add your VNC driver).
- Have a large TFT display and a small monochrome display.
- Have some smaller and simple displays in a large instrument or technology.
- Have two large TFT displays: one for a customer and one for the shop assistant.
Using only one display
----------------------
2023-04-27 11:47:13 -06:00
Using more displays can be useful but in most cases it's not required.
2023-04-27 06:42:02 -06:00
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.
2023-10-12 20:37:27 +02:00
:cpp:func: `lv_screen_active` , :cpp:func: `lv_screen_load` , :cpp:func: `lv_layer_top` ,
2023-04-27 06:42:02 -06:00
:cpp:func: `lv_layer_sys` , :c:macro: `LV_HOR_RES` and :c:macro: `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
2023-12-13 21:23:08 +01:00
usually be used. E.g. :cpp:expr: `lv_display_trig_activity(NULL)` will trigger a
2023-04-27 06:42:02 -06:00
user activity on the default display. (See below in `Inactivity <#Inactivity> `__ ).
Mirror display
--------------
2023-04-27 11:47:13 -06:00
To mirror the image of a display to another display, you don't need to
2023-04-27 06:42:02 -06:00
use multi-display support. Just transfer the buffer received in
`` flush_cb `` to the other display too.
Split image
-----------
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
2023-04-27 11:47:13 -06:00
large display's resolution. 2. In `` flush_cb `` , truncate and modify the
`` area `` parameter for each display. 3. Send the buffer's content to
2023-04-27 06:42:02 -06:00
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
objects on each screen.
Be sure not to confuse displays and screens:
- **Displays** are the physical hardware drawing the pixels.
- **Screens** are the high-level root objects associated with a
particular display. One display can have multiple screens associated
with it, but not vice versa.
Screens can be considered the highest level containers which have no
2023-04-27 11:47:13 -06:00
parent. 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,
2023-04-27 06:42:02 -06:00
i.e. :cpp:expr: `lv_obj_set_pos()` , :cpp:expr: `lv_obj_set_size()` or similar functions
2023-04-27 11:47:13 -06:00
can't be used on screens.
2023-04-27 06:42:02 -06:00
A screen can be created from any object type but the two most typical
types are `Base object </widgets/obj> `__ and `Image </widgets/img> `__
(to create a wallpaper).
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.
2023-10-12 20:37:27 +02:00
To load a screen, use :cpp:expr: `lv_screen_load(scr)` . To get the active screen,
use :cpp:expr: `lv_screen_active()` . These functions work on the default display. If
2023-04-27 06:42:02 -06:00
you want to specify which display to work on, use
2023-12-13 21:23:08 +01:00
:cpp:expr: `lv_display_get_screen_active(disp)` and :cpp:expr: `lv_display_load_scr(disp, scr)` . A
2023-04-27 06:42:02 -06:00
screen can be loaded with animations too. Read more
`here <object.html#load-screens> `__ .
2023-10-12 20:37:27 +02:00
Screens can be deleted with :cpp:expr: `lv_obj_delete(scr)` , but ensure that you do
2023-04-27 06:42:02 -06:00
not delete the currently loaded screen.
Transparent screens
-------------------
Usually, the opacity of the screen is :cpp:enumerator: `LV_OPA_COVER` to provide a
solid background for its children. If this is not the case (opacity <
2023-04-27 11:47:13 -06:00
100%) the display's `` bottom_layer `` be visible. If the bottom layer's
2023-04-27 06:42:02 -06:00
opacity is also not :cpp:enumerator: `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 overlaid on an upper layer.
2023-04-27 11:47:13 -06:00
To properly render the screen the display's color format needs to be set
2023-04-27 06:42:02 -06:00
to one with alpha channel.
In summary, to enable transparent screens and displays for OSD menu-like
UIs:
2023-04-27 11:47:13 -06:00
- Set the screen's `` bg_opa `` to transparent:
2023-10-12 20:37:27 +02:00
:cpp:expr: `lv_obj_set_style_bg_opa(lv_screen_active(), LV_OPA_TRANSP, 0)`
2023-04-27 11:47:13 -06:00
- Set the bottom layer's `` bg_opa `` to transparent:
2023-10-12 20:37:27 +02:00
:cpp:expr: `lv_obj_set_style_bg_opa(lv_screen_active(), LV_OPA_TRANSP, 0)`
2023-04-27 11:47:13 -06:00
- Set the screen's bg_opa to 0:
2023-04-27 06:42:02 -06:00
:cpp:expr: `lv_obj_set_style_bg_opa(lv_layer_bottom(), LV_OPA_TRANSP, 0)`
- Set a color format with alpha channel. E.g.
2023-12-13 21:23:08 +01:00
:cpp:expr: `lv_display_set_color_format(disp, LV_COLOR_FORMAT_ARGB8888)`
2023-04-27 06:42:02 -06:00
Features of displays
***** ***** ***** *****
Inactivity
----------
2023-04-27 11:47:13 -06:00
A user's inactivity time is measured on each display. Every use of an
2023-04-27 06:42:02 -06:00
`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
2023-12-13 21:23:08 +01:00
:cpp:expr: `lv_display_get_inactive_time(disp)` . If `` NULL `` is passed, the lowest
2023-04-27 11:47:13 -06:00
inactivity time among all displays will be returned (**NULL isn't just
2023-04-27 06:42:02 -06:00
the default display**).
You can manually trigger an activity using
2023-12-13 21:23:08 +01:00
:cpp:expr: `lv_display_trig_activity(disp)` . If `` disp `` is `` NULL `` , the default
2023-04-27 06:42:02 -06:00
screen will be used (**and not all displays** ).
Background
----------
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.
The background color is a simple color to fill the display. It can be
adjusted with :cpp:expr: `lv_obj_set_style_bg_color(obj, color)` ;
The display background image is a path to a file or a pointer to an
2023-09-27 12:23:40 +02:00
:cpp:struct: `lv_image_dsc_t` variable (converted image data) to be used as
2023-04-27 06:42:02 -06:00
wallpaper. It can be set with :cpp:expr: `lv_obj_set_style_bg_img_src(obj, &my_img)` ;
2023-04-27 11:47:13 -06:00
If a background image is configured the background won't be filled with
2023-04-27 06:42:02 -06:00
`` bg_color `` .
The opacity of the background color or image can be adjusted with
:cpp:expr: `lv_obj_set_style_bg_opa(obj, opa)` .
The `` disp `` parameter of these functions can be `` NULL `` to select the
default display.
API
***