Merge branch 'master' of https://github.com/lvgl/lvgl
This commit is contained in:
@@ -34,6 +34,7 @@ PDF version: :download:`LVGL.pdf <LVGL.pdf>`
|
||||
overview/index
|
||||
widgets/index
|
||||
layouts/index
|
||||
others/index
|
||||
CONTRIBUTING
|
||||
CHANGELOG
|
||||
ROADMAP
|
||||
|
||||
BIN
docs/misc/anim-timeline.png
Normal file
BIN
docs/misc/anim-timeline.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 85 KiB |
16
docs/others/index.md
Normal file
16
docs/others/index.md
Normal file
@@ -0,0 +1,16 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/others/index.md
|
||||
```
|
||||
# Others
|
||||
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
snapshot
|
||||
|
||||
```
|
||||
|
||||
67
docs/others/snapshot.md
Normal file
67
docs/others/snapshot.md
Normal file
@@ -0,0 +1,67 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/others/snapshot.md
|
||||
```
|
||||
# Snapshot
|
||||
|
||||
Snapshot provides APIs to take snapshot image for LVGL object together with its children. The image will look exactly like the object.
|
||||
|
||||
## Usage
|
||||
|
||||
Simply call API `lv_snapshot_take` to generate the image descriptor which can be set as image object src using `lv_img_set_src`.
|
||||
|
||||
|
||||
Note, only below color formats are supported for now:
|
||||
- LV_IMG_CF_TRUE_COLOR_ALPHA
|
||||
- LV_IMG_CF_ALPHA_1BIT
|
||||
- LV_IMG_CF_ALPHA_2BIT
|
||||
- LV_IMG_CF_ALPHA_4BIT
|
||||
- LV_IMG_CF_ALPHA_8BIT
|
||||
|
||||
|
||||
### Free the Image
|
||||
The memory `lv_snapshot_take` uses are dynamically allocated using `lv_mem_alloc`. Use API `lv_snapshot_free` to free the memory it takes. This will firstly free memory the image data takes, then the image descriptor.
|
||||
|
||||
|
||||
Take caution to free the snapshot but not delete the image object. Before free the memory, be sure to firstly unlink it from image object, using `lv_img_set_src(NULL)` and `lv_img_cache_invalidate_src(src)`.
|
||||
|
||||
|
||||
Below code snippet explains usage of this API.
|
||||
|
||||
```c
|
||||
void update_snapshot(lv_obj_t * obj, lv_obj_t * img_snapshot)
|
||||
{
|
||||
lv_img_dsc_t* snapshot = (void*)lv_img_get_src(img_snapshot);
|
||||
if(snapshot) {
|
||||
lv_snapshot_free(snapshot);
|
||||
}
|
||||
snapshot = lv_snapshot_take(obj, LV_IMG_CF_TRUE_COLOR_ALPHA);
|
||||
lv_img_set_src(img_snapshot, snapshot);
|
||||
}
|
||||
```
|
||||
|
||||
### Use Existing Buffer
|
||||
If the snapshot needs update now and then, or simply caller provides memory, use API `lv_res_t lv_snapshot_take_to_buf(lv_obj_t * obj, lv_img_cf_t cf, lv_img_dsc_t * dsc, void * buf, uint32_t buff_size);` for this case. It's caller's responsibility to alloc/free the memory.
|
||||
|
||||
|
||||
If snapshot is generated successfully, the image descriptor is updated and image data will be stored to provided `buf`.
|
||||
|
||||
|
||||
Note that snapshot may fail if provided buffer is not enough, which may happen when object size changes. It's recommended to use API `lv_snapshot_buf_size_needed` to check the needed buffer size in byte firstly and resize the buffer accordingly.
|
||||
|
||||
## Example
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/others/snapshot/index.rst
|
||||
|
||||
```
|
||||
## API
|
||||
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_snapshot.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
||||
@@ -104,6 +104,28 @@ The speed is interpreted in _unit/sec_ dimension. For example, `lv_anim_speed_t
|
||||
|
||||
You can delete an animation with `lv_anim_del(var, func)` if you provide the animated variable and its animator function.
|
||||
|
||||
## Timeline
|
||||
Timeline is a collection of multiple Animations, which makes it easy to create complex composite animations.
|
||||
|
||||
Firstly, create the animation element, but don’t call `lv_anim_start()`.
|
||||
|
||||
Secondly, create an animation timeline object, by calling `lv_anim_timeline_create()`.
|
||||
|
||||
Thirdly, add animation elements to the animation timeline, by calling `lv_anim_timeline_add(at, start_time, &a)`. `start_time` is the start time of the animation on the timeline. Note that `start_time` will override the value of `delay`.
|
||||
|
||||
Finally, call `lv_anim_timeline_start(at)` to start the animation timeline.
|
||||
|
||||
It supports forward and backward playback of the entire animation group, using `lv_anim_timeline_set_reverse(at, reverse)`.
|
||||
|
||||
Call the `lv_anim_timeline_set_progress(at, progress)` function to set the state of the object corresponding to the progress of the timeline.
|
||||
|
||||
Call the `lv_anim_timeline_get_playtime(at)` function to get the total duration of the entire animation timeline.
|
||||
|
||||
Call the `lv_anim_timeline_get_reverse(at)` function to get whether to reverse the animation timeline.
|
||||
|
||||
Call the `lv_anim_timeline_del(at)` function to delete the animation timeline.
|
||||
|
||||

|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
@@ -218,3 +218,5 @@ In both cases ORed state values can be used as well. E.g. `lv_obj_add_state(obj,
|
||||
|
||||
To learn more about the states read the related section of the [Style overview](/overview/style).
|
||||
|
||||
## Snapshot
|
||||
A snapshot image could be generated for object together with its children. Check details in [Snapshot](/others/snapshot).
|
||||
|
||||
@@ -123,7 +123,7 @@ indev_drv.read_cb = encoder_with_keys_read;
|
||||
|
||||
...
|
||||
|
||||
bool encoder_with_keys_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
|
||||
void encoder_with_keys_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
|
||||
data->key = last_key(); /*Get the last pressed or released key*/
|
||||
/* use LV_KEY_ENTER for encoder press */
|
||||
if(key_pressed()) data->state = LV_INDEV_STATE_PRESSED;
|
||||
@@ -132,8 +132,6 @@ bool encoder_with_keys_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
|
||||
/* Optionally you can also use enc_diff, if you have encoder*/
|
||||
data->enc_diff = enc_get_new_moves();
|
||||
}
|
||||
|
||||
return false; /*No buffering now so no more data read*/
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -19,6 +19,18 @@ The spangroup object uses span to describe text and text style. so, first we nee
|
||||
|
||||
If spangroup object `mode != LV_SPAN_MODE_FIXED` you must call `lv_spangroup_refr_mode()` after you have modified `span` style(eg:set text, changed the font size, del span).
|
||||
|
||||
### Retreiving a span child
|
||||
Spangroups store their children differently from normal objects, so normal functions for getting children won't work.
|
||||
|
||||
`lv_spangroup_get_child(spangroup, id)` will return a pointer to the child span at index `id`. In addition, `id` can be negative to index from the end of the spangroup where `-1` is the youngest child, `-2` is second youngest, etc.
|
||||
|
||||
e.g. `lv_span_t* span = lv_spangroup_get_child(spangroup, 0)` will return the first child of the spangroup. `lv_span_t* span = lv_spangroup_get_child(spangroup, -1)` will return the last (or most recent) child.
|
||||
|
||||
### Child Count
|
||||
Use the function `lv_spangroup_get_child_cnt(spangroup)` to get back the number of spans the group is maintaining.
|
||||
|
||||
e.g. `uint32_t size = lv_spangroup_get_child_cnt(spangroup)`
|
||||
|
||||
### Text align
|
||||
like label object, the spangroup can be set to one the following modes:
|
||||
- `LV_TEXT_ALIGN_LEFT` Align text to left.
|
||||
|
||||
@@ -10,4 +10,8 @@ Playback animation
|
||||
.. lv_example:: anim/lv_example_anim_2
|
||||
:language: c
|
||||
|
||||
Animation timeline
|
||||
"""""""""""""""""""
|
||||
.. lv_example:: anim/lv_example_anim_timeline_1.c
|
||||
:language: c
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ extern "C" {
|
||||
**********************/
|
||||
void lv_example_anim_1(void);
|
||||
void lv_example_anim_2(void);
|
||||
void lv_example_anim_timeline_1(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
170
examples/anim/lv_example_anim_timeline_1.c
Normal file
170
examples/anim/lv_example_anim_timeline_1.c
Normal file
@@ -0,0 +1,170 @@
|
||||
#include "../lv_examples.h"
|
||||
#if LV_BUILD_EXAMPLES
|
||||
|
||||
static lv_anim_timeline_t * anim_timeline = NULL;
|
||||
|
||||
static lv_obj_t * obj1 = NULL;
|
||||
static lv_obj_t * obj2 = NULL;
|
||||
static lv_obj_t * obj3 = NULL;
|
||||
|
||||
static const lv_coord_t obj_width = 150;
|
||||
static const lv_coord_t obj_height = 200;
|
||||
|
||||
static void set_width(void * var, int32_t v)
|
||||
{
|
||||
lv_obj_set_width((lv_obj_t *)var, v);
|
||||
}
|
||||
|
||||
static void set_height(void * var, int32_t v)
|
||||
{
|
||||
lv_obj_set_height((lv_obj_t *)var, v);
|
||||
}
|
||||
|
||||
static void anim_timeline_create(void)
|
||||
{
|
||||
/* obj1 */
|
||||
lv_anim_t a1;
|
||||
lv_anim_init(&a1);
|
||||
lv_anim_set_var(&a1, obj1);
|
||||
lv_anim_set_values(&a1, 0, obj_width);
|
||||
lv_anim_set_early_apply(&a1, false);
|
||||
lv_anim_set_exec_cb(&a1, (lv_anim_exec_xcb_t)set_width);
|
||||
lv_anim_set_path_cb(&a1, lv_anim_path_overshoot);
|
||||
lv_anim_set_time(&a1, 300);
|
||||
|
||||
lv_anim_t a2;
|
||||
lv_anim_init(&a2);
|
||||
lv_anim_set_var(&a2, obj1);
|
||||
lv_anim_set_values(&a2, 0, obj_height);
|
||||
lv_anim_set_early_apply(&a2, false);
|
||||
lv_anim_set_exec_cb(&a2, (lv_anim_exec_xcb_t)set_height);
|
||||
lv_anim_set_path_cb(&a2, lv_anim_path_ease_out);
|
||||
lv_anim_set_time(&a2, 300);
|
||||
|
||||
/* obj2 */
|
||||
lv_anim_t a3;
|
||||
lv_anim_init(&a3);
|
||||
lv_anim_set_var(&a3, obj2);
|
||||
lv_anim_set_values(&a3, 0, obj_width);
|
||||
lv_anim_set_early_apply(&a3, false);
|
||||
lv_anim_set_exec_cb(&a3, (lv_anim_exec_xcb_t)set_width);
|
||||
lv_anim_set_path_cb(&a3, lv_anim_path_overshoot);
|
||||
lv_anim_set_time(&a3, 300);
|
||||
|
||||
lv_anim_t a4;
|
||||
lv_anim_init(&a4);
|
||||
lv_anim_set_var(&a4, obj2);
|
||||
lv_anim_set_values(&a4, 0, obj_height);
|
||||
lv_anim_set_early_apply(&a4, false);
|
||||
lv_anim_set_exec_cb(&a4, (lv_anim_exec_xcb_t)set_height);
|
||||
lv_anim_set_path_cb(&a4, lv_anim_path_ease_out);
|
||||
lv_anim_set_time(&a4, 300);
|
||||
|
||||
/* obj3 */
|
||||
lv_anim_t a5;
|
||||
lv_anim_init(&a5);
|
||||
lv_anim_set_var(&a5, obj3);
|
||||
lv_anim_set_values(&a5, 0, obj_width);
|
||||
lv_anim_set_early_apply(&a5, false);
|
||||
lv_anim_set_exec_cb(&a5, (lv_anim_exec_xcb_t)set_width);
|
||||
lv_anim_set_path_cb(&a5, lv_anim_path_overshoot);
|
||||
lv_anim_set_time(&a5, 300);
|
||||
|
||||
lv_anim_t a6;
|
||||
lv_anim_init(&a6);
|
||||
lv_anim_set_var(&a6, obj3);
|
||||
lv_anim_set_values(&a6, 0, obj_height);
|
||||
lv_anim_set_early_apply(&a6, false);
|
||||
lv_anim_set_exec_cb(&a6, (lv_anim_exec_xcb_t)set_height);
|
||||
lv_anim_set_path_cb(&a6, lv_anim_path_ease_out);
|
||||
lv_anim_set_time(&a6, 300);
|
||||
|
||||
/* Create anim timeline */
|
||||
anim_timeline = lv_anim_timeline_create();
|
||||
lv_anim_timeline_add(anim_timeline, 0, &a1);
|
||||
lv_anim_timeline_add(anim_timeline, 0, &a2);
|
||||
lv_anim_timeline_add(anim_timeline, 200, &a3);
|
||||
lv_anim_timeline_add(anim_timeline, 200, &a4);
|
||||
lv_anim_timeline_add(anim_timeline, 400, &a5);
|
||||
lv_anim_timeline_add(anim_timeline, 400, &a6);
|
||||
}
|
||||
|
||||
static void btn_run_event_handler(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * btn = lv_event_get_target(e);
|
||||
|
||||
if (!anim_timeline) {
|
||||
anim_timeline_create();
|
||||
}
|
||||
|
||||
bool reverse = lv_obj_has_state(btn, LV_STATE_CHECKED);
|
||||
lv_anim_timeline_set_reverse(anim_timeline, reverse);
|
||||
lv_anim_timeline_start(anim_timeline);
|
||||
}
|
||||
|
||||
static void btn_del_event_handler(lv_event_t * e)
|
||||
{
|
||||
LV_UNUSED(e);
|
||||
if (anim_timeline) {
|
||||
lv_anim_timeline_del(anim_timeline);
|
||||
anim_timeline = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void slider_prg_event_handler(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * slider = lv_event_get_target(e);
|
||||
|
||||
if (!anim_timeline) {
|
||||
anim_timeline_create();
|
||||
}
|
||||
|
||||
int32_t progress = lv_slider_get_value(slider);
|
||||
lv_anim_timeline_set_progress(anim_timeline, progress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an animation timeline
|
||||
*/
|
||||
void lv_example_anim_timeline_1(void)
|
||||
{
|
||||
lv_obj_t * par = lv_scr_act();
|
||||
lv_obj_set_flex_flow(par, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_flex_align(par, LV_FLEX_ALIGN_SPACE_AROUND, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
lv_obj_t * btn_run = lv_btn_create(par);
|
||||
lv_obj_add_event_cb(btn_run, btn_run_event_handler, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
lv_obj_add_flag(btn_run, LV_OBJ_FLAG_IGNORE_LAYOUT);
|
||||
lv_obj_add_flag(btn_run, LV_OBJ_FLAG_CHECKABLE);
|
||||
lv_obj_align(btn_run, LV_ALIGN_TOP_MID, -50, 20);
|
||||
|
||||
lv_obj_t * label_run = lv_label_create(btn_run);
|
||||
lv_label_set_text(label_run, "Run");
|
||||
lv_obj_center(label_run);
|
||||
|
||||
lv_obj_t * btn_del = lv_btn_create(par);
|
||||
lv_obj_add_event_cb(btn_del, btn_del_event_handler, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_add_flag(btn_del, LV_OBJ_FLAG_IGNORE_LAYOUT);
|
||||
lv_obj_align(btn_del, LV_ALIGN_TOP_MID, 50, 20);
|
||||
|
||||
lv_obj_t * label_del = lv_label_create(btn_del);
|
||||
lv_label_set_text(label_del, "Stop");
|
||||
lv_obj_center(label_del);
|
||||
|
||||
lv_obj_t * slider_prg = lv_slider_create(par);
|
||||
lv_obj_add_event_cb(slider_prg, slider_prg_event_handler, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
lv_obj_add_flag(slider_prg, LV_OBJ_FLAG_IGNORE_LAYOUT);
|
||||
lv_obj_align(slider_prg, LV_ALIGN_BOTTOM_MID, 0, -20);
|
||||
lv_slider_set_range(slider_prg, 0, 65535);
|
||||
|
||||
obj1 = lv_obj_create(par);
|
||||
lv_obj_set_size(obj1, obj_width, obj_height);
|
||||
|
||||
obj2 = lv_obj_create(par);
|
||||
lv_obj_set_size(obj2, obj_width, obj_height);
|
||||
|
||||
obj3 = lv_obj_create(par);
|
||||
lv_obj_set_size(obj3, obj_width, obj_height);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -23,6 +23,7 @@ extern "C" {
|
||||
#include "anim/lv_example_anim.h"
|
||||
#include "event/lv_example_event.h"
|
||||
#include "styles/lv_example_style.h"
|
||||
#include "others/lv_example_others.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
|
||||
37
examples/others/lv_example_others.h
Normal file
37
examples/others/lv_example_others.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @file lv_example_others.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_EXAMPLE_OTHERS_H
|
||||
#define LV_EXAMPLE_OTHERS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "snapshot/lv_example_snapshot.h"
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_EX_OTHERS_H*/
|
||||
8
examples/others/snapshot/index.rst
Normal file
8
examples/others/snapshot/index.rst
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
Simple snapshot example
|
||||
"""""""""""""""""""
|
||||
|
||||
.. lv_example:: others/snapshot/lv_example_snapshot_1
|
||||
:language: c
|
||||
|
||||
|
||||
38
examples/others/snapshot/lv_example_snapshot.h
Normal file
38
examples/others/snapshot/lv_example_snapshot.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file lv_example_snapshot.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_EX_SNAPSHOT_H
|
||||
#define LV_EX_SNAPSHOT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_example_snapshot_1(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_EX_GET_STARTED_H*/
|
||||
57
examples/others/snapshot/lv_example_snapshot_1.c
Normal file
57
examples/others/snapshot/lv_example_snapshot_1.c
Normal file
@@ -0,0 +1,57 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_SNAPSHOT && LV_BUILD_EXAMPLES
|
||||
|
||||
static void event_cb(lv_event_t* e)
|
||||
{
|
||||
lv_obj_t * snapshot_obj = lv_event_get_user_data(e);
|
||||
lv_obj_t * img = lv_event_get_target(e);
|
||||
|
||||
if(snapshot_obj) {
|
||||
lv_img_dsc_t* snapshot = (void*)lv_img_get_src(snapshot_obj);
|
||||
if(snapshot){
|
||||
lv_snapshot_free(snapshot);
|
||||
}
|
||||
|
||||
/*Update the snapshot, we know parent of object is the container.*/
|
||||
snapshot = lv_snapshot_take(img->parent, LV_IMG_CF_TRUE_COLOR_ALPHA);
|
||||
if(snapshot == NULL)
|
||||
return;
|
||||
lv_img_set_src(snapshot_obj, snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_example_snapshot_1(void)
|
||||
{
|
||||
LV_IMG_DECLARE(img_star);
|
||||
lv_obj_t * root = lv_scr_act();
|
||||
lv_obj_set_style_bg_color(root, lv_palette_main(LV_PALETTE_LIGHT_BLUE), 0);
|
||||
|
||||
/*Create an image object to show snapshot*/
|
||||
lv_obj_t * snapshot_obj = lv_img_create(root);
|
||||
lv_obj_set_style_bg_color(snapshot_obj, lv_palette_main(LV_PALETTE_PURPLE), 0);
|
||||
lv_obj_set_style_bg_opa(snapshot_obj, LV_OPA_100, 0);
|
||||
lv_img_set_zoom(snapshot_obj, 128);
|
||||
|
||||
/*Create the container and its children*/
|
||||
lv_obj_t * container = lv_obj_create(root);
|
||||
|
||||
lv_obj_align(container, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_set_size(container, 180, 180);
|
||||
lv_obj_set_flex_flow(container, LV_FLEX_FLOW_ROW_WRAP);
|
||||
lv_obj_set_flex_align(container, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
lv_obj_set_style_radius(container, 50, 0);
|
||||
lv_obj_t * img;
|
||||
int i;
|
||||
for(i = 0; i < 4; i++) {
|
||||
img = lv_img_create(container);
|
||||
lv_img_set_src(img, &img_star);
|
||||
lv_obj_set_style_bg_color(img, lv_color_black(), 0);
|
||||
lv_obj_set_style_bg_opa(img, LV_OPA_COVER, 0);
|
||||
lv_obj_set_style_transform_zoom(img, 400, LV_STATE_PRESSED);
|
||||
lv_obj_add_flag(img, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_add_event_cb(img, event_cb, LV_EVENT_PRESSED, snapshot_obj);
|
||||
lv_obj_add_event_cb(img, event_cb, LV_EVENT_RELEASED, snapshot_obj);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
70
examples/others/snapshot/lv_example_snapshot_1.py
Normal file
70
examples/others/snapshot/lv_example_snapshot_1.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import lvgl as lv
|
||||
from imagetools import get_png_info, open_png
|
||||
|
||||
# Register PNG image decoder
|
||||
decoder = lv.img.decoder_create()
|
||||
decoder.info_cb = get_png_info
|
||||
decoder.open_cb = open_png
|
||||
|
||||
# Measure memory usage
|
||||
gc.enable()
|
||||
gc.collect()
|
||||
mem_free = gc.mem_free()
|
||||
|
||||
label = lv.label(lv.scr_act())
|
||||
label.align(lv.ALIGN.BOTTOM_MID, 0, -10)
|
||||
label.set_text(" memory free:" + str(mem_free/1024) + " kB")
|
||||
|
||||
# Create an image from the png file
|
||||
try:
|
||||
with open('../../assets/img_star.png','rb') as f:
|
||||
png_data = f.read()
|
||||
except:
|
||||
print("Could not find img_star.png")
|
||||
sys.exit()
|
||||
|
||||
img_star = lv.img_dsc_t({
|
||||
'data_size': len(png_data),
|
||||
'data': png_data
|
||||
})
|
||||
|
||||
def event_cb(e, snapshot_obj):
|
||||
img = e.get_target()
|
||||
|
||||
if snapshot_obj:
|
||||
# no need to free the old source for snapshot_obj, gc will free it for us.
|
||||
|
||||
# take a new snapshot, overwrite the old one
|
||||
dsc = lv.snapshot_take(img.get_parent(), lv.img.CF.TRUE_COLOR_ALPHA)
|
||||
snapshot_obj.set_src(dsc)
|
||||
|
||||
gc.collect()
|
||||
mem_used = mem_free - gc.mem_free()
|
||||
label.set_text("memory used:" + str(mem_used/1024) + " kB")
|
||||
|
||||
root = lv.scr_act()
|
||||
root.set_style_bg_color(lv.palette_main(lv.PALETTE.LIGHT_BLUE), 0)
|
||||
|
||||
# Create an image object to show snapshot
|
||||
snapshot_obj = lv.img(root)
|
||||
snapshot_obj.set_style_bg_color(lv.palette_main(lv.PALETTE.PURPLE), 0)
|
||||
snapshot_obj.set_style_bg_opa(lv.OPA.COVER, 0)
|
||||
snapshot_obj.set_zoom(128)
|
||||
|
||||
# Create the container and its children
|
||||
container = lv.obj(root)
|
||||
container.align(lv.ALIGN.CENTER, 0, 0)
|
||||
container.set_size(180, 180)
|
||||
container.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP)
|
||||
container.set_flex_align(lv.FLEX_ALIGN.SPACE_EVENLY, lv.FLEX_ALIGN.CENTER, lv.FLEX_ALIGN.CENTER)
|
||||
container.set_style_radius(50, 0)
|
||||
|
||||
for i in range(4):
|
||||
img = lv.img(container)
|
||||
img.set_src(img_star)
|
||||
img.set_style_bg_color(lv.palette_main(lv.PALETTE.GREY), 0)
|
||||
img.set_style_bg_opa(lv.OPA.COVER, 0)
|
||||
img.set_style_transform_zoom(400, lv.STATE.PRESSED)
|
||||
img.add_flag(img.FLAG.CLICKABLE)
|
||||
img.add_event_cb(lambda e: event_cb(e, snapshot_obj), lv.EVENT.PRESSED, None)
|
||||
img.add_event_cb(lambda e: event_cb(e, snapshot_obj), lv.EVENT.RELEASED, None)
|
||||
@@ -214,6 +214,9 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/
|
||||
#endif /*LV_ENABLE_GC*/
|
||||
|
||||
/*1: Enable API to take snapshot for object*/
|
||||
#define LV_USE_SNAPSHOT 1
|
||||
|
||||
/*=====================
|
||||
* COMPILER SETTINGS
|
||||
*====================*/
|
||||
|
||||
2
lvgl.h
2
lvgl.h
@@ -26,6 +26,7 @@ extern "C" {
|
||||
#include "src/misc/lv_timer.h"
|
||||
#include "src/misc/lv_math.h"
|
||||
#include "src/misc/lv_async.h"
|
||||
#include "src/misc/lv_anim_timeline.h"
|
||||
|
||||
#include "src/hal/lv_hal.h"
|
||||
|
||||
@@ -69,6 +70,7 @@ extern "C" {
|
||||
#include "src/extra/widgets/lv_widgets.h"
|
||||
#include "src/extra/layouts/lv_layouts.h"
|
||||
#include "src/extra/themes/lv_themes.h"
|
||||
#include "src/extra/others/lv_others.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
|
||||
38
src/extra/others/lv_others.h
Normal file
38
src/extra/others/lv_others.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file lv_others.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OTHERS_H
|
||||
#define LV_OTHERS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "snapshot/lv_snapshot.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OTHERS_H*/
|
||||
213
src/extra/others/snapshot/lv_snapshot.c
Normal file
213
src/extra/others/snapshot/lv_snapshot.c
Normal file
@@ -0,0 +1,213 @@
|
||||
/**
|
||||
* @file lv_snapshot.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_snapshot.h"
|
||||
#if LV_USE_SNAPSHOT
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "../../../core/lv_disp.h"
|
||||
#include "../../../core/lv_refr.h"
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/** Get the buffer needed for object snapshot image.
|
||||
*
|
||||
* @param obj The object to generate snapshot.
|
||||
* @param cf color format for generated image.
|
||||
*
|
||||
* @return the buffer size needed in bytes
|
||||
*/
|
||||
uint32_t lv_snapshot_buf_size_needed(lv_obj_t * obj, lv_img_cf_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR_ALPHA:
|
||||
case LV_IMG_CF_ALPHA_1BIT:
|
||||
case LV_IMG_CF_ALPHA_2BIT:
|
||||
case LV_IMG_CF_ALPHA_4BIT:
|
||||
case LV_IMG_CF_ALPHA_8BIT:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
lv_obj_update_layout(obj);
|
||||
|
||||
/*Width and height determine snapshot image size.*/
|
||||
lv_coord_t w = lv_obj_get_width(obj);
|
||||
lv_coord_t h = lv_obj_get_height(obj);
|
||||
|
||||
uint8_t px_size = lv_img_cf_get_px_size(cf);
|
||||
return w * h * ((px_size + 7) >> 3);
|
||||
}
|
||||
|
||||
/** Take snapshot for object with its children, save image info to provided buffer.
|
||||
*
|
||||
* @param obj The object to generate snapshot.
|
||||
* @param cf color format for generated image.
|
||||
* @param dsc image descriptor to store the image result.
|
||||
* @param buf the buffer to store image data.
|
||||
* @param buff_size provided buffer size in bytes.
|
||||
*
|
||||
* @return LV_RES_OK on success, LV_RES_INV on error.
|
||||
*/
|
||||
lv_res_t lv_snapshot_take_to_buf(lv_obj_t * obj, lv_img_cf_t cf, lv_img_dsc_t * dsc, void * buf, uint32_t buff_size)
|
||||
{
|
||||
LV_ASSERT(dsc);
|
||||
LV_ASSERT(buf);
|
||||
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR_ALPHA:
|
||||
case LV_IMG_CF_ALPHA_1BIT:
|
||||
case LV_IMG_CF_ALPHA_2BIT:
|
||||
case LV_IMG_CF_ALPHA_4BIT:
|
||||
case LV_IMG_CF_ALPHA_8BIT:
|
||||
break;
|
||||
default:
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if(lv_snapshot_buf_size_needed(obj, cf) > buff_size)
|
||||
return LV_RES_INV;
|
||||
|
||||
/*Width and height determine snapshot image size.*/
|
||||
lv_coord_t w = lv_obj_get_width(obj);
|
||||
lv_coord_t h = lv_obj_get_height(obj);
|
||||
|
||||
/*Backup obj original info.*/
|
||||
lv_disp_t * disp_old = lv_obj_get_disp(obj);
|
||||
lv_obj_t * parent_old = lv_obj_get_parent(obj);
|
||||
|
||||
lv_memset(buf, 0x00, buff_size);
|
||||
lv_memset_00(dsc, sizeof(lv_img_dsc_t));
|
||||
|
||||
/*We are safe to use stack for below variables since disp will be
|
||||
* unregistered when function returns. */
|
||||
lv_disp_t * disp;
|
||||
lv_disp_drv_t driver;
|
||||
lv_disp_draw_buf_t draw_buf;
|
||||
|
||||
lv_disp_draw_buf_init(&draw_buf, buf, NULL, w * h);
|
||||
|
||||
lv_disp_drv_init(&driver);
|
||||
driver.draw_buf = &draw_buf;
|
||||
driver.hor_res = lv_disp_get_hor_res(disp_old);
|
||||
driver.ver_res = lv_disp_get_ver_res(disp_old);
|
||||
lv_disp_drv_use_generic_set_px_cb(&driver, cf);
|
||||
|
||||
disp = lv_disp_drv_register(&driver);
|
||||
if(disp == NULL) {
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
/*Make background transparent */
|
||||
lv_disp_set_bg_opa(disp, LV_OPA_TRANSP);
|
||||
|
||||
/*Move obj to newly created disp and refresh it. */
|
||||
lv_obj_t * screen = lv_disp_get_scr_act(disp);
|
||||
lv_obj_remove_style_all(screen);
|
||||
lv_obj_allocate_spec_attr(screen);
|
||||
screen->spec_attr->child_cnt = 1;
|
||||
screen->spec_attr->children = &obj;
|
||||
|
||||
obj->parent = screen;
|
||||
|
||||
disp->inv_p = 0;
|
||||
lv_obj_invalidate(obj);
|
||||
|
||||
/*Don't call lv_refr_now to avoid animation disruption */
|
||||
_lv_disp_refr_timer(disp->refr_timer);
|
||||
|
||||
/*Restore obj original parameters and clean up*/
|
||||
obj->parent = parent_old;
|
||||
screen->spec_attr->child_cnt = 0;
|
||||
screen->spec_attr->children = NULL;
|
||||
|
||||
lv_disp_remove(disp);
|
||||
|
||||
dsc->data = buf;
|
||||
dsc->header.w = w;
|
||||
dsc->header.h = h;
|
||||
dsc->header.cf = cf;
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
/** Take snapshot for object with its children, alloc the memory needed.
|
||||
*
|
||||
* @param obj The object to generate snapshot.
|
||||
* @param cf color format for generated image.
|
||||
*
|
||||
* @return a pointer to a image descriptor, or NULL if failed.
|
||||
*/
|
||||
lv_img_dsc_t * lv_snapshot_take(lv_obj_t * obj, lv_img_cf_t cf)
|
||||
{
|
||||
uint32_t buff_size = lv_snapshot_buf_size_needed(obj, cf);
|
||||
|
||||
void * buf = lv_mem_alloc(buff_size);
|
||||
if(buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_img_dsc_t * dsc = lv_mem_alloc(sizeof(lv_img_dsc_t));
|
||||
if(dsc == NULL) {
|
||||
lv_mem_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(lv_snapshot_take_to_buf(obj, cf, dsc, buf, buff_size) == LV_RES_INV) {
|
||||
lv_mem_free(buf);
|
||||
lv_mem_free(dsc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dsc;
|
||||
}
|
||||
|
||||
/** Free the snapshot image returned by @ref lv_snapshot_take
|
||||
*
|
||||
* It will firstly free the data image takes, then the image descriptor.
|
||||
*
|
||||
* @param dsc The image descriptor generated by lv_snapshot_take.
|
||||
*
|
||||
*/
|
||||
void lv_snapshot_free(lv_img_dsc_t * dsc)
|
||||
{
|
||||
if(!dsc)
|
||||
return;
|
||||
|
||||
if(dsc->data)
|
||||
lv_mem_free((void *)dsc->data);
|
||||
|
||||
lv_mem_free(dsc);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_SNAPSHOT*/
|
||||
84
src/extra/others/snapshot/lv_snapshot.h
Normal file
84
src/extra/others/snapshot/lv_snapshot.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @file lv_snapshot.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_SNAPSHOT_H
|
||||
#define LV_SNAPSHOT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
#include "../../../core/lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#if LV_USE_SNAPSHOT
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/** Take snapshot for object with its children.
|
||||
*
|
||||
* @param obj The object to generate snapshot.
|
||||
* @param cf color format for generated image.
|
||||
*
|
||||
* @return a pointer to a image descriptor, or NULL if failed.
|
||||
*/
|
||||
lv_img_dsc_t * lv_snapshot_take(lv_obj_t * obj, lv_img_cf_t cf);
|
||||
|
||||
/** Free the snapshot image returned by @ref lv_snapshot_take
|
||||
*
|
||||
* It will firstly free the data image takes, then the image descriptor.
|
||||
*
|
||||
* @param dsc The image descriptor generated by lv_snapshot_take.
|
||||
*
|
||||
*/
|
||||
void lv_snapshot_free(lv_img_dsc_t * dsc);
|
||||
|
||||
/** Get the buffer needed for object snapshot image.
|
||||
*
|
||||
* @param obj The object to generate snapshot.
|
||||
* @param cf color format for generated image.
|
||||
*
|
||||
* @return the buffer size needed in bytes
|
||||
*/
|
||||
uint32_t lv_snapshot_buf_size_needed(lv_obj_t * obj, lv_img_cf_t cf);
|
||||
|
||||
/** Take snapshot for object with its children, save image info to provided buffer.
|
||||
*
|
||||
* @param obj The object to generate snapshot.
|
||||
* @param cf color format for generated image.
|
||||
* @param dsc image descriptor to store the image result.
|
||||
* @param buff the buffer to store image data.
|
||||
* @param buff_size provided buffer size in bytes.
|
||||
*
|
||||
* @return LV_RES_OK on success, LV_RES_INV on error.
|
||||
*/
|
||||
lv_res_t lv_snapshot_take_to_buf(lv_obj_t * obj, lv_img_cf_t cf, lv_img_dsc_t * dsc, void * buf, uint32_t buff_size);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
#endif /*LV_USE_SNAPSHOT*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -254,6 +254,71 @@ void lv_spangroup_set_mode(lv_obj_t * obj, lv_span_mode_t mode)
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get a spangroup child by its index.
|
||||
*
|
||||
* @param obj The spangroup object
|
||||
* @param id the index of the child.
|
||||
* 0: the oldest (firstly created) child
|
||||
* 1: the second oldest
|
||||
* child count-1: the youngest
|
||||
* -1: the youngest
|
||||
* -2: the second youngest
|
||||
* @return The child span at index `id`, or NULL if the ID does not exist
|
||||
*/
|
||||
lv_span_t * lv_spangroup_get_child(const lv_obj_t * obj, int32_t id)
|
||||
{
|
||||
if(obj == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_spangroup_t * spans = (lv_spangroup_t *)obj;
|
||||
lv_ll_t * linked_list = &spans->child_ll;
|
||||
|
||||
bool traverse_forwards = (id >= 0);
|
||||
int32_t cur_idx = 0;
|
||||
lv_ll_node_t * cur_node = linked_list->head;
|
||||
|
||||
/*If using a negative index, start from the tail and use cur -1 to indicate the end*/
|
||||
if(!traverse_forwards) {
|
||||
cur_idx = -1;
|
||||
cur_node = linked_list->tail;
|
||||
}
|
||||
|
||||
while(cur_node != NULL) {
|
||||
if(cur_idx == id) {
|
||||
return (lv_span_t *) cur_node;
|
||||
}
|
||||
if(traverse_forwards) {
|
||||
cur_node = (lv_ll_node_t *) _lv_ll_get_next(linked_list, cur_node);
|
||||
cur_idx++;
|
||||
}
|
||||
else {
|
||||
cur_node = (lv_ll_node_t *) _lv_ll_get_prev(linked_list, cur_node);
|
||||
cur_idx--;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param obj The spangroup object to get the child count of.
|
||||
* @return The span count of the spangroup.
|
||||
*/
|
||||
uint32_t lv_spangroup_get_child_cnt(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
if(obj == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
lv_spangroup_t * spans = (lv_spangroup_t *)obj;
|
||||
return _lv_ll_get_len(&(spans->child_ll));
|
||||
}
|
||||
|
||||
/**
|
||||
* get the align of the spangroup.
|
||||
* @param obj pointer to a spangroup object.
|
||||
|
||||
@@ -137,6 +137,27 @@ void lv_spangroup_set_mode(lv_obj_t * obj, lv_span_mode_t mode);
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get a spangroup child by its index.
|
||||
*
|
||||
* @param obj The spangroup object
|
||||
* @param id the index of the child.
|
||||
* 0: the oldest (firstly created) child
|
||||
* 1: the second oldest
|
||||
* child count-1: the youngest
|
||||
* -1: the youngest
|
||||
* -2: the second youngest
|
||||
* @return The child span at index `id`, or NULL if the ID does not exist
|
||||
*/
|
||||
lv_span_t * lv_spangroup_get_child(const lv_obj_t * obj, int32_t id);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param obj The spangroup object to get the child count of.
|
||||
* @return The span count of the spangroup.
|
||||
*/
|
||||
uint32_t lv_spangroup_get_child_cnt(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* get the align of the spangroup.
|
||||
* @param obj pointer to a spangroup object.
|
||||
|
||||
@@ -34,6 +34,24 @@
|
||||
**********************/
|
||||
static lv_obj_tree_walk_res_t invalidate_layout_cb(lv_obj_t * obj, void * user_data);
|
||||
|
||||
static void set_px_true_color_alpha(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha1(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha2(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha4(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha8(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_alpha_generic(lv_img_dsc_t * d, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@@ -218,9 +236,6 @@ void lv_disp_remove(lv_disp_t * disp)
|
||||
indev = lv_indev_get_next(indev);
|
||||
}
|
||||
|
||||
_lv_ll_remove(&LV_GC_ROOT(_lv_disp_ll), disp);
|
||||
lv_timer_del(disp->refr_timer);
|
||||
|
||||
/** delete screen and other obj */
|
||||
if (disp->sys_layer) {
|
||||
lv_obj_del(disp->sys_layer);
|
||||
@@ -234,6 +249,9 @@ void lv_disp_remove(lv_disp_t * disp)
|
||||
/*Delete the screenst*/
|
||||
lv_obj_del(disp->screens[0]);
|
||||
}
|
||||
|
||||
_lv_ll_remove(&LV_GC_ROOT(_lv_disp_ll), disp);
|
||||
lv_timer_del(disp->refr_timer);
|
||||
lv_mem_free(disp);
|
||||
|
||||
if(was_default) lv_disp_set_default(_lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll)));
|
||||
@@ -403,6 +421,29 @@ lv_disp_rot_t lv_disp_get_rotation(lv_disp_t * disp)
|
||||
return disp->driver->rotated;
|
||||
}
|
||||
|
||||
void lv_disp_drv_use_generic_set_px_cb(lv_disp_drv_t * disp_drv, lv_img_cf_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR_ALPHA:
|
||||
disp_drv->set_px_cb = set_px_true_color_alpha;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_1BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha1;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_2BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha2;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_4BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha4;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_8BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha8;
|
||||
break;
|
||||
default:
|
||||
disp_drv->set_px_cb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@@ -413,3 +454,99 @@ static lv_obj_tree_walk_res_t invalidate_layout_cb(lv_obj_t * obj, void * user_d
|
||||
lv_obj_mark_layout_as_dirty(obj);
|
||||
return LV_OBJ_TREE_WALK_NEXT;
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha1(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_1BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha2(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_2BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha4(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_4BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha8(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_8BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_alpha_generic(lv_img_dsc_t * d, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
d->header.always_zero = 0;
|
||||
d->header.h = 1; /*Doesn't matter*/
|
||||
|
||||
uint8_t br = lv_color_brightness(color);
|
||||
if(opa < LV_OPA_MAX) {
|
||||
uint8_t bg = lv_img_buf_get_px_alpha(d, x, y);
|
||||
br = (uint16_t)((uint16_t)br * opa + (bg * (255 - opa))) >> 8;
|
||||
}
|
||||
|
||||
lv_img_buf_set_px_alpha(d, x, y, br);
|
||||
}
|
||||
|
||||
static void set_px_true_color_alpha(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.always_zero = 0;
|
||||
d.header.h = 1; /*Doesn't matter*/;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
|
||||
|
||||
lv_color_t bg_color = lv_img_buf_get_px_color(&d, x, y, lv_color_black());
|
||||
lv_opa_t bg_opa = lv_img_buf_get_px_alpha(&d, x, y);
|
||||
|
||||
lv_opa_t res_opa;
|
||||
lv_color_t res_color;
|
||||
|
||||
lv_color_mix_with_alpha(bg_color, bg_opa, color, opa, &res_color, &res_opa);
|
||||
|
||||
lv_img_buf_set_px_alpha(&d, x, y, res_opa);
|
||||
lv_img_buf_set_px_color(&d, x, y, res_color);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ extern "C" {
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "lv_hal.h"
|
||||
#include "../draw/lv_img_buf.h"
|
||||
#include "../misc/lv_color.h"
|
||||
#include "../misc/lv_area.h"
|
||||
#include "../misc/lv_ll.h"
|
||||
@@ -312,6 +313,8 @@ lv_disp_t * lv_disp_get_next(lv_disp_t * disp);
|
||||
*/
|
||||
lv_disp_draw_buf_t * lv_disp_get_draw_buf(lv_disp_t * disp);
|
||||
|
||||
void lv_disp_drv_use_generic_set_px_cb(lv_disp_drv_t * disp_drv, lv_img_cf_t cf);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -81,7 +81,7 @@ typedef struct {
|
||||
int16_t enc_diff; /**< For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/
|
||||
|
||||
lv_indev_state_t state; /**< LV_INDEV_STATE_REL or LV_INDEV_STATE_PR*/
|
||||
bool continue_reading; /**< Call the read callback until it's set to true*/
|
||||
bool continue_reading; /**< If set to true, the read callback is invoked again*/
|
||||
} lv_indev_data_t;
|
||||
|
||||
/** Initialized by the user and registered by 'lv_indev_add()'*/
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
#endif
|
||||
|
||||
/*Enable more complex drawing routines to manage screens transparency.
|
||||
*Can be used if the UI is above an other layer, e.g. an OSD menu or video player.
|
||||
*Can be used if the UI is above another layer, e.g. an OSD menu or video player.
|
||||
*Requires `LV_COLOR_DEPTH = 32` colors and the screen's `bg_opa` should be set to non LV_OPA_COVER value*/
|
||||
#ifndef LV_COLOR_SCREEN_TRANSP
|
||||
# ifdef CONFIG_LV_COLOR_SCREEN_TRANSP
|
||||
@@ -585,6 +585,15 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
#endif
|
||||
#endif /*LV_ENABLE_GC*/
|
||||
|
||||
/*1: Enable API to take snapshot for object*/
|
||||
#ifndef LV_USE_SNAPSHOT
|
||||
# ifdef CONFIG_LV_USE_SNAPSHOT
|
||||
# define LV_USE_SNAPSHOT CONFIG_LV_USE_SNAPSHOT
|
||||
# else
|
||||
# define LV_USE_SNAPSHOT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*=====================
|
||||
* COMPILER SETTINGS
|
||||
*====================*/
|
||||
|
||||
168
src/misc/lv_anim_timeline.c
Normal file
168
src/misc/lv_anim_timeline.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* @file lv_anim_timeline.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_anim_timeline.h"
|
||||
#include "lv_mem.h"
|
||||
#include "../misc/lv_assert.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*Data of anim_timeline_dsc*/
|
||||
typedef struct{
|
||||
lv_anim_t anim;
|
||||
lv_anim_t * new_anim;
|
||||
uint32_t start_time;
|
||||
}lv_anim_timeline_dsc_t;
|
||||
|
||||
/*Data of anim_timeline*/
|
||||
struct _lv_anim_timeline_t{
|
||||
lv_anim_timeline_dsc_t * anim_dsc; /**< Dynamically allocated anim dsc array*/
|
||||
uint32_t anim_dsc_cnt; /**< The length of anim dsc array*/
|
||||
bool reverse; /**< Reverse playback*/
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_anim_timeline_t * lv_anim_timeline_create(void)
|
||||
{
|
||||
lv_anim_timeline_t * at = (lv_anim_timeline_t *)lv_mem_alloc(sizeof(lv_anim_timeline_t));
|
||||
|
||||
LV_ASSERT_MALLOC(at);
|
||||
|
||||
if(at) lv_memset_00(at, sizeof(lv_anim_timeline_t));
|
||||
|
||||
return at;
|
||||
}
|
||||
|
||||
void lv_anim_timeline_del(lv_anim_timeline_t * at)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
|
||||
for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
|
||||
lv_anim_t * a = &(at->anim_dsc[i].anim);
|
||||
lv_anim_custom_del(at->anim_dsc[i].new_anim, (lv_anim_custom_exec_cb_t)a->exec_cb);
|
||||
}
|
||||
|
||||
lv_mem_free(at->anim_dsc);
|
||||
lv_mem_free(at);
|
||||
}
|
||||
|
||||
void lv_anim_timeline_add(lv_anim_timeline_t * at, uint32_t start_time, lv_anim_t * a)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
|
||||
at->anim_dsc_cnt++;
|
||||
at->anim_dsc = lv_mem_realloc(at->anim_dsc, at->anim_dsc_cnt * sizeof(lv_anim_timeline_dsc_t));
|
||||
|
||||
LV_ASSERT_MALLOC(at->anim_dsc);
|
||||
|
||||
at->anim_dsc[at->anim_dsc_cnt - 1].anim = *a;
|
||||
at->anim_dsc[at->anim_dsc_cnt - 1].new_anim = NULL;
|
||||
at->anim_dsc[at->anim_dsc_cnt - 1].start_time = start_time;
|
||||
}
|
||||
|
||||
uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
|
||||
const uint32_t playtime = lv_anim_timeline_get_playtime(at);
|
||||
bool reverse = at->reverse;
|
||||
|
||||
for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
|
||||
lv_anim_t a = at->anim_dsc[i].anim;
|
||||
uint32_t start_time = at->anim_dsc[i].start_time;
|
||||
|
||||
if(reverse) {
|
||||
int32_t temp = a.start_value;
|
||||
a.start_value = a.end_value;
|
||||
a.end_value = temp;
|
||||
lv_anim_set_delay(&a, playtime - (start_time + a.time));
|
||||
}
|
||||
else {
|
||||
lv_anim_set_delay(&a, start_time);
|
||||
}
|
||||
|
||||
at->anim_dsc[i].new_anim = lv_anim_start(&a);
|
||||
}
|
||||
|
||||
return playtime;
|
||||
}
|
||||
|
||||
void lv_anim_timeline_set_reverse(lv_anim_timeline_t * at, bool reverse)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
at->reverse = reverse;
|
||||
}
|
||||
|
||||
void lv_anim_timeline_set_progress(lv_anim_timeline_t * at, uint16_t progress)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
|
||||
const uint32_t playtime = lv_anim_timeline_get_playtime(at);
|
||||
const uint32_t act_time = progress * playtime / 0xFFFF;
|
||||
|
||||
for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
|
||||
lv_anim_t * a = &(at->anim_dsc[i].anim);
|
||||
uint32_t start_time = at->anim_dsc[i].start_time;
|
||||
int32_t value = 0;
|
||||
|
||||
if(act_time < start_time) {
|
||||
value = a->start_value;
|
||||
}
|
||||
else if(act_time < (start_time + a->time)) {
|
||||
a->act_time = act_time - start_time;
|
||||
value = a->path_cb(a);
|
||||
}
|
||||
else {
|
||||
value = a->end_value;
|
||||
}
|
||||
|
||||
a->exec_cb(a->var, value);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t lv_anim_timeline_get_playtime(lv_anim_timeline_t * at)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
|
||||
uint32_t playtime = 0;
|
||||
for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
|
||||
uint32_t end = at->anim_dsc[i].start_time + at->anim_dsc[i].anim.time;
|
||||
if(end > playtime) {
|
||||
playtime = end;
|
||||
}
|
||||
}
|
||||
|
||||
return playtime;
|
||||
}
|
||||
|
||||
bool lv_anim_timeline_get_reverse(lv_anim_timeline_t * at)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
return at->reverse;
|
||||
}
|
||||
97
src/misc/lv_anim_timeline.h
Normal file
97
src/misc/lv_anim_timeline.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @file lv_anim_timeline.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_ANIM_TIMELINE_H
|
||||
#define LV_ANIM_TIMELINE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_anim.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct _lv_anim_timeline_t;
|
||||
|
||||
typedef struct _lv_anim_timeline_t lv_anim_timeline_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a animation timeline.
|
||||
* @return pointer to the animation timeline.
|
||||
*/
|
||||
lv_anim_timeline_t * lv_anim_timeline_create(void);
|
||||
|
||||
/**
|
||||
* Delete animation timeline.
|
||||
* @param at pointer to the animation timeline.
|
||||
*/
|
||||
void lv_anim_timeline_del(lv_anim_timeline_t * at);
|
||||
|
||||
/**
|
||||
* Add animation to the animation timeline.
|
||||
* @param at pointer to the animation timeline.
|
||||
* @param start_time the time the animation started on the timeline, note that start_time will override the value of delay.
|
||||
* @param a pointer to an animation.
|
||||
*/
|
||||
void lv_anim_timeline_add(lv_anim_timeline_t * at, uint32_t start_time, lv_anim_t * a);
|
||||
|
||||
/**
|
||||
* Start the animation timeline.
|
||||
* @param at pointer to the animation timeline.
|
||||
* @return total time spent in animation timeline.
|
||||
*/
|
||||
uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at);
|
||||
|
||||
/**
|
||||
* Set the playback direction of the animation timeline.
|
||||
* @param at pointer to the animation timeline.
|
||||
* @param reverse whether to play in reverse.
|
||||
*/
|
||||
void lv_anim_timeline_set_reverse(lv_anim_timeline_t * at, bool reverse);
|
||||
|
||||
/**
|
||||
* Set the progress of the animation timeline.
|
||||
* @param at pointer to the animation timeline.
|
||||
* @param progress set value 0~65535 to map 0~100% animation progress.
|
||||
*/
|
||||
void lv_anim_timeline_set_progress(lv_anim_timeline_t * at, uint16_t progress);
|
||||
|
||||
/**
|
||||
* Get the time used to play the animation timeline.
|
||||
* @param at pointer to the animation timeline.
|
||||
* @return total time spent in animation timeline.
|
||||
*/
|
||||
uint32_t lv_anim_timeline_get_playtime(lv_anim_timeline_t * at);
|
||||
|
||||
/**
|
||||
* Get whether the animation timeline is played in reverse.
|
||||
* @param at pointer to the animation timeline.
|
||||
* @return return true if it is reverse playback.
|
||||
*/
|
||||
bool lv_anim_timeline_get_reverse(lv_anim_timeline_t * at);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_ANIM_TIMELINE_H*/
|
||||
@@ -1,4 +1,5 @@
|
||||
CSRCS += lv_anim.c
|
||||
CSRCS += lv_anim_timeline.c
|
||||
CSRCS += lv_area.c
|
||||
CSRCS += lv_async.c
|
||||
CSRCS += lv_bidi.c
|
||||
|
||||
@@ -27,25 +27,6 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_canvas_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
static void set_set_px_cb(lv_disp_drv_t * disp_drv, lv_img_cf_t cf);
|
||||
|
||||
static void set_px_true_color_alpha(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha1(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha2(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha4(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_cb_alpha8(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
static void set_px_alpha_generic(lv_img_dsc_t * d, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -595,7 +576,7 @@ void lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord
|
||||
disp.driver->hor_res = dsc->header.w;
|
||||
disp.driver->ver_res = dsc->header.h;
|
||||
|
||||
set_set_px_cb(disp.driver, dsc->header.cf);
|
||||
lv_disp_drv_use_generic_set_px_cb(disp.driver, dsc->header.cf);
|
||||
|
||||
/*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/
|
||||
lv_color_t ctransp = LV_COLOR_CHROMA_KEY;
|
||||
@@ -656,7 +637,7 @@ void lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord
|
||||
disp.driver->hor_res = dsc->header.w;
|
||||
disp.driver->ver_res = dsc->header.h;
|
||||
|
||||
set_set_px_cb(disp.driver, dsc->header.cf);
|
||||
lv_disp_drv_use_generic_set_px_cb(disp.driver, dsc->header.cf);
|
||||
|
||||
lv_disp_t * refr_ori = _lv_refr_get_disp_refreshing();
|
||||
_lv_refr_set_disp_refreshing(&disp);
|
||||
@@ -717,7 +698,7 @@ void lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const voi
|
||||
disp.driver->hor_res = dsc->header.w;
|
||||
disp.driver->ver_res = dsc->header.h;
|
||||
|
||||
set_set_px_cb(disp.driver, dsc->header.cf);
|
||||
lv_disp_drv_use_generic_set_px_cb(disp.driver, dsc->header.cf);
|
||||
|
||||
lv_disp_t * refr_ori = _lv_refr_get_disp_refreshing();
|
||||
_lv_refr_set_disp_refreshing(&disp);
|
||||
@@ -764,7 +745,7 @@ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t
|
||||
disp.driver->hor_res = dsc->header.w;
|
||||
disp.driver->ver_res = dsc->header.h;
|
||||
|
||||
set_set_px_cb(disp.driver, dsc->header.cf);
|
||||
lv_disp_drv_use_generic_set_px_cb(disp.driver, dsc->header.cf);
|
||||
|
||||
/*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/
|
||||
lv_color_t ctransp = LV_COLOR_CHROMA_KEY;
|
||||
@@ -822,7 +803,7 @@ void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t points[], uint32
|
||||
disp.driver->hor_res = dsc->header.w;
|
||||
disp.driver->ver_res = dsc->header.h;
|
||||
|
||||
set_set_px_cb(disp.driver, dsc->header.cf);
|
||||
lv_disp_drv_use_generic_set_px_cb(disp.driver, dsc->header.cf);
|
||||
|
||||
/*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/
|
||||
lv_color_t ctransp = LV_COLOR_CHROMA_KEY;
|
||||
@@ -878,7 +859,7 @@ void lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_
|
||||
disp.driver->hor_res = dsc->header.w;
|
||||
disp.driver->ver_res = dsc->header.h;
|
||||
|
||||
set_set_px_cb(disp.driver, dsc->header.cf);
|
||||
lv_disp_drv_use_generic_set_px_cb(disp.driver, dsc->header.cf);
|
||||
|
||||
/*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/
|
||||
lv_color_t ctransp = LV_COLOR_CHROMA_KEY;
|
||||
@@ -930,123 +911,4 @@ static void lv_canvas_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj
|
||||
LV_TRACE_OBJ_CREATE("finished");
|
||||
}
|
||||
|
||||
static void set_set_px_cb(lv_disp_drv_t * disp_drv, lv_img_cf_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR_ALPHA:
|
||||
disp_drv->set_px_cb = set_px_true_color_alpha;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_1BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha1;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_2BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha2;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_4BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha4;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_8BIT:
|
||||
disp_drv->set_px_cb = set_px_cb_alpha8;
|
||||
break;
|
||||
default:
|
||||
disp_drv->set_px_cb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha1(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_1BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha2(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_2BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha4(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_4BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_cb_alpha8(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_ALPHA_8BIT;
|
||||
|
||||
set_px_alpha_generic(&d, x, y, color, opa);
|
||||
}
|
||||
|
||||
static void set_px_alpha_generic(lv_img_dsc_t * d, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
d->header.always_zero = 0;
|
||||
d->header.h = 1; /*Doesn't matter*/
|
||||
|
||||
uint8_t br = lv_color_brightness(color);
|
||||
if(opa < LV_OPA_MAX) {
|
||||
uint8_t bg = lv_img_buf_get_px_alpha(d, x, y);
|
||||
br = (uint16_t)((uint16_t)br * opa + (bg * (255 - opa))) >> 8;
|
||||
}
|
||||
|
||||
lv_img_buf_set_px_alpha(d, x, y, br);
|
||||
}
|
||||
|
||||
static void set_px_true_color_alpha(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
(void) disp_drv; /*Unused*/
|
||||
|
||||
if(opa <= LV_OPA_MIN) return;
|
||||
lv_img_dsc_t d;
|
||||
d.data = buf;
|
||||
d.header.always_zero = 0;
|
||||
d.header.h = 1; /*Doesn't matter*/;
|
||||
d.header.w = buf_w;
|
||||
d.header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
|
||||
|
||||
lv_color_t bg_color = lv_img_buf_get_px_color(&d, x, y, lv_color_black());
|
||||
lv_opa_t bg_opa = lv_img_buf_get_px_alpha(&d, x, y);
|
||||
|
||||
lv_opa_t res_opa;
|
||||
lv_color_t res_color;
|
||||
|
||||
lv_color_mix_with_alpha(bg_color, bg_opa, color, opa, &res_color, &res_opa);
|
||||
|
||||
lv_img_buf_set_px_alpha(&d, x, y, res_opa);
|
||||
lv_img_buf_set_px_color(&d, x, y, res_color);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user