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