2021-04-19 22:10:01 +02:00
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/overview/scroll.md
```
# Scroll
## Overview
2021-04-21 12:30:52 +02:00
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.
2021-04-19 22:10:01 +02:00
2021-04-21 12:30:52 +02:00
Any object can be scrollable including `lv_obj_t` , `lv_img` , `lv_btn` , `lv_meter` , etc
2021-06-09 15:10:35 +02:00
The object can either be scrolled either horizontally or vertically in one stroke; diagonal scrolling is not possible.
2021-04-21 12:30:52 +02:00
### Scrollbar
#### Mode
The scrollbars are displayed according to the set `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_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.
#### Styling
2021-06-09 15:10:35 +02:00
The scrollbars have their own dedicated part, called `LV_PART_SCROLLBAR` . For example a scrollbar can turned to red like this:
2021-04-21 12:30:52 +02:00
```c
static lv_style_t style_red;
lv_style_init(&style_red);
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.
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_obj_add_style(obj, & style_blue, LV_STATE_SCROLLED | LV_PART_SCROLLBAR);
```
2021-04-19 22:10:01 +02:00
2021-08-19 12:51:29 +02:00
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 inhertied. 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.
2021-04-19 22:10:01 +02:00
### Events
2021-04-21 12:30:52 +02:00
The following events are related to scrolling:
- `LV_EVENT_SCROLL_BEGIN` Scrolling begins
- `LV_EVENT_SCROLL_END` Scrolling ends
- `LV_EVENT_SCROLL` Scroll happened. Triggered on every position change.
2021-04-19 22:10:01 +02:00
Scroll events
## Basic example
2021-04-21 12:30:52 +02:00
TODO
2021-04-19 22:10:01 +02:00
## Features of scrolling
2021-04-21 12:30:52 +02:00
Besides managing "normal" scrolling there are many interesting and useful additional features too.
2021-04-19 22:10:01 +02:00
### Scrollable
2021-05-18 10:35:10 +08:00
It's possible to make an object non-scrollable with `lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE)` .
2021-04-21 12:30:52 +02:00
Non-scrollable object can still propagate the scrolling (chain) to the parents.
The direction in which scrolling can happen 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
- `LV_DIR_BOTTOM` only scroll down
- `LV_DIR_RIGHT` only scroll right
- `LV_DIR_HOR` only scroll horizontally
- `LV_DIR_TOP` only scroll vertically
- `LV_DIR_ALL` scroll any directions
OR-ed values are also possible. E.g. `LV_DIR_TOP | LV_DIR_LEFT` .
2021-04-19 22:10:01 +02:00
### Scroll chain
2021-04-21 12:30:52 +02:00
If an object can't be scrolled further (e.g. it's content has reached the bottom most position) the scrolling is propagated to it's parent. If the parent an be scrolled in that direction than it will be scrolled instead.
2021-06-09 15:10:35 +02:00
It propagets to the grandparent and grand-grandparents too.
2021-04-19 22:10:01 +02:00
2021-06-09 15:10:35 +02:00
The propagation on scrolling is called "scroll chaining" and it can be enabled/disabled with the `LV_OBJ_FLAG_SCROLL_CHAIN` flag.
2021-04-21 12:30:52 +02:00
If chaining is disabled the propagation stops on the object and the parent(s) won't be scrolled.
2021-04-19 22:10:01 +02:00
2021-04-21 12:30:52 +02:00
### Scroll momentum
2021-06-09 15:10:35 +02:00
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.
2021-04-19 22:10:01 +02:00
2021-04-21 12:30:52 +02:00
The scroll momentum can be enabled/disabled with the `LV_OBJ_FLAG_SCROLL_MOMENTUM` flag.
2021-04-19 22:10:01 +02:00
### Elastic scroll
2021-04-21 12:30:52 +02:00
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.
2021-04-19 22:10:01 +02:00
2021-04-21 12:30:52 +02:00
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.
2021-06-09 15:10:35 +02:00
When the object is released the content scrolled in it will be animated back to the valid position.
2021-04-21 12:30:52 +02:00
2021-06-09 15:10:35 +02:00
### Snapping
2021-06-09 16:33:27 +02:00
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.
2021-04-21 12:30:52 +02:00
The object can align the snapped children in 4 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
The alignment can be set with `lv_obj_set_scroll_snap_x/y(obj, LV_SCROLL_SNAP_...)` :
2021-06-09 15:10:35 +02:00
Under the hood the following happens:
2021-04-21 12:30:52 +02:00
1. User scrolls an object and releases the screen
2021-06-09 15:10:35 +02:00
2. LVGL calculates where the scroll would end considering scroll momentum
2021-04-21 12:30:52 +02:00
3. LVGL finds the nearest scroll point
2021-06-09 15:10:35 +02:00
4. LVGL scrolls to the snap point with an animation
2021-04-21 12:30:52 +02:00
### Scroll one
2021-06-09 15:10:35 +02:00
The "scroll one" feature tells LVGL to allow scrolling only one snappable child at a time.
2021-06-09 16:33:27 +02:00
So this requires to make the children snappable and set a scroll snap alignment different from `LV_SCROLL_SNAP_NONE` .
2021-04-21 12:30:52 +02:00
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.
## Scroll manually
The following API functions allow to manually scroll 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
2021-04-19 22:10:01 +02:00
## Self size
2021-04-21 12:30:52 +02:00
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.
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.
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);
//If x or y < 0 then it doesn ' t neesd to be calculated now
if(p->x >= 0) {
p->x = 200; //Set or calculate the self width
}
2021-05-18 10:35:10 +08:00
if(p->y >= 0) {
2021-04-21 12:30:52 +02:00
p->y = 50; //Set or calculate the self height
}
}
```
2021-04-19 22:10:01 +02:00
## Examples
2021-05-26 16:34:25 +02:00
```eval_rst
2021-05-26 16:45:13 +02:00
.. include:: ../../examples/scroll/index.rst
2021-05-26 16:34:25 +02:00
```