1.. _widget_basics:
2
3=============
4Widget Basics
5=============
6
7
8
9What is a Widget?
10*****************
11A Widget is the **basic building block** of the LVGL user interface.
12
13Examples of Widgets:  :ref:`Base Widget (and Screen) <base_widget>`,
14:ref:`Button <lv_button>`, :ref:`Label <lv_label>`,
15:ref:`Image <lv_image>`, :ref:`List <lv_list>`,
16:ref:`Chart <lv_chart>` and :ref:`Text Area <lv_textarea>`.
17
18See :ref:`widgets` to see all Widget types.
19
20All Widgets are referenced using an :cpp:type:`lv_obj_t` pointer as a handle.
21This pointer can later be used to read or change the Widget's attributes.
22
23
24
25.. _base_widget:
26
27Base Widget
28***********
29The most fundamental of all Widgets is the Base Widget, on which all other widgets
30are based.  From an Object-Oriented perspective, think of the Base Widget as the
31Widget class from which all other Widgets inherit.
32
33The functions and functionalities of the Base Widget can be used with
34other widgets as well.  For example :cpp:expr:`lv_obj_set_width(slider, 100)`.
35
36The Base Widget can be used directly as a simple widget.  While it is a simple
37rectangle, it has a large number of features shared with all Widgets, detailed
38below and in subsequent pages.  In HTML terms, think of it as a ``<div>``.
39
40
41
42.. _widget_attributes:
43
44Attributes
45**********
46
47
48Basic attributes
49----------------
50
51All Widget types share some basic attributes:
52
53- Position
54- Size
55- Parent
56- Styles
57- Events it emits
58- Flags like *Clickable*, *Scollable*, etc.
59- Etc.
60
61You can set/get these attributes with ``lv_obj_set_...`` and
62``lv_obj_get_...`` functions. For example:
63
64.. code-block:: c
65
66   /* Set basic Widget attributes */
67   lv_obj_set_size(btn1, 100, 50);   /* Set a button's size */
68   lv_obj_set_pos(btn1, 20,30);      /* Set a button's position */
69
70For complete details on position, size, coordinates and layouts, see :ref:`coord`.
71
72
73Widget-specific attributes
74--------------------------
75
76The Widget types have special attributes as well. For example, a slider has
77
78- Minimum and maximum values
79- Current value
80
81For these special attributes, every Widget type may have unique API
82functions. For example for a slider:
83
84.. code-block:: c
85
86   /* Set slider specific attributes */
87   lv_slider_set_range(slider1, 0, 100);               /* Set the min. and max. values */
88   lv_slider_set_value(slider1, 40, LV_ANIM_ON);       /* Set the current value (position) */
89
90The API of the widgets is described in their
91:ref:`Documentation <widgets>` but you can also check the respective
92header files (e.g. *widgets/lv_slider.h*)
93
94
95.. _lv_obj_parents_and_children:
96
97Parents and children
98--------------------
99
100A Widget's parent is set when the widget is created --- the parent is passed to the
101creation function.
102
103To get a Widget's current parent, use :cpp:expr:`lv_obj_get_parent(widget)`.
104
105You can move the Widget to a new parent with :cpp:expr:`lv_obj_set_parent(widget, new_parent)`.
106
107To get a specific child of a parent use :cpp:expr:`lv_obj_get_child(parent, idx)`.
108Some examples for ``idx``:
109
110- ``0`` get the child created first
111- ``1`` get the child created second
112- ``-1`` get the child created last
113
114You can iterate through a parent Widget's children like this:
115
116.. code-block:: c
117
118    uint32_t i;
119    for(i = 0; i < lv_obj_get_child_count(parent); i++) {
120        lv_obj_t * child = lv_obj_get_child(parent, i);
121        /* Do something with child. */
122    }
123
124:cpp:expr:`lv_obj_get_index(widget)` returns the index of the Widget in its parent.
125It is equivalent to the number of older children in the parent.
126
127You can bring a Widget to the foreground or send it to the background with
128:cpp:expr:`lv_obj_move_foreground(widget)` and :cpp:expr:`lv_obj_move_background(widget)`.
129
130You can change the index of a Widget in its parent using :cpp:expr:`lv_obj_move_to_index(widget, index)`.
131
132You can swap the position of two Widgets with :cpp:expr:`lv_obj_swap(widget1, widget2)`.
133
134To get a Widget's Screen (highest-level parent) use :cpp:expr:`lv_obj_get_screen(widget)`.
135
136
137
138.. _widget_working_mechanisms:
139
140Working Mechanisms
141******************
142
143Parent-child structure
144----------------------
145
146A parent Widget can be considered as the container of its children.  Every Widget has
147exactly one parent Widget (except Screens), but a parent Widget can have any number
148of children.  There is no limitation for the type of the parent but there are Widgets
149which are typically a parent (e.g. button) or a child (e.g. label).
150
151
152
153Moving together
154---------------
155
156If the position of a parent changes, the children will move along with
157it. Therefore, all positions are relative to the parent.
158
159.. image:: /misc/par_child1.png
160
161.. code-block:: c
162
163   lv_obj_t * parent = lv_obj_create(lv_screen_active());  /* Create a parent Widget on current screen */
164   lv_obj_set_size(parent, 100, 80);                       /* Set size of parent */
165
166   lv_obj_t * obj1 = lv_obj_create(parent);                /* Create a Widget on previously created parent Widget */
167   lv_obj_set_pos(widget1, 10, 10);                        /* Set position of new Widget */
168
169Modify the position of the parent:
170
171.. image:: /misc/par_child2.png
172
173.. code-block:: c
174
175   lv_obj_set_pos(parent, 50, 50); /* Move the parent. The child will move with it. */
176
177(For simplicity the adjusting of colors of the Widgets is not shown in
178the example.)
179
180Visibility only on the parent
181-----------------------------
182
183If a child is partially or fully outside its parent then the parts
184outside will not be visible.
185
186.. image:: /misc/par_child3.png
187
188.. code-block:: c
189
190   lv_obj_set_x(widget1, -30);    /* Move the child a little bit off the parent */
191
192This behavior can be overwritten with
193:cpp:expr:`lv_obj_add_flag(widget, LV_OBJ_FLAG_OVERFLOW_VISIBLE)` which allow the
194children to be drawn out of the parent. In addition to this, you must register
195the following event callback (this was not required in previous versions).
196
197Note: ``ext_width`` should be the maximum absolute width the children will be
198drawn within.
199
200.. code-block:: c
201
202    static void ext_draw_size_event_cb(lv_event_t * e)
203    {
204        lv_event_set_ext_draw_size(e, 30); /*Set 30px extra draw area around the widget*/
205    }
206
207Create and delete Widgets
208-------------------------
209
210In LVGL, Widgets can be created and deleted dynamically at run time. It
211means only the currently created (existing) Widgets consume RAM.
212
213This allows for the creation of a screen just when a button is clicked
214to open it, and for deletion of screens when a new screen is loaded.
215
216UIs can be created based on the current environment of the device. For
217example one can create meters, charts, bars and sliders based on the
218currently attached sensors.
219
220Every widget has its own **create** function with a prototype like this:
221
222.. code-block:: c
223
224   lv_obj_t * lv_<widget>_create(lv_obj_t * parent, <other parameters if any>);
225
226Typically, the create functions only have a ``parent`` parameter telling
227them on which Widget to create the new Widget.
228
229The return value is a pointer to the created Widget with :cpp:type:`lv_obj_t` ``*``
230type.
231
232There is a common **delete** function for all Widget types. It deletes
233the Widget and all of its children.
234
235.. code-block:: c
236
237   void lv_obj_delete(lv_obj_t * widget);
238
239:cpp:func:`lv_obj_delete` will delete the Widget immediately. If for any reason you
240can't delete the Widget immediately you can use
241:cpp:expr:`lv_obj_delete_async(widget)` which will perform the deletion on the next
242call of :cpp:func:`lv_timer_handler`. This is useful e.g. if you want to
243delete the parent of a Widget in the child's :cpp:enumerator:`LV_EVENT_DELETE`
244handler.
245
246You can remove all the children of a Widget (but not the Widget itself)
247using :cpp:expr:`lv_obj_clean(widget)`.
248
249You can use :cpp:expr:`lv_obj_delete_delayed(widget, 1000)` to delete a Widget after
250some time. The delay is expressed in milliseconds.
251
252Sometimes you're not sure whether a Widget was deleted and you need some way to
253check if it's still "alive". Anytime before the Widget is deleted, you can use
254cpp:expr:`lv_obj_null_on_delete(&widget)` to cause your Widget pointer to be set to ``NULL``
255when the Widget is deleted.
256
257Make sure the pointer variable itself stays valid until the Widget is deleted. Here
258is an example:
259
260.. code:: c
261
262   void some_timer_callback(lv_timer_t * t)
263   {
264      static lv_obj_t * my_label;
265      if(my_label == NULL) {
266         my_label = lv_label_create(lv_screen_active());
267         lv_obj_delete_delayed(my_label, 1000);
268         lv_obj_null_on_delete(&my_label);
269      }
270      else {
271         lv_obj_set_x(my_label, lv_obj_get_x(my_label) + 1);
272      }
273   }
274
275
276
277.. _screens:
278
279Screens
280*******
281
282What are Screens?
283-----------------
284
285Not to be confused with a :ref:`display`, Screens are simply any Widget created
286without a parent (i.e. passing NULL for the ``parent`` argument during creation).  As
287such, they form the "root" of a Widget Tree.
288
289Normally the Base Widget is used for this purpose since it has all the features most
290Screens need.  But an :ref:`lv_image` Widget can also be used to create a wallpaper
291background for the Widget Tree.
292
293All Screens:
294
295- are automatically attached to the :ref:`default_display` current when the Screen
296  was created;
297- automatically occupy the full area of the associated display;
298- cannot be moved, i.e. functions such as :cpp:func:`lv_obj_set_pos` and
299  :cpp:func:`lv_obj_set_size` cannot be used on screens.
300
301Each :ref:`display` object can have multiple screens associated with it, but not vice
302versa.  Thus the relationship::
303
304       Display
305          |
306         --- (one or more)
307         /|\
308    Screen Widgets  (root of a Widget Tree)
309          |
310          O  (zero or more)
311         /|\
312    Child Widgets
313
314
315Creating Screens
316----------------
317
318Screens are created like this:
319
320.. code-block:: c
321
322   lv_obj_t * scr1 = lv_obj_create(NULL);
323
324Screens can be deleted with :cpp:expr:`lv_obj_delete(scr)`, but be sure you do not
325delete the :ref:`active_screen`.
326
327
328.. _active_screen:
329
330Active Screen
331-------------
332While each :ref:`display` object can have any number of Screens Widgets associated
333with it, only one of those Screens is considered "Active" at any given time.  That
334Screen is referred to as the Display's "Active Screen".  For this reason, only one
335Screen and its child Widgets will ever be shown on a display at one time.
336
337When each :ref:`display` object was created, a default screen was created with it and
338set as its "Active Screen".
339
340To get a pointer to the "Active Screen", call :cpp:func:`lv_screen_active`.
341
342To set a Screen to be the "Active Screen", call :cpp:func:`lv_screen_load` or
343:cpp:func:`lv_screen_load_anim`.
344
345
346.. _loading_screens:
347
348Loading Screens
349---------------
350
351To load a new screen, use :cpp:expr:`lv_screen_load(scr1)`.  This sets ``scr1`` as
352the Active Screen.
353
354Load Screen with Animation
355^^^^^^^^^^^^^^^^^^^^^^^^^^
356
357A new screen can be loaded with animation by using
358:cpp:expr:`lv_screen_load_anim(scr, transition_type, time, delay, auto_del)`. The
359following transition types exist:
360
361- :cpp:enumerator:`LV_SCR_LOAD_ANIM_NONE`: Switch immediately after ``delay`` milliseconds
362- :cpp:enumerator:`LV_SCR_LOAD_ANIM_OVER_LEFT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_OVER_RIGHT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_OVER_TOP` and :cpp:enumerator:`LV_SCR_LOAD_ANIM_OVER_BOTTOM`: Move the new screen over the current towards the given direction
363- :cpp:enumerator:`LV_SCR_LOAD_ANIM_OUT_LEFT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_OUT_RIGHT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_OUT_TOP` and :cpp:enumerator:`LV_SCR_LOAD_ANIM_OUT_BOTTOM`: Move out the old screen over the current towards the given direction
364- :cpp:enumerator:`LV_SCR_LOAD_ANIM_MOVE_LEFT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_MOVE_RIGHT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_MOVE_TOP` and :cpp:enumerator:`LV_SCR_LOAD_ANIM_MOVE_BOTTOM`: Move both the current and new screens towards the given direction
365- :cpp:enumerator:`LV_SCR_LOAD_ANIM_FADE_IN` and :cpp:enumerator:`LV_SCR_LOAD_ANIM_FADE_OUT`: Fade the new screen over the old screen, or vice versa
366
367Setting ``auto_del`` to ``true`` will automatically delete the old
368screen when the animation is finished.
369
370The new screen will become active (returned by :cpp:func:`lv_screen_active`) when
371the animation starts after ``delay`` time. All inputs are disabled
372during the screen animation.
373
374
375.. _layers_overview:
376
377Layers
378------
379
380When an ``lv_display_t`` object is created, 4 Screens (layers) are created and
381attached to it.
382
3831.  Bottom Layer
3842.  Active Screen
3853.  Top Layer
3864.  System Layer
387
3881, 3 and 4 are independent of the :ref:`active_screen` and they will be shown (if
389they contain anything that is visible) regardless of which screen is the Active
390Screen.  See :ref:`screen_layers` for more information.
391
392
393.. _transparent_screens:
394
395Transparent Screens
396-------------------
397
398Usually, the opacity of the Screen is :cpp:enumerator:`LV_OPA_COVER` to provide a
399solid background for its children. If this is not the case (opacity <
400100%) the display's ``bottom_layer`` will be visible.  If the bottom layer's
401opacity is also not :cpp:enumerator:`LV_OPA_COVER` LVGL will have no solid background
402to draw.
403
404This configuration (transparent Screen) could be useful to create, for example,
405on-screen display (OSD) menus where a video is played on a different hardware layer
406of the display panel, and a menu is overlaid on a higher layer.
407
408To properly render a UI on a transparent Screen the Display's color format needs to
409be set to one with an alpha channel (for example LV_COLOR_FORMAT_ARGB8888).
410
411In summary, to enable transparent screens and displays for OSD menu-like UIs:
412
413- Set the screen's ``bg_opa`` to transparent:
414  :cpp:expr:`lv_obj_set_style_bg_opa(lv_screen_active(), LV_OPA_TRANSP, LV_PART_MAIN)`
415- Set the bottom layer's ``bg_opa`` to transparent:
416  :cpp:expr:`lv_obj_set_style_bg_opa(lv_layer_bottom(), LV_OPA_TRANSP, LV_PART_MAIN)`
417- Set a color format with alpha channel. E.g.
418  :cpp:expr:`lv_display_set_color_format(disp, LV_COLOR_FORMAT_ARGB8888)`
419
420
421
422.. _widget_parts:
423
424Parts
425*****
426
427The widgets are built from multiple parts. For example a
428:ref:`Base Widget <base_widget>` uses the main and scrollbar parts but a
429:ref:`Slider <lv_slider>` uses the main, indicator and knob parts.
430Parts are similar to *pseudo-elements* in CSS.
431
432The following predefined parts exist in LVGL:
433
434- :cpp:enumerator:`LV_PART_MAIN`: A background like rectangle
435- :cpp:enumerator:`LV_PART_SCROLLBAR`: The scrollbar(s)
436- :cpp:enumerator:`LV_PART_INDICATOR`: Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox
437- :cpp:enumerator:`LV_PART_KNOB`: Like a handle to grab to adjust the value
438- :cpp:enumerator:`LV_PART_SELECTED`: Indicate the currently selected option or section
439- :cpp:enumerator:`LV_PART_ITEMS`: Used if the widget has multiple similar elements (e.g. table cells)
440- :cpp:enumerator:`LV_PART_CURSOR`: Mark a specific place e.g. text area's or chart's cursor
441- :cpp:enumerator:`LV_PART_CUSTOM_FIRST`: Custom parts can be added from here.
442
443The main purpose of parts is to allow styling the "components" of the
444widgets. They are described in more detail in the
445:ref:`Style overview <styles>` section.
446
447
448
449.. _widget_states:
450
451States
452******
453
454The Widget can be in a combination of the following states:
455
456- :cpp:enumerator:`LV_STATE_DEFAULT`: Normal, released state
457- :cpp:enumerator:`LV_STATE_CHECKED`: Toggled or checked state
458- :cpp:enumerator:`LV_STATE_FOCUSED`: Focused via keypad or encoder or clicked via touchpad/mouse
459- :cpp:enumerator:`LV_STATE_FOCUS_KEY`: Focused via keypad or encoder but not via touchpad/mouse
460- :cpp:enumerator:`LV_STATE_EDITED`: Edit by an encoder
461- :cpp:enumerator:`LV_STATE_HOVERED`: Hovered by mouse (not supported now)
462- :cpp:enumerator:`LV_STATE_PRESSED`: Being pressed
463- :cpp:enumerator:`LV_STATE_SCROLLED`: Being scrolled
464- :cpp:enumerator:`LV_STATE_DISABLED`: Disabled state
465- :cpp:enumerator:`LV_STATE_USER_1`: Custom state
466- :cpp:enumerator:`LV_STATE_USER_2`: Custom state
467- :cpp:enumerator:`LV_STATE_USER_3`: Custom state
468- :cpp:enumerator:`LV_STATE_USER_4`: Custom state
469
470The states are usually automatically changed by the library as the user
471interacts with a Widget (presses, releases, focuses, etc.). However,
472the states can be changed manually as well. To set or clear given state (but
473leave the other states untouched) use
474:cpp:expr:`lv_obj_add_state(widget, LV_STATE_...)` and
475:cpp:expr:`lv_obj_remove_state(widget, LV_STATE_...)`.  In both cases OR-ed state
476values can be used as well. E.g.
477:cpp:expr:`lv_obj_add_state(widget, part, LV_STATE_PRESSED | LV_PRESSED_CHECKED)`.
478
479To learn more about the states, read the related section of
480:ref:`styles_overview`.
481
482
483
484.. _lv_obj_flags:
485
486Flags
487*****
488
489There are some Widget attributes which can be enabled/disabled by
490:cpp:expr:`lv_obj_add_flag(widget, LV_OBJ_FLAG_...)` and
491:cpp:expr:`lv_obj_remove_flag(widget, LV_OBJ_FLAG_...)`.
492
493-  :cpp:enumerator:`LV_OBJ_FLAG_HIDDEN` Make the Widget hidden. (Like it wasn't there at all)
494-  :cpp:enumerator:`LV_OBJ_FLAG_CLICKABLE` Make the Widget clickable by input devices
495-  :cpp:enumerator:`LV_OBJ_FLAG_CLICK_FOCUSABLE` Add focused state to the Widget when clicked
496-  :cpp:enumerator:`LV_OBJ_FLAG_CHECKABLE` Toggle checked state when the Widget is clicked
497-  :cpp:enumerator:`LV_OBJ_FLAG_SCROLLABLE` Make the Widget scrollable
498-  :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_ELASTIC` Allow scrolling inside but with slower speed
499-  :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_MOMENTUM` Make the Widget scroll further when "thrown"
500-  :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_ONE` Allow scrolling only one snappable children
501-  :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_CHAIN_HOR` Allow propagating the horizontal scroll to a parent
502-  :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_CHAIN_VER` Allow propagating the vertical scroll to a parent
503-  :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_CHAIN` Simple packaging for (:cpp:expr:`LV_OBJ_FLAG_SCROLL_CHAIN_HOR | LV_OBJ_FLAG_SCROLL_CHAIN_VER`)
504-  :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_ON_FOCUS` Automatically scroll Widget to make it visible when focused
505-  :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_WITH_ARROW` Allow scrolling the focused Widget with arrow keys
506-  :cpp:enumerator:`LV_OBJ_FLAG_SNAPPABLE` If scroll snap is enabled on the parent it can snap to this Widget
507-  :cpp:enumerator:`LV_OBJ_FLAG_PRESS_LOCK` Keep the Widget pressed even if the press slid from the Widget
508-  :cpp:enumerator:`LV_OBJ_FLAG_EVENT_BUBBLE` Propagate the events to the parent as well
509-  :cpp:enumerator:`LV_OBJ_FLAG_GESTURE_BUBBLE` Propagate the gestures to the parent
510-  :cpp:enumerator:`LV_OBJ_FLAG_ADV_HITTEST` Allow performing more accurate hit (click) test. E.g. accounting for rounded corners
511-  :cpp:enumerator:`LV_OBJ_FLAG_IGNORE_LAYOUT` Make the Widget not positioned by the layouts
512-  :cpp:enumerator:`LV_OBJ_FLAG_FLOATING` Do not scroll the Widget when the parent scrolls and ignore layout
513-  :cpp:enumerator:`LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS` Enable sending ``LV_EVENT_DRAW_TASK_ADDED`` events
514-  :cpp:enumerator:`LV_OBJ_FLAG_OVERFLOW_VISIBLE` Do not clip the children's content to the parent's boundary
515-  :cpp:enumerator:`LV_OBJ_FLAG_FLEX_IN_NEW_TRACK` Start a new flex track on this item
516-  :cpp:enumerator:`LV_OBJ_FLAG_LAYOUT_1` Custom flag, free to use by layouts
517-  :cpp:enumerator:`LV_OBJ_FLAG_LAYOUT_2` Custom flag, free to use by layouts
518-  :cpp:enumerator:`LV_OBJ_FLAG_WIDGET_1` Custom flag, free to use by widget
519-  :cpp:enumerator:`LV_OBJ_FLAG_WIDGET_2` Custom flag, free to use by widget
520-  :cpp:enumerator:`LV_OBJ_FLAG_USER_1` Custom flag, free to use by user
521-  :cpp:enumerator:`LV_OBJ_FLAG_USER_2` Custom flag, free to use by user
522-  :cpp:enumerator:`LV_OBJ_FLAG_USER_3` Custom flag, free to use by user
523-  :cpp:enumerator:`LV_OBJ_FLAG_USER_4` Custom flag, free to use by user
524
525Some examples:
526
527.. code-block:: c
528
529    /* Hide on Widget */
530    lv_obj_add_flag(widget, LV_OBJ_FLAG_HIDDEN);
531
532    /* Make a Widget non-clickable */
533    lv_obj_remove_flag(widget, LV_OBJ_FLAG_CLICKABLE);
534
535
536
537.. _lv_obj_events:
538
539Base-Widget Events
540******************
541
542.. _widget_events:
543
544Events from Input Devices
545-------------------------
546-  :cpp:enumerator:`LV_EVENT_PRESSED`              Widget has been pressed.
547-  :cpp:enumerator:`LV_EVENT_PRESSING`             Widget is being pressed (sent continuously while pressing).
548-  :cpp:enumerator:`LV_EVENT_PRESS_LOST`           Widget is still being pressed but slid cursor/finger off Widget.
549-  :cpp:enumerator:`LV_EVENT_SHORT_CLICKED`        Widget was pressed for a short period of time, then released. Not sent if scrolled.
550-  :cpp:enumerator:`LV_EVENT_SINGLE_CLICKED`       Sent for first short click within a small distance and short time.
551-  :cpp:enumerator:`LV_EVENT_DOUBLE_CLICKED`       Sent for second short click within small distance and short time.
552-  :cpp:enumerator:`LV_EVENT_TRIPLE_CLICKED`       Sent for third short click within small distance and short time.
553-  :cpp:enumerator:`LV_EVENT_LONG_PRESSED`         Object has been pressed for at least `long_press_time`.  Not sent if scrolled.
554-  :cpp:enumerator:`LV_EVENT_LONG_PRESSED_REPEAT`  Sent after `long_press_time` in every `long_press_repeat_time` ms.  Not sent if scrolled.
555-  :cpp:enumerator:`LV_EVENT_CLICKED`              Sent on release if not scrolled (regardless to long press).
556-  :cpp:enumerator:`LV_EVENT_RELEASED`             Sent in every cases when Widget has been released.
557-  :cpp:enumerator:`LV_EVENT_SCROLL_BEGIN`         Scrolling begins. The event parameter is a pointer to the animation of the scroll. Can be modified.
558-  :cpp:enumerator:`LV_EVENT_SCROLL_THROW_BEGIN`   Received when scrolling begins.
559-  :cpp:enumerator:`LV_EVENT_SCROLL_END`           Scrolling ended.
560-  :cpp:enumerator:`LV_EVENT_SCROLL`               Scrolling
561-  :cpp:enumerator:`LV_EVENT_GESTURE`              A gesture is detected. Get gesture with `lv_indev_get_gesture_dir(lv_indev_active());`
562-  :cpp:enumerator:`LV_EVENT_KEY`                  A key is sent to Widget. Get key with `lv_indev_get_key(lv_indev_active());`
563-  :cpp:enumerator:`LV_EVENT_FOCUSED`              Widget received focus,
564-  :cpp:enumerator:`LV_EVENT_DEFOCUSED`            Widget's focus has been lost.
565-  :cpp:enumerator:`LV_EVENT_LEAVE`                Widget's focus has been lost but is still selected.
566-  :cpp:enumerator:`LV_EVENT_HIT_TEST`             Perform advanced hit-testing.
567
568Special Events
569--------------
570-  :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` when the :cpp:enumerator:`LV_OBJ_FLAG_CHECKABLE` flag is
571   enabled and the Widget was clicked (on transition to/from the checked state)
572
573Drawing Events
574--------------
575-  :cpp:enumerator:`LV_EVENT_DRAW_MAIN`            Performing drawing of main part
576-  :cpp:enumerator:`LV_EVENT_DRAW_MAIN_BEGIN`      Starting drawing of main part
577-  :cpp:enumerator:`LV_EVENT_DRAW_MAIN_END`        Finishing drawing of main part
578-  :cpp:enumerator:`LV_EVENT_DRAW_POST`            Perform the post draw phase (when all children are drawn)
579-  :cpp:enumerator:`LV_EVENT_DRAW_POST_BEGIN`      Starting the post draw phase (when all children are drawn)
580-  :cpp:enumerator:`LV_EVENT_DRAW_POST_END`        Finishing the post draw phase (when all children are drawn)
581
582Other Events
583------------
584-  :cpp:enumerator:`LV_EVENT_DELETE`               Object is being deleted
585-  :cpp:enumerator:`LV_EVENT_CHILD_CHANGED`        Child was removed, added, or its size, position were changed
586-  :cpp:enumerator:`LV_EVENT_CHILD_CREATED`        Child was created, always bubbles up to all parents
587-  :cpp:enumerator:`LV_EVENT_CHILD_DELETED`        Child was deleted, always bubbles up to all parents
588-  :cpp:enumerator:`LV_EVENT_SIZE_CHANGED`         Object coordinates/size have changed
589-  :cpp:enumerator:`LV_EVENT_STYLE_CHANGED`        Object's style has changed
590-  :cpp:enumerator:`LV_EVENT_LAYOUT_CHANGED`       A child's position has changed due to a layout recalculation (when container has flex or grid layout style)
591-  :cpp:enumerator:`LV_EVENT_GET_SELF_SIZE`        Get internal size of a widget
592
593.. admonition::  Further Reading
594
595    Learn more about :ref:`events`.
596
597
598
599.. _lv_obj_keys:
600
601Keys
602****
603
604If :cpp:enumerator:`LV_OBJ_FLAG_CHECKABLE` is enabled, :cpp:enumerator:`LV_KEY_RIGHT` and
605:cpp:enumerator:`LV_KEY_UP` make the Widget checked, and :cpp:enumerator:`LV_KEY_LEFT` and
606:cpp:enumerator:`LV_KEY_DOWN` make it unchecked.
607
608If :cpp:enumerator:`LV_OBJ_FLAG_SCROLLABLE` is enabled, but the Widget is not editable
609(as declared by the widget class), the arrow keys (:cpp:enumerator:`LV_KEY_UP`,
610:cpp:enumerator:`LV_KEY_DOWN`, :cpp:enumerator:`LV_KEY_LEFT`, :cpp:enumerator:`LV_KEY_RIGHT`) scroll the Widget.
611If the Widget can only scroll vertically, :cpp:enumerator:`LV_KEY_LEFT` and
612:cpp:enumerator:`LV_KEY_RIGHT` will scroll up/down instead, making it compatible with
613an encoder input device. See :ref:`Input devices overview <indev>` for
614more on encoder behaviors and the edit mode.
615
616.. admonition::  Further Reading
617
618    Learn more about :ref:`indev_keys`.
619
620
621
622
623
624.. _widget_snapshot:
625
626Snapshot
627********
628
629A snapshot image can be generated for a Widget together with its
630children. Check details in :ref:`snapshot`.
631
632
633
634Example
635*******
636
637.. include:: ../../examples/widgets/obj/index.rst
638
639
640
641.. _lv_obj_api:
642
643API
644***
645