acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

scroll.md (9127B)

      1 ```eval_rst
      2 .. include:: /header.rst
      3 :github_url: |github_link_base|/overview/scroll.md
      4 ```
      5 # Scroll
      6 
      7 ## Overview
      8 In LVGL scrolling works very intuitively: if an object is outside its parent content area (the size without padding), the parent becomes scrollable and scrollbar(s) will appear. That's it.
      9 
     10 Any object can be scrollable including `lv_obj_t`, `lv_img`, `lv_btn`, `lv_meter`, etc
     11 
     12 The object can either be scrolled horizontally or vertically in one stroke; diagonal scrolling is not possible.
     13 
     14 ### Scrollbar
     15 
     16 #### Mode
     17 Scrollbars are displayed according to a configured `mode`. The following `mode`s exist:
     18 - `LV_SCROLLBAR_MODE_OFF`  Never show the scrollbars
     19 - `LV_SCROLLBAR_MODE_ON`  Always show the scrollbars
     20 - `LV_SCROLLBAR_MODE_ACTIVE` Show scroll bars while an object is being scrolled
     21 - `LV_SCROLLBAR_MODE_AUTO`  Show scroll bars when the content is large enough to be scrolled
     22 
     23 `lv_obj_set_scrollbar_mode(obj, LV_SCROLLBAR_MODE_...)` sets the scrollbar mode on an object.
     24 
     25 
     26 #### Styling
     27 The scrollbars have their own dedicated part, called `LV_PART_SCROLLBAR`. For example a scrollbar can turn to red like this:
     28 ```c
     29 static lv_style_t style_red;
     30 lv_style_init(&style_red);
     31 lv_style_set_bg_color(&style_red, lv_color_red());
     32 
     33 ...
     34 
     35 lv_obj_add_style(obj, &style_red, LV_PART_SCROLLBAR);
     36 ```
     37 
     38 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.
     39 This code makes the scrollbar blue when the object is scrolled:
     40 ```c
     41 static lv_style_t style_blue;
     42 lv_style_init(&style_blue);
     43 lv_style_set_bg_color(&style_blue, lv_color_blue());
     44 
     45 ...
     46 
     47 lv_obj_add_style(obj, &style_blue, LV_STATE_SCROLLED | LV_PART_SCROLLBAR);
     48 ```
     49 
     50 If the base direction of the `LV_PART_SCROLLBAR` is RTL (`LV_BASE_DIR_RTL`) the vertical scrollbar will be placed on the left.
     51 Note that, the `base_dir` style property is inherited. Therefore, it can be set directly on the `LV_PART_SCROLLBAR` part of an object
     52 or on the object's or any parent's main part to make a scrollbar inherit the base direction.
     53 
     54 `pad_left/right/top/bottom` sets the spacing around the scrollbars and `width` sets the scrollbar's width.
     55 
     56 ### Events
     57 The following events are related to scrolling:
     58 - `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.
     59 - `LV_EVENT_SCROLL_END` Scrolling ends.
     60 - `LV_EVENT_SCROLL` Scroll happened. Triggered on every position change.
     61 Scroll events
     62 
     63 ## Basic example
     64 TODO
     65 
     66 ## Features of scrolling
     67 
     68 Besides, managing "normal" scrolling there are many interesting and useful additional features.
     69 
     70 
     71 ### Scrollable
     72 
     73 It's possible to make an object non-scrollable with `lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE)`.
     74 
     75 Non-scrollable objects can still propagate the scrolling (chain) to their parents.
     76 
     77 The direction in which scrolling happens can be controlled by `lv_obj_set_scroll_dir(obj, LV_DIR_...)`.
     78 The following values are possible for the direction:
     79 - `LV_DIR_TOP` only scroll up
     80 - `LV_DIR_LEFT` only scroll left
     81 - `LV_DIR_BOTTOM` only scroll down
     82 - `LV_DIR_RIGHT` only scroll right
     83 - `LV_DIR_HOR` only scroll horizontally
     84 - `LV_DIR_VER` only scroll vertically
     85 - `LV_DIR_ALL` scroll any directions
     86 
     87 OR-ed values are also possible. E.g. `LV_DIR_TOP | LV_DIR_LEFT`.
     88 
     89 
     90 ### Scroll chain
     91 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.
     92 It continues propagating to the grandparent and grand-grandparents as well.
     93 
     94 The propagation on scrolling is called "scroll chaining" and it can be enabled/disabled with `LV_OBJ_FLAG_SCROLL_CHAIN_HOR/VER` flag.
     95 If chaining is disabled the propagation stops on the object and the parent(s) won't be scrolled.
     96 
     97 ### Scroll momentum
     98 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.
     99 
    100 The scroll momentum can be enabled/disabled with the `LV_OBJ_FLAG_SCROLL_MOMENTUM` flag.
    101 
    102 ### Elastic scroll
    103 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.
    104 
    105 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.
    106 When the object is released the content scrolled in it will be animated back to the valid position.
    107 
    108 ### Snapping
    109 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.
    110 
    111 An object can align snapped children in four ways:
    112 - `LV_SCROLL_SNAP_NONE` Snapping is disabled. (default)
    113 - `LV_SCROLL_SNAP_START` Align the children to the left/top side of a scrolled object
    114 - `LV_SCROLL_SNAP_END` Align the children to the right/bottom side of a scrolled object
    115 - `LV_SCROLL_SNAP_CENTER` Align the children to the center of a scrolled object
    116 
    117 Snap alignment is set with `lv_obj_set_scroll_snap_x/y(obj, LV_SCROLL_SNAP_...)`:
    118 
    119 Under the hood the following happens:
    120 1. User scrolls an object and releases the screen
    121 2. LVGL calculates where the scroll would end considering scroll momentum
    122 3. LVGL finds the nearest scroll point
    123 4. LVGL scrolls to the snap point with an animation
    124 
    125 ### Scroll one
    126 The "scroll one" feature tells LVGL to allow scrolling only one snappable child at a time.
    127 This requires making the children snappable and setting a scroll snap alignment different from `LV_SCROLL_SNAP_NONE`.
    128 
    129 This feature can be enabled by the `LV_OBJ_FLAG_SCROLL_ONE` flag.
    130 
    131 ### Scroll on focus
    132 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.
    133 If the "scroll on focus" feature is enabled LVGL will automatically scroll objects to bring their children into view.
    134 The scrolling happens recursively therefore even nested scrollable objects are handled properly.
    135 The object will be scrolled into view even if it's on a different page of a tabview.
    136 
    137 ## Scroll manually
    138 The following API functions allow manual scrolling of objects:
    139 - `lv_obj_scroll_by(obj, x, y, LV_ANIM_ON/OFF)` scroll by `x` and `y` values
    140 - `lv_obj_scroll_to(obj, x, y, LV_ANIM_ON/OFF)` scroll to bring the given coordinate to the top left corner
    141 - `lv_obj_scroll_to_x(obj, x, LV_ANIM_ON/OFF)` scroll to bring the given coordinate to the left side
    142 - `lv_obj_scroll_to_y(obj, y, LV_ANIM_ON/OFF)` scroll to bring the given coordinate to the top side
    143 
    144 From time to time you may need to retrieve the scroll position of an element, either to restore it later, or to display dynamically some elements according to the current scroll.
    145 Here is an example to see how to combine scroll event and store the scroll top position.
    146 ```c
    147 static int scroll_value = 0;
    148 
    149 static void store_scroll_value_event_cb(lv_event_t* e) {
    150   lv_obj_t* screen = lv_event_get_target(e);
    151   scroll_value = lv_obj_get_scroll_top(screen);
    152   printf("%d pixels are scrolled out on the top\n", scroll_value);
    153 }
    154 
    155 lv_obj_t* container = lv_obj_create(NULL);
    156 lv_obj_add_event_cb(container, store_scroll_value_event_cb, LV_EVENT_SCROLL, NULL);
    157 ```
    158 
    159 Scrool coordinates can be retrieve from differents axes with these functions:
    160 - `lv_obj_get_scroll_x(obj)` Get the `x` coordinate of object
    161 - `lv_obj_get_scroll_y(obj)` Get the `y` coordinate of object
    162 - `lv_obj_get_scroll_top(obj)` Get the scroll coordinate from the top
    163 - `lv_obj_get_scroll_bottom(obj)` Get the scroll coordinate from the bottom
    164 - `lv_obj_get_scroll_left(obj)` Get the scroll coordinate from the left
    165 - `lv_obj_get_scroll_right(obj)` Get the scroll coordinate from the right
    166 
    167 ## Self size
    168 
    169 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.
    170 
    171 In short, self size establishes the size of an object's content. To understand it better take the example of a table.
    172 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.
    173 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.
    174 
    175 This means not only the children can make an object scrollable but a larger self size will too.
    176 
    177 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:
    178 ```c
    179 if(event_code == LV_EVENT_GET_SELF_SIZE) {
    180 	lv_point_t * p = lv_event_get_param(e);
    181 
    182   //If x or y < 0 then it doesn't neesd to be calculated now
    183   if(p->x >= 0) {
    184     p->x = 200;	//Set or calculate the self width
    185   }
    186 
    187   if(p->y >= 0) {
    188     p->y = 50;	//Set or calculate the self height
    189   }
    190 }
    191 ```
    192 
    193 ## Examples
    194 
    195 ```eval_rst
    196 
    197 .. include:: ../../examples/scroll/index.rst
    198 
    199 ```