feat(blur): add blur support (#9223)
Arduino Lint / lint (push) Has been cancelled
Build Examples with C++ Compiler / build-examples (push) Has been cancelled
MicroPython CI / Build esp32 port (push) Has been cancelled
MicroPython CI / Build rp2 port (push) Has been cancelled
MicroPython CI / Build stm32 port (push) Has been cancelled
MicroPython CI / Build unix port (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_NORMAL_8BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_SDL - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build ESP IDF ESP32S3 (push) Has been cancelled
C/C++ CI / Run tests with 32bit build (push) Has been cancelled
C/C++ CI / Run tests with 64bit build (push) Has been cancelled
BOM Check / bom-check (push) Has been cancelled
Verify that lv_conf_internal.h matches repository state / verify-conf-internal (push) Has been cancelled
Verify the widget property name / verify-property-name (push) Has been cancelled
Verify code formatting / verify-formatting (push) Has been cancelled
Compare file templates with file names / template-check (push) Has been cancelled
Build docs / build-and-deploy (push) Has been cancelled
Test API JSON generator / Test API JSON (push) Has been cancelled
Install LVGL using CMake / build-examples (push) Has been cancelled
Check Makefile / Build using Makefile (push) Has been cancelled
Check Makefile for UEFI / Build using Makefile for UEFI (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/benchmark_results_comment/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/filter_docker_logs/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/serialize_results/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 32b - lv_conf_perf32b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 64b - lv_conf_perf64b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Save PR Number (push) Has been cancelled
Hardware Performance Test / Hardware Performance Benchmark (push) Has been cancelled
Hardware Performance Test / HW Benchmark - Save PR Number (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_32B - Ubuntu (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_64B - Ubuntu (push) Has been cancelled
Port repo release update / run-release-branch-updater (push) Has been cancelled
Verify Font License / verify-font-license (push) Has been cancelled
Verify Kconfig / verify-kconfig (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
@@ -1408,6 +1408,48 @@ Sets the intensity of color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means
|
||||
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Ext. draw</strong> No</li>
|
||||
</ul>
|
||||
|
||||
blur_radius
|
||||
~~~~~~~~~~~
|
||||
|
||||
Sets the intensity of blurring. Applied on each lv_part separately before the children are rendered.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<ul>
|
||||
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `0`</li>
|
||||
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Layout</strong> No</li>
|
||||
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Ext. draw</strong> No</li>
|
||||
</ul>
|
||||
|
||||
blur_backdrop
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
If `true` the background of the widget will be blurred. The part should have < 100% opacity to make it visible. If `false` the given part will be blurred when it's rendered but before drawing the children.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<ul>
|
||||
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `false`</li>
|
||||
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Layout</strong> No</li>
|
||||
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Ext. draw</strong> No</li>
|
||||
</ul>
|
||||
|
||||
blur_quality
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Setting to `LV_BLUR_QUALITY_SPEED` the blurring algorithm will prefer speed over quality. `LV_BLUR_QUALITY_PRECISION` will force using higher quality but slower blur. With `LV_BLUR_QUALITY_AUTO` the quality will be selected automatically.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<ul>
|
||||
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `LV_BLUR_QUALITY_AUTO`</li>
|
||||
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Layout</strong> No</li>
|
||||
<li style='display:inline-block; margin-right: 20px; margin-left: 0px'><strong>Ext. draw</strong> No</li>
|
||||
</ul>
|
||||
|
||||
anim
|
||||
~~~~
|
||||
|
||||
|
||||
@@ -617,6 +617,25 @@ Functions for triangle drawing:
|
||||
|
||||
|
||||
|
||||
Blur Draw Descriptor
|
||||
********************
|
||||
|
||||
Blur is defined by :cpp:type:`lv_draw_blur_dsc_t`, which includes:
|
||||
|
||||
:blur_radius: The radius of the blur.
|
||||
:corner_radius: The radius of the corners.
|
||||
:quality: Tells whether to prefer speed or quality.
|
||||
|
||||
Functions for blur drawing:
|
||||
|
||||
- :cpp:expr:`lv_draw_blur_dsc_init(&dsc)` initializes a blur descriptor.
|
||||
- :cpp:expr:`lv_draw_blur(layer, &dsc, area)` creates a task to blur an area.
|
||||
- :cpp:expr:`lv_draw_task_get_blur_dsc(draw_task)` retrieves blur descriptor.
|
||||
|
||||
.. lv_example:: widgets/canvas/lv_example_canvas_10
|
||||
:language: c
|
||||
|
||||
|
||||
Vector Draw Descriptor
|
||||
**********************
|
||||
|
||||
|
||||
@@ -57,14 +57,22 @@ Draw a triangle to the canvas
|
||||
.. lv_example:: widgets/canvas/lv_example_canvas_9
|
||||
:language: c
|
||||
|
||||
Draw Fancy Letter Effects
|
||||
-------------------------
|
||||
Blur an area on the canvas
|
||||
-----------------------------
|
||||
|
||||
.. lv_example:: widgets/canvas/lv_example_canvas_10
|
||||
:language: c
|
||||
|
||||
|
||||
Draw Fancy Letter Effects 2
|
||||
---------------------------
|
||||
Draw Fancy Letter Effects
|
||||
-------------------------
|
||||
|
||||
.. lv_example:: widgets/canvas/lv_example_canvas_11
|
||||
:language: c
|
||||
|
||||
|
||||
Draw Fancy Letter Effects 2
|
||||
---------------------------
|
||||
.. lv_example:: widgets/canvas/lv_example_canvas_12
|
||||
:language: c
|
||||
|
||||
|
||||
@@ -1,67 +1,69 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES
|
||||
#if LV_USE_CANVAS && LV_FONT_MONTSERRAT_18 && LV_BUILD_EXAMPLES
|
||||
|
||||
#define CANVAS_WIDTH 300
|
||||
#define CANVAS_HEIGHT 200
|
||||
|
||||
static void timer_cb(lv_timer_t * timer)
|
||||
{
|
||||
static int16_t counter = 0;
|
||||
const char * string = "lol~ I'm wavvvvvvving~>>>";
|
||||
const int16_t string_len = lv_strlen(string);
|
||||
|
||||
lv_obj_t * canvas = (lv_obj_t *)lv_timer_get_user_data(timer);
|
||||
lv_layer_t layer;
|
||||
lv_canvas_init_layer(canvas, &layer);
|
||||
|
||||
lv_canvas_fill_bg(canvas, lv_color_white(), LV_OPA_COVER);
|
||||
|
||||
lv_draw_letter_dsc_t letter_dsc;
|
||||
lv_draw_letter_dsc_init(&letter_dsc);
|
||||
letter_dsc.color = lv_color_hex(0xff0000);
|
||||
letter_dsc.font = lv_font_get_default();
|
||||
|
||||
{
|
||||
#define CURVE2_X(t) (t * 2 + 10)
|
||||
#define CURVE2_Y(t) (lv_trigo_sin((t) * 5) * 40 / 32767 + CANVAS_HEIGHT / 2)
|
||||
|
||||
int32_t pre_x = CURVE2_X(-1);
|
||||
int32_t pre_y = CURVE2_Y(-1);
|
||||
for(int16_t i = 0; i < string_len; i++) {
|
||||
const int16_t angle = (int16_t)(i * 5);
|
||||
const int32_t x = CURVE2_X(angle);
|
||||
const int32_t y = CURVE2_Y(angle + counter / 2);
|
||||
const lv_point_t point = { .x = x, .y = y };
|
||||
|
||||
letter_dsc.unicode = (uint32_t)string[i % string_len];
|
||||
letter_dsc.rotation = lv_atan2(y - pre_y, x - pre_x) * 10;
|
||||
letter_dsc.color = lv_color_hsv_to_rgb(i * 10, 100, 100);
|
||||
lv_draw_letter(&layer, &letter_dsc, &point);
|
||||
|
||||
pre_x = x;
|
||||
pre_y = y;
|
||||
}
|
||||
}
|
||||
|
||||
lv_canvas_finish_layer(canvas, &layer);
|
||||
|
||||
counter++;
|
||||
}
|
||||
#define CANVAS_WIDTH 100
|
||||
#define CANVAS_HEIGHT 100
|
||||
|
||||
/**
|
||||
*Blur an area on the canvas
|
||||
*/
|
||||
void lv_example_canvas_10(void)
|
||||
{
|
||||
/*Create a buffer for the canvas*/
|
||||
LV_DRAW_BUF_DEFINE_STATIC(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);
|
||||
LV_DRAW_BUF_DEFINE_STATIC(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_RGB565);
|
||||
LV_DRAW_BUF_INIT_STATIC(draw_buf);
|
||||
|
||||
/*Create a canvas and initialize its palette*/
|
||||
lv_obj_t * canvas = lv_canvas_create(lv_screen_active());
|
||||
lv_obj_set_size(canvas, CANVAS_WIDTH, CANVAS_HEIGHT);
|
||||
|
||||
lv_canvas_set_draw_buf(canvas, &draw_buf);
|
||||
lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);
|
||||
lv_obj_center(canvas);
|
||||
|
||||
lv_canvas_set_draw_buf(canvas, &draw_buf);
|
||||
lv_layer_t layer;
|
||||
lv_canvas_init_layer(canvas, &layer);
|
||||
|
||||
lv_timer_create(timer_cb, 16, canvas);
|
||||
/*A label in the background*/
|
||||
lv_draw_label_dsc_t label_dsc;
|
||||
lv_draw_label_dsc_init(&label_dsc);
|
||||
label_dsc.color = lv_palette_main(LV_PALETTE_RED);
|
||||
label_dsc.font = &lv_font_montserrat_14;
|
||||
label_dsc.decor = LV_TEXT_DECOR_UNDERLINE;
|
||||
label_dsc.align = LV_TEXT_ALIGN_CENTER;
|
||||
label_dsc.text = "Some parts of\nthis canvas is blurred";
|
||||
|
||||
lv_area_t label1_coords = {10, 10, 90, 90};
|
||||
|
||||
lv_draw_label(&layer, &label_dsc, &label1_coords);
|
||||
|
||||
/*Blur the middle of the canvas*/
|
||||
lv_draw_blur_dsc_t blur_dsc;
|
||||
lv_draw_blur_dsc_init(&blur_dsc);
|
||||
blur_dsc.corner_radius = 10;
|
||||
blur_dsc.blur_radius = 8;
|
||||
|
||||
lv_area_t fill_coords = {20, 30, 80, 70};
|
||||
lv_draw_blur(&layer, &blur_dsc, &fill_coords);
|
||||
|
||||
/*Draw a semi-transparent rectangle on the blurred area*/
|
||||
lv_draw_fill_dsc_t fill_dsc;
|
||||
lv_draw_fill_dsc_init(&fill_dsc);
|
||||
fill_dsc.color = lv_palette_lighten(LV_PALETTE_BLUE, 1);
|
||||
fill_dsc.radius = 10;
|
||||
fill_dsc.opa = LV_OPA_30;
|
||||
|
||||
lv_draw_fill(&layer, &fill_dsc, &fill_coords);
|
||||
|
||||
/*Add label on the blurred area*/
|
||||
lv_draw_label_dsc_init(&label_dsc);
|
||||
label_dsc.color = lv_color_black();
|
||||
label_dsc.font = &lv_font_montserrat_14;
|
||||
label_dsc.align = LV_TEXT_ALIGN_CENTER;
|
||||
label_dsc.text = "Hello world";
|
||||
|
||||
lv_area_t label2_coords = {20, 35, 80, 60};
|
||||
lv_draw_label(&layer, &label_dsc, &label2_coords);
|
||||
|
||||
lv_canvas_finish_layer(canvas, &layer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
static void timer_cb(lv_timer_t * timer)
|
||||
{
|
||||
static int32_t counter = 0;
|
||||
const char * string = "windstorrrrrrrrrrrrrrrrm~>>>";
|
||||
const char * string = "lol~ I'm wavvvvvvving~>>>";
|
||||
const int16_t string_len = lv_strlen(string);
|
||||
|
||||
lv_obj_t * canvas = (lv_obj_t *) lv_timer_get_user_data(timer);
|
||||
lv_obj_t * canvas = (lv_obj_t *)lv_timer_get_user_data(timer);
|
||||
lv_layer_t layer;
|
||||
lv_canvas_init_layer(canvas, &layer);
|
||||
|
||||
@@ -22,23 +22,21 @@ static void timer_cb(lv_timer_t * timer)
|
||||
letter_dsc.font = lv_font_get_default();
|
||||
|
||||
{
|
||||
#define CURVE2_X(t) ((t) * 2 + lv_trigo_cos((t) * 5) * 40 / 32767 - 10)
|
||||
#define CURVE2_Y(t, T) ((t) * lv_trigo_sin(((t) + (T)) * 5) * 40 / 32767 / 80 + CANVAS_HEIGHT / 2)
|
||||
#define CURVE2_X(t) (t * 2 + 10)
|
||||
#define CURVE2_Y(t) (lv_trigo_sin((t) * 5) * 40 / 32767 + CANVAS_HEIGHT / 2)
|
||||
|
||||
int32_t pre_x = CURVE2_X(-1);
|
||||
int32_t pre_y = CURVE2_Y(-1, 0);
|
||||
int32_t pre_y = CURVE2_Y(-1);
|
||||
for(int16_t i = 0; i < string_len; i++) {
|
||||
const int32_t angle = i * 5;
|
||||
const int16_t angle = (int16_t)(i * 5);
|
||||
const int32_t x = CURVE2_X(angle);
|
||||
const int32_t y = CURVE2_Y(angle + 30, counter / 2);
|
||||
const int32_t y = CURVE2_Y(angle + counter / 2);
|
||||
const lv_point_t point = { .x = x, .y = y };
|
||||
|
||||
letter_dsc.unicode = (uint32_t)string[i % string_len];
|
||||
letter_dsc.rotation = lv_atan2(y - pre_y, x - pre_x) * 10;
|
||||
letter_dsc.color = lv_color_hsv_to_rgb(i * 10, 100, 100);
|
||||
lv_point_t p = (lv_point_t) {
|
||||
.x = x, .y = y
|
||||
};
|
||||
lv_draw_letter(&layer, &letter_dsc, &p);
|
||||
lv_draw_letter(&layer, &letter_dsc, &point);
|
||||
|
||||
pre_x = x;
|
||||
pre_y = y;
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES
|
||||
|
||||
#define CANVAS_WIDTH 300
|
||||
#define CANVAS_HEIGHT 200
|
||||
|
||||
static void timer_cb(lv_timer_t * timer)
|
||||
{
|
||||
static int32_t counter = 0;
|
||||
const char * string = "windstorrrrrrrrrrrrrrrrm~>>>";
|
||||
const int16_t string_len = lv_strlen(string);
|
||||
|
||||
lv_obj_t * canvas = (lv_obj_t *) lv_timer_get_user_data(timer);
|
||||
lv_layer_t layer;
|
||||
lv_canvas_init_layer(canvas, &layer);
|
||||
|
||||
lv_canvas_fill_bg(canvas, lv_color_white(), LV_OPA_COVER);
|
||||
|
||||
lv_draw_letter_dsc_t letter_dsc;
|
||||
lv_draw_letter_dsc_init(&letter_dsc);
|
||||
letter_dsc.color = lv_color_hex(0xff0000);
|
||||
letter_dsc.font = lv_font_get_default();
|
||||
|
||||
{
|
||||
#define CURVE2_X(t) ((t) * 2 + lv_trigo_cos((t) * 5) * 40 / 32767 - 10)
|
||||
#define CURVE2_Y(t, T) ((t) * lv_trigo_sin(((t) + (T)) * 5) * 40 / 32767 / 80 + CANVAS_HEIGHT / 2)
|
||||
|
||||
int32_t pre_x = CURVE2_X(-1);
|
||||
int32_t pre_y = CURVE2_Y(-1, 0);
|
||||
for(int16_t i = 0; i < string_len; i++) {
|
||||
const int32_t angle = i * 5;
|
||||
const int32_t x = CURVE2_X(angle);
|
||||
const int32_t y = CURVE2_Y(angle + 30, counter / 2);
|
||||
|
||||
letter_dsc.unicode = (uint32_t)string[i % string_len];
|
||||
letter_dsc.rotation = lv_atan2(y - pre_y, x - pre_x) * 10;
|
||||
letter_dsc.color = lv_color_hsv_to_rgb(i * 10, 100, 100);
|
||||
lv_point_t p = (lv_point_t) {
|
||||
.x = x, .y = y
|
||||
};
|
||||
lv_draw_letter(&layer, &letter_dsc, &p);
|
||||
|
||||
pre_x = x;
|
||||
pre_y = y;
|
||||
}
|
||||
}
|
||||
|
||||
lv_canvas_finish_layer(canvas, &layer);
|
||||
|
||||
counter++;
|
||||
}
|
||||
|
||||
void lv_example_canvas_12(void)
|
||||
{
|
||||
/*Create a buffer for the canvas*/
|
||||
LV_DRAW_BUF_DEFINE_STATIC(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);
|
||||
LV_DRAW_BUF_INIT_STATIC(draw_buf);
|
||||
|
||||
lv_obj_t * canvas = lv_canvas_create(lv_screen_active());
|
||||
lv_obj_set_size(canvas, CANVAS_WIDTH, CANVAS_HEIGHT);
|
||||
|
||||
lv_obj_center(canvas);
|
||||
|
||||
lv_canvas_set_draw_buf(canvas, &draw_buf);
|
||||
|
||||
lv_timer_create(timer_cb, 16, canvas);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -63,6 +63,7 @@ void lv_example_canvas_8(void);
|
||||
void lv_example_canvas_9(void);
|
||||
void lv_example_canvas_10(void);
|
||||
void lv_example_canvas_11(void);
|
||||
void lv_example_canvas_12(void);
|
||||
|
||||
void lv_example_chart_1(void);
|
||||
void lv_example_chart_2(void);
|
||||
@@ -118,6 +119,7 @@ void lv_example_menu_5(void);
|
||||
|
||||
void lv_example_msgbox_1(void);
|
||||
void lv_example_msgbox_2(void);
|
||||
void lv_example_msgbox_3(void);
|
||||
|
||||
void lv_example_obj_1(void);
|
||||
void lv_example_obj_2(void);
|
||||
|
||||
@@ -11,4 +11,10 @@ Scrolling and styled Message box
|
||||
.. lv_example:: widgets/msgbox/lv_example_msgbox_2
|
||||
:language: c
|
||||
|
||||
Message box with blurred background
|
||||
-----------------------------------
|
||||
|
||||
.. lv_example:: widgets/msgbox/lv_example_msgbox_3
|
||||
:language: c
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_MSGBOX && LV_BUILD_EXAMPLES
|
||||
|
||||
static void dropdown_value_changed_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * dropdown = lv_event_get_target_obj(e);
|
||||
lv_obj_t * msgbox = (lv_obj_t *)lv_event_get_user_data(e);
|
||||
lv_obj_t * top_layer = lv_layer_top();
|
||||
uint32_t opt = lv_dropdown_get_selected(dropdown);
|
||||
|
||||
/*Blur screen*/
|
||||
if(opt == 0) {
|
||||
lv_obj_set_style_blur_radius(msgbox, 0, 0);
|
||||
lv_obj_set_style_blur_radius(top_layer, 24, 0);
|
||||
}
|
||||
/*Blur Message box*/
|
||||
else {
|
||||
lv_obj_set_style_blur_radius(msgbox, 24, 0);
|
||||
lv_obj_set_style_blur_radius(top_layer, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_example_msgbox_3(void)
|
||||
{
|
||||
|
||||
lv_obj_t * label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(label, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
||||
" Ut orci mauris, placerat et euismod eu, ullamcorper eget massa. "
|
||||
"Suspendisse sodales vitae augue ut vestibulum. "
|
||||
"Nunc fringilla leo ut tellus consectetur tincidunt. "
|
||||
"Quisque eu tortor semper odio aliquet congue egestas ac massa. "
|
||||
"Phasellus elit lectus, finibus tempor augue in, elementum lobortis nisl. "
|
||||
"Donec tristique lorem et tincidunt faucibus.\n\n"
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
||||
" Ut orci mauris, placerat et euismod eu, ullamcorper eget massa. "
|
||||
"Suspendisse sodales vitae augue ut vestibulum. "
|
||||
"Nunc fringilla leo ut tellus consectetur tincidunt. "
|
||||
"Quisque eu tortor semper odio aliquet congue egestas ac massa. "
|
||||
"Phasellus elit lectus, finibus tempor augue in, elementum lobortis nisl. "
|
||||
"Donec tristique lorem et tincidunt faucibus.");
|
||||
|
||||
lv_obj_set_width(label, lv_pct(60));
|
||||
lv_obj_center(label);
|
||||
lv_obj_set_style_text_color(label, lv_palette_main(LV_PALETTE_BLUE), 0);
|
||||
|
||||
lv_obj_t * msgbox1 = lv_msgbox_create(lv_layer_top());
|
||||
lv_msgbox_add_title(msgbox1, "Setting");
|
||||
lv_msgbox_add_text(msgbox1, "Hello!\n\n"
|
||||
"Scroll the text in the background to see how it behaves.");
|
||||
|
||||
/*Just a little styling on the message box*/
|
||||
lv_obj_set_style_bg_opa(msgbox1, LV_OPA_40, 0);
|
||||
lv_obj_set_style_bg_opa(lv_msgbox_get_header(msgbox1), LV_OPA_50, 0);
|
||||
lv_obj_set_style_bg_color(lv_msgbox_get_header(msgbox1), lv_color_black(), 0);
|
||||
lv_obj_set_style_bg_color(msgbox1, lv_color_black(), 0);
|
||||
lv_obj_set_style_text_color(msgbox1, lv_color_white(), 0);
|
||||
lv_obj_set_style_text_color(lv_msgbox_get_header(msgbox1), lv_color_white(), 0);
|
||||
lv_obj_set_style_blur_backdrop(msgbox1, true, 0);
|
||||
|
||||
/*A dropdown to select what to blur*/
|
||||
lv_obj_t * dropdown = lv_dropdown_create(lv_layer_top());
|
||||
lv_dropdown_set_options(dropdown, "Blur screen\nBlur msgbox");
|
||||
lv_obj_set_pos(dropdown, 5, 5);
|
||||
lv_obj_add_event_cb(dropdown, dropdown_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, msgbox1);
|
||||
/*Also make the list blurred*/
|
||||
lv_obj_set_style_blur_radius(lv_dropdown_get_list(dropdown), 24, 0);
|
||||
lv_obj_set_style_blur_backdrop(lv_dropdown_get_list(dropdown), true, 0);
|
||||
lv_obj_set_style_bg_opa(lv_dropdown_get_list(dropdown), LV_OPA_50, 0);
|
||||
|
||||
/*Send a value changed event to set the initial state*/
|
||||
lv_obj_send_event(dropdown, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -401,6 +401,18 @@ props = [
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_TRANSP`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Sets the intensity of color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent. A value of 255, `LV_OPA_100` or `LV_OPA_COVER` means fully opaque. Intermediate values like LV_OPA_10, LV_OPA_20, etc result in semi-transparency."},
|
||||
|
||||
{'name': 'BLUR_RADIUS',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':'`0`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Sets the intensity of blurring. Applied on each lv_part separately before the children are rendered."},
|
||||
|
||||
{'name': 'BLUR_BACKDROP',
|
||||
'style_type': 'num', 'var_type': 'bool', 'default':'`false`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "If `true` the background of the widget will be blurred. The part should have < 100% opacity to make it visible. If `false` the given part will be blurred when it's rendered but before drawing the children."},
|
||||
|
||||
{'name': 'BLUR_QUALITY',
|
||||
'style_type': 'num', 'var_type': 'lv_blur_quality_t', 'default':'`LV_BLUR_QUALITY_AUTO`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Setting to `LV_BLUR_QUALITY_SPEED` the blurring algorithm will prefer speed over quality. `LV_BLUR_QUALITY_PRECISION` will force using higher quality but slower blur. With `LV_BLUR_QUALITY_AUTO` the quality will be selected automatically. "},
|
||||
|
||||
{'name': 'ANIM',
|
||||
'style_type': 'ptr', 'var_type': 'const lv_anim_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Animation template for Widget's animation. Should be a pointer to `lv_anim_t`. The animation parameters are widget specific, e.g. animation time could be the E.g. blink time of the cursor on the Text Area or scroll time of a roller. See Widgets' documentation to learn more."},
|
||||
|
||||
@@ -693,10 +693,20 @@ static void lv_obj_draw(lv_event_t * e)
|
||||
}
|
||||
else if(code == LV_EVENT_DRAW_MAIN) {
|
||||
lv_layer_t * layer = lv_event_get_layer(e);
|
||||
|
||||
lv_draw_rect_dsc_t draw_dsc;
|
||||
lv_draw_rect_dsc_init(&draw_dsc);
|
||||
draw_dsc.base.layer = layer;
|
||||
|
||||
lv_draw_blur_dsc_t blur_dsc;
|
||||
lv_draw_blur_dsc_init(&blur_dsc);
|
||||
blur_dsc.corner_radius = draw_dsc.radius;
|
||||
|
||||
bool backdrop_blur = lv_obj_get_style_blur_backdrop(obj, LV_PART_INDICATOR);
|
||||
lv_obj_init_draw_blur_dsc(obj, LV_PART_MAIN, &blur_dsc);
|
||||
blur_dsc.base.layer = layer;
|
||||
if(backdrop_blur) lv_draw_blur(layer, &blur_dsc, &obj->coords);
|
||||
|
||||
lv_obj_init_draw_rect_dsc(obj, LV_PART_MAIN, &draw_dsc);
|
||||
/*If the border is drawn later disable loading its properties*/
|
||||
if(lv_obj_get_style_border_post(obj, LV_PART_MAIN)) {
|
||||
@@ -710,6 +720,9 @@ static void lv_obj_draw(lv_event_t * e)
|
||||
lv_area_increase(&coords, w, h);
|
||||
|
||||
lv_draw_rect(layer, &draw_dsc, &coords);
|
||||
|
||||
blur_dsc.blur_radius = lv_obj_get_style_blur_radius(obj, LV_PART_MAIN);
|
||||
if(!backdrop_blur) lv_draw_blur(layer, &blur_dsc, &coords);
|
||||
}
|
||||
else if(code == LV_EVENT_DRAW_POST) {
|
||||
lv_layer_t * layer = lv_event_get_layer(e);
|
||||
@@ -747,17 +760,34 @@ static void draw_scrollbar(lv_obj_t * obj, lv_layer_t * layer)
|
||||
|
||||
if(lv_area_get_size(&hor_area) <= 0 && lv_area_get_size(&ver_area) <= 0) return;
|
||||
|
||||
lv_draw_rect_dsc_t draw_dsc;
|
||||
lv_result_t sb_res = scrollbar_init_draw_dsc(obj, &draw_dsc);
|
||||
lv_draw_rect_dsc_t rect_dsc;
|
||||
lv_result_t sb_res = scrollbar_init_draw_dsc(obj, &rect_dsc);
|
||||
if(sb_res != LV_RESULT_OK) return;
|
||||
|
||||
bool backdrop_blur = lv_obj_get_style_blur_backdrop(obj, LV_PART_SCROLLBAR);
|
||||
lv_draw_blur_dsc_t blur_dsc;
|
||||
lv_draw_blur_dsc_init(&blur_dsc);
|
||||
blur_dsc.corner_radius = rect_dsc.radius;
|
||||
blur_dsc.blur_radius = lv_obj_get_style_blur_radius(obj, LV_PART_SCROLLBAR);
|
||||
|
||||
if(lv_area_get_size(&hor_area) > 0) {
|
||||
draw_dsc.base.id1 = 0;
|
||||
lv_draw_rect(layer, &draw_dsc, &hor_area);
|
||||
if(backdrop_blur) lv_obj_init_draw_blur_dsc(obj, LV_PART_SCROLLBAR, &blur_dsc);
|
||||
blur_dsc.base.id1 = 0;
|
||||
lv_draw_blur(layer, &blur_dsc, &hor_area);
|
||||
|
||||
rect_dsc.base.id1 = 0;
|
||||
lv_draw_rect(layer, &rect_dsc, &hor_area);
|
||||
|
||||
if(!backdrop_blur) lv_draw_blur(layer, &blur_dsc, &hor_area);
|
||||
}
|
||||
if(lv_area_get_size(&ver_area) > 0) {
|
||||
draw_dsc.base.id1 = 1;
|
||||
lv_draw_rect(layer, &draw_dsc, &ver_area);
|
||||
blur_dsc.base.id1 = 1;
|
||||
if(backdrop_blur) lv_draw_blur(layer, &blur_dsc, &ver_area);
|
||||
|
||||
rect_dsc.base.id1 = 1;
|
||||
lv_draw_rect(layer, &rect_dsc, &ver_area);
|
||||
|
||||
if(!backdrop_blur) lv_draw_blur(layer, &blur_dsc, &ver_area);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "../display/lv_display.h"
|
||||
#include "../indev/lv_indev.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
#include "../draw/lv_draw_arc.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -319,6 +318,24 @@ void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_arc_dsc_t
|
||||
LV_PROFILER_DRAW_END;
|
||||
}
|
||||
|
||||
void lv_obj_init_draw_blur_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_blur_dsc_t * draw_dsc)
|
||||
{
|
||||
LV_PROFILER_DRAW_BEGIN;
|
||||
draw_dsc->base.obj = obj;
|
||||
draw_dsc->base.part = part;
|
||||
|
||||
draw_dsc->blur_radius = lv_obj_get_style_blur_radius(obj, part);
|
||||
draw_dsc->quality = lv_obj_get_style_blur_quality(obj, part);
|
||||
|
||||
/*Radius might be set earlier as it's already known*/
|
||||
if(draw_dsc->corner_radius == 0) {
|
||||
draw_dsc->corner_radius = lv_obj_get_style_radius(obj, part);
|
||||
}
|
||||
|
||||
LV_PROFILER_DRAW_END;
|
||||
}
|
||||
|
||||
|
||||
int32_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
LV_PROFILER_DRAW_BEGIN;
|
||||
|
||||
@@ -20,6 +20,7 @@ extern "C" {
|
||||
#include "../draw/lv_draw_line.h"
|
||||
#include "../draw/lv_draw_arc.h"
|
||||
#include "../draw/lv_draw_triangle.h"
|
||||
#include "../draw/lv_draw_blur.h"
|
||||
#include "lv_obj_style.h"
|
||||
|
||||
/*********************
|
||||
@@ -103,6 +104,18 @@ void lv_obj_init_draw_line_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_line_dsc_
|
||||
*/
|
||||
void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_arc_dsc_t * draw_dsc);
|
||||
|
||||
|
||||
/**
|
||||
* Initialize a blur draw descriptor from an object's styles in its current state.
|
||||
* draw_dsc->radius will only be calculated if it's 0 initially. Radius can be set before calling this function
|
||||
* to avoid getting it twice.
|
||||
* @param obj pointer to an object
|
||||
* @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc
|
||||
* @param draw_dsc the descriptor to initialize.
|
||||
* Should be initialized with `lv_draw_blur_dsc_init(draw_dsc)`.
|
||||
*/
|
||||
void lv_obj_init_draw_blur_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_blur_dsc_t * draw_dsc);
|
||||
|
||||
/**
|
||||
* Get the required extra size (around the object's part) to draw shadow, outline, value etc.
|
||||
* @param obj pointer to an object
|
||||
|
||||
@@ -36,6 +36,8 @@ static void layout_update_core(lv_obj_t * obj);
|
||||
static void transform_point_array(const lv_obj_t * obj, lv_point_t * p, size_t p_count, bool inv);
|
||||
static bool is_transformed(const lv_obj_t * obj);
|
||||
static lv_obj_tree_walk_res_t update_layout_completed_cb(lv_obj_t * obj, void * user_data);
|
||||
static lv_result_t invalidate_area_core(const lv_obj_t * obj, lv_area_t * area_tmp);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@@ -860,35 +862,94 @@ void lv_obj_get_transformed_area(const lv_obj_t * obj, lv_area_t * area, lv_obj_
|
||||
area->y2 = LV_MAX4(p[0].y, p[1].y, p[2].y, p[3].y);
|
||||
}
|
||||
|
||||
void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area)
|
||||
typedef struct {
|
||||
const lv_obj_t * requester_obj;
|
||||
const lv_area_t * inv_area;
|
||||
} blur_walk_data_t;
|
||||
|
||||
static lv_obj_tree_walk_res_t blur_walk_cb(lv_obj_t * obj, void * user_data)
|
||||
{
|
||||
blur_walk_data_t * blur_data = user_data;
|
||||
if(obj == blur_data->requester_obj) return LV_OBJ_TREE_WALK_SKIP_CHILDREN;
|
||||
|
||||
/*Truncate the area to the object*/
|
||||
lv_area_t obj_coords;
|
||||
int32_t ext_size = lv_obj_get_ext_draw_size(obj);
|
||||
lv_area_copy(&obj_coords, &obj->coords);
|
||||
lv_area_increase(&obj_coords, ext_size, ext_size);
|
||||
|
||||
if(is_transformed(obj)) {
|
||||
lv_obj_get_transformed_area(obj, &obj_coords, LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE);
|
||||
}
|
||||
|
||||
/*If the widget has blur set, invalidate it*/
|
||||
if(lv_area_is_on(blur_data->inv_area, &obj_coords)) {
|
||||
const uint32_t group = (uint32_t)1 << lv_style_get_prop_group(LV_STYLE_BLUR_RADIUS);
|
||||
const lv_state_t state = lv_obj_style_get_selector_state(lv_obj_get_state(obj));
|
||||
const lv_state_t state_inv = ~state;
|
||||
lv_style_value_t v;
|
||||
uint32_t i;
|
||||
for(i = 0; i < obj->style_cnt; i++) {
|
||||
lv_obj_style_t * obj_style = &obj->styles[i];
|
||||
if(obj_style->is_disabled) continue;
|
||||
if((obj_style->style->has_group & group) == 0) continue;
|
||||
lv_state_t state_style = lv_obj_style_get_selector_state(obj->styles[i].selector);
|
||||
if((state_style & state_inv)) continue;
|
||||
if(lv_style_get_prop(obj_style->style, LV_STYLE_BLUR_RADIUS, &v)) {
|
||||
/*Truncate the area to the object*/
|
||||
ext_size = lv_obj_get_ext_draw_size(obj);
|
||||
lv_area_copy(&obj_coords, &obj->coords);
|
||||
obj_coords.x1 -= ext_size;
|
||||
obj_coords.y1 -= ext_size;
|
||||
obj_coords.x2 += ext_size;
|
||||
obj_coords.y2 += ext_size;
|
||||
|
||||
invalidate_area_core(obj, &obj_coords);
|
||||
|
||||
/*No need to check the children as the widget is already invalidated
|
||||
*which will redraw the children too*/
|
||||
return LV_OBJ_TREE_WALK_SKIP_CHILDREN;
|
||||
}
|
||||
}
|
||||
|
||||
/*Check the next child, maybe it's blurred*/
|
||||
return LV_OBJ_TREE_WALK_NEXT;
|
||||
}
|
||||
else {
|
||||
/*Not on the area of interest, skip it*/
|
||||
return LV_OBJ_TREE_WALK_SKIP_CHILDREN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
lv_result_t lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_display_t * disp = lv_obj_get_display(obj);
|
||||
if(!lv_display_is_invalidation_enabled(disp)) return;
|
||||
if(!lv_display_is_invalidation_enabled(disp)) return LV_RESULT_INVALID;
|
||||
|
||||
lv_area_t area_tmp;
|
||||
lv_area_copy(&area_tmp, area);
|
||||
|
||||
if(!lv_obj_area_is_visible(obj, &area_tmp)) return;
|
||||
#if LV_DRAW_TRANSFORM_USE_MATRIX
|
||||
/**
|
||||
* When using the global matrix, the vertex coordinates of clip_area lose precision after transformation,
|
||||
* which can be solved by expanding the redrawing area.
|
||||
*/
|
||||
lv_area_increase(&area_tmp, 5, 5);
|
||||
#else
|
||||
if(obj->spec_attr && obj->spec_attr->layer_type == LV_LAYER_TYPE_TRANSFORM) {
|
||||
/*Make the area slightly larger to avoid rounding errors.
|
||||
*5 is an empirical value*/
|
||||
lv_area_increase(&area_tmp, 5, 5);
|
||||
}
|
||||
#endif
|
||||
lv_result_t res = invalidate_area_core(obj, &area_tmp);
|
||||
if(res == LV_RESULT_INVALID) return res;
|
||||
|
||||
lv_inv_area(lv_obj_get_display(obj), &area_tmp);
|
||||
/*If this area is on a blurred widget, invalidate that widget too*/
|
||||
blur_walk_data_t blur_walk_data;
|
||||
blur_walk_data.requester_obj = obj;
|
||||
blur_walk_data.inv_area = &area_tmp;
|
||||
lv_obj_tree_walk(disp->act_scr, blur_walk_cb, &blur_walk_data);
|
||||
if(disp->prev_scr) lv_obj_tree_walk(disp->prev_scr, blur_walk_cb, &blur_walk_data);
|
||||
lv_obj_tree_walk(disp->sys_layer, blur_walk_cb, &blur_walk_data);
|
||||
lv_obj_tree_walk(disp->top_layer, blur_walk_cb, &blur_walk_data);
|
||||
lv_obj_tree_walk(disp->bottom_layer, blur_walk_cb, &blur_walk_data);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void lv_obj_invalidate(const lv_obj_t * obj)
|
||||
|
||||
lv_result_t lv_obj_invalidate(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
@@ -901,7 +962,9 @@ void lv_obj_invalidate(const lv_obj_t * obj)
|
||||
obj_coords.x2 += ext_size;
|
||||
obj_coords.y2 += ext_size;
|
||||
|
||||
lv_obj_invalidate_area(obj, &obj_coords);
|
||||
lv_result_t res = lv_obj_invalidate_area(obj, &obj_coords);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool lv_obj_area_is_visible(const lv_obj_t * obj, lv_area_t * area)
|
||||
@@ -1351,4 +1414,26 @@ static lv_obj_tree_walk_res_t update_layout_completed_cb(lv_obj_t * obj, void *
|
||||
LV_UNUSED(user_data);
|
||||
lv_obj_send_event(obj, LV_EVENT_UPDATE_LAYOUT_COMPLETED, NULL);
|
||||
return LV_OBJ_TREE_WALK_NEXT;
|
||||
}
|
||||
}
|
||||
|
||||
static lv_result_t invalidate_area_core(const lv_obj_t * obj, lv_area_t * area_tmp)
|
||||
{
|
||||
if(!lv_obj_area_is_visible(obj, area_tmp)) return LV_RESULT_INVALID;
|
||||
#if LV_DRAW_TRANSFORM_USE_MATRIX
|
||||
/**
|
||||
* When using the global matrix, the vertex coordinates of clip_area lose precision after transformation,
|
||||
* which can be solved by expanding the redrawing area.
|
||||
*/
|
||||
lv_area_increase(area_tmp, 5, 5);
|
||||
#else
|
||||
if(obj->spec_attr && obj->spec_attr->layer_type == LV_LAYER_TYPE_TRANSFORM) {
|
||||
/*Make the area slightly larger to avoid rounding errors.
|
||||
*5 is an empirical value*/
|
||||
lv_area_increase(area_tmp, 5, 5);
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_result_t res = lv_inv_area(lv_obj_get_display(obj), area_tmp);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -401,14 +401,18 @@ void lv_obj_get_transformed_area(const lv_obj_t * obj, lv_area_t * area, lv_obj_
|
||||
* The area will be truncated to the object's area and marked for redraw.
|
||||
* @param obj pointer to an object
|
||||
* @param area the area to redraw
|
||||
* @return LV_RESULT_OK: the area is invalidated; LV_RESULT_INVALID: the area wasn't invalidated.
|
||||
* (maybe it was off-screen or fully clipped)
|
||||
*/
|
||||
void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area);
|
||||
lv_result_t lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area);
|
||||
|
||||
/**
|
||||
* Mark the object as invalid to redrawn its area
|
||||
* @param obj pointer to an object
|
||||
* @return LV_RESULT_OK: the area is invalidated; LV_RESULT_INVALID: the area wasn't invalidated.
|
||||
* (maybe it was off-screen or fully clipped)
|
||||
*/
|
||||
void lv_obj_invalidate(const lv_obj_t * obj);
|
||||
lv_result_t lv_obj_invalidate(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Tell whether an area of an object is visible (even partially) now or not
|
||||
|
||||
@@ -746,7 +746,8 @@ void lv_obj_set_style_opa_layered(lv_obj_t * obj, lv_opa_t value, lv_style_selec
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_OPA_LAYERED, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_color_filter_dsc(lv_obj_t * obj, const lv_color_filter_dsc_t * value, lv_style_selector_t selector)
|
||||
void lv_obj_set_style_color_filter_dsc(lv_obj_t * obj, const lv_color_filter_dsc_t * value,
|
||||
lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.ptr = value
|
||||
@@ -778,6 +779,30 @@ void lv_obj_set_style_recolor_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selec
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_RECOLOR_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_blur_radius(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BLUR_RADIUS, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_blur_backdrop(lv_obj_t * obj, bool value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BLUR_BACKDROP, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_blur_quality(lv_obj_t * obj, lv_blur_quality_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BLUR_QUALITY, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_anim(lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
|
||||
@@ -243,7 +243,8 @@ static inline lv_color_t lv_obj_get_style_bg_grad_color(const lv_obj_t * obj, lv
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_bg_grad_color_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_COLOR));
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
||||
LV_STYLE_BG_GRAD_COLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
@@ -303,7 +304,8 @@ static inline lv_color_t lv_obj_get_style_bg_image_recolor(const lv_obj_t * obj,
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_bg_image_recolor_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_RECOLOR));
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
||||
LV_STYLE_BG_IMAGE_RECOLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
@@ -327,7 +329,8 @@ static inline lv_color_t lv_obj_get_style_border_color(const lv_obj_t * obj, lv_
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_border_color_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_COLOR));
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
||||
LV_STYLE_BORDER_COLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
@@ -369,7 +372,8 @@ static inline lv_color_t lv_obj_get_style_outline_color(const lv_obj_t * obj, lv
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_outline_color_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_COLOR));
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
||||
LV_STYLE_OUTLINE_COLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
@@ -417,7 +421,8 @@ static inline lv_color_t lv_obj_get_style_shadow_color(const lv_obj_t * obj, lv_
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_shadow_color_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_COLOR));
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
||||
LV_STYLE_SHADOW_COLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
@@ -441,7 +446,8 @@ static inline lv_color_t lv_obj_get_style_image_recolor(const lv_obj_t * obj, lv
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_image_recolor_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_IMAGE_RECOLOR));
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
||||
LV_STYLE_IMAGE_RECOLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
@@ -591,7 +597,8 @@ static inline lv_color_t lv_obj_get_style_text_outline_stroke_color(const lv_obj
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_text_outline_stroke_color_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_OUTLINE_STROKE_COLOR));
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
||||
LV_STYLE_TEXT_OUTLINE_STROKE_COLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
@@ -661,6 +668,24 @@ static inline lv_opa_t lv_obj_get_style_recolor_opa(const lv_obj_t * obj, lv_par
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_blur_radius(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BLUR_RADIUS);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline bool lv_obj_get_style_blur_backdrop(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BLUR_BACKDROP);
|
||||
return (bool)v.num;
|
||||
}
|
||||
|
||||
static inline lv_blur_quality_t lv_obj_get_style_blur_quality(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BLUR_QUALITY);
|
||||
return (lv_blur_quality_t)v.num;
|
||||
}
|
||||
|
||||
static inline const lv_anim_t * lv_obj_get_style_anim(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ANIM);
|
||||
@@ -897,10 +922,14 @@ void lv_obj_set_style_radial_offset(lv_obj_t * obj, int32_t value, lv_style_sele
|
||||
void lv_obj_set_style_clip_corner(lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_opa_layered(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_color_filter_dsc(lv_obj_t * obj, const lv_color_filter_dsc_t * value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_color_filter_dsc(lv_obj_t * obj, const lv_color_filter_dsc_t * value,
|
||||
lv_style_selector_t selector);
|
||||
void lv_obj_set_style_color_filter_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_recolor(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_recolor_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_blur_radius(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_blur_backdrop(lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_blur_quality(lv_obj_t * obj, lv_blur_quality_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_anim(lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_anim_duration(lv_obj_t * obj, uint32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_transition(lv_obj_t * obj, const lv_style_transition_dsc_t * value, lv_style_selector_t selector);
|
||||
|
||||
@@ -266,11 +266,11 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj)
|
||||
LV_PROFILER_REFR_END;
|
||||
}
|
||||
|
||||
void lv_inv_area(lv_display_t * disp, const lv_area_t * area_p)
|
||||
lv_result_t lv_inv_area(lv_display_t * disp, const lv_area_t * area_p)
|
||||
{
|
||||
if(!disp) disp = lv_display_get_default();
|
||||
if(!disp) return;
|
||||
if(!lv_display_is_invalidation_enabled(disp)) return;
|
||||
if(!disp) return LV_RESULT_INVALID;
|
||||
if(!lv_display_is_invalidation_enabled(disp)) return LV_RESULT_INVALID;
|
||||
|
||||
/**
|
||||
* There are two reasons for this issue:
|
||||
@@ -288,7 +288,7 @@ void lv_inv_area(lv_display_t * disp, const lv_area_t * area_p)
|
||||
/*Clear the invalidate buffer if the parameter is NULL*/
|
||||
if(area_p == NULL) {
|
||||
disp->inv_p = 0;
|
||||
return;
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_area_t scr_area;
|
||||
@@ -301,7 +301,7 @@ void lv_inv_area(lv_display_t * disp, const lv_area_t * area_p)
|
||||
bool suc;
|
||||
|
||||
suc = lv_area_intersect(&com_area, area_p, &scr_area);
|
||||
if(suc == false) return; /*Out of the screen*/
|
||||
if(suc == false) return LV_RESULT_INVALID; /*Out of the screen*/
|
||||
|
||||
if(disp->color_format == LV_COLOR_FORMAT_I1) {
|
||||
/*Make sure that the X coordinates start and end on byte boundary.
|
||||
@@ -315,16 +315,16 @@ void lv_inv_area(lv_display_t * disp, const lv_area_t * area_p)
|
||||
disp->inv_areas[0] = scr_area;
|
||||
disp->inv_p = 1;
|
||||
lv_display_send_event(disp, LV_EVENT_REFR_REQUEST, NULL);
|
||||
return;
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t res = lv_display_send_event(disp, LV_EVENT_INVALIDATE_AREA, &com_area);
|
||||
if(res != LV_RESULT_OK) return;
|
||||
if(res != LV_RESULT_OK) return LV_RESULT_INVALID;
|
||||
|
||||
/*Save only if this area is not in one of the saved areas*/
|
||||
uint16_t i;
|
||||
for(i = 0; i < disp->inv_p; i++) {
|
||||
if(lv_area_is_in(&com_area, &disp->inv_areas[i], 0) != false) return;
|
||||
if(lv_area_is_in(&com_area, &disp->inv_areas[i], 0) != false) return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
/*Save the area*/
|
||||
@@ -337,6 +337,8 @@ void lv_inv_area(lv_display_t * disp, const lv_area_t * area_p)
|
||||
disp->inv_p++;
|
||||
|
||||
lv_display_send_event(disp, LV_EVENT_REFR_REQUEST, NULL);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,8 +43,9 @@ void lv_refr_deinit(void);
|
||||
* @param area_p pointer to area which should be invalidated (NULL: delete the invalidated areas)
|
||||
* @param disp pointer to display where the area should be invalidated (NULL can be used if there is
|
||||
* only one display)
|
||||
* @return LV_RESULT_OK: the area is invalidated; LV_RESULT_INVALID: the area wasn't invalidated.
|
||||
*/
|
||||
void lv_inv_area(lv_display_t * disp, const lv_area_t * area_p);
|
||||
lv_result_t lv_inv_area(lv_display_t * disp, const lv_area_t * area_p);
|
||||
|
||||
/**
|
||||
* Get the display which is being refreshed
|
||||
|
||||
@@ -605,6 +605,8 @@ static inline size_t get_draw_dsc_size(lv_draw_task_type_t type)
|
||||
return sizeof(lv_draw_arc_dsc_t);
|
||||
case LV_DRAW_TASK_TYPE_TRIANGLE:
|
||||
return sizeof(lv_draw_triangle_dsc_t);
|
||||
case LV_DRAW_TASK_TYPE_BLUR:
|
||||
return sizeof(lv_draw_blur_dsc_t);
|
||||
case LV_DRAW_TASK_TYPE_MASK_RECTANGLE:
|
||||
return sizeof(lv_draw_mask_rect_dsc_t);
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ typedef enum {
|
||||
LV_DRAW_TASK_TYPE_TRIANGLE,
|
||||
LV_DRAW_TASK_TYPE_MASK_RECTANGLE,
|
||||
LV_DRAW_TASK_TYPE_MASK_BITMAP,
|
||||
LV_DRAW_TASK_TYPE_BLUR,
|
||||
#if LV_USE_VECTOR_GRAPHIC
|
||||
LV_DRAW_TASK_TYPE_VECTOR,
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @file lv_draw_blur.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_private.h"
|
||||
#include "lv_draw_blur.h"
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void LV_ATTRIBUTE_FAST_MEM lv_draw_blur_dsc_init(lv_draw_blur_dsc_t * dsc)
|
||||
{
|
||||
lv_memzero(dsc, sizeof(lv_draw_blur_dsc_t));
|
||||
dsc->base.dsc_size = sizeof(lv_draw_blur_dsc_t);
|
||||
}
|
||||
|
||||
lv_draw_blur_dsc_t * lv_draw_task_get_blur_dsc(lv_draw_task_t * task)
|
||||
{
|
||||
return task->type == LV_DRAW_TASK_TYPE_BLUR ? (lv_draw_blur_dsc_t *)task->draw_dsc : NULL;
|
||||
}
|
||||
|
||||
void LV_ATTRIBUTE_FAST_MEM lv_draw_blur(lv_layer_t * layer, const lv_draw_blur_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->blur_radius <= 0) return;
|
||||
|
||||
LV_PROFILER_DRAW_BEGIN;
|
||||
|
||||
lv_draw_task_t * t = lv_draw_add_task(layer, coords, LV_DRAW_TASK_TYPE_BLUR);
|
||||
|
||||
lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc));
|
||||
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
LV_PROFILER_DRAW_END;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* @file lv_draw_blur.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_BLUR_H
|
||||
#define LV_DRAW_BLUR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
#include "../misc/lv_color.h"
|
||||
#include "../misc/lv_area.h"
|
||||
#include "../misc/lv_style.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
lv_draw_dsc_base_t base;
|
||||
|
||||
/**
|
||||
* The intensity of blur.
|
||||
*/
|
||||
int32_t blur_radius;
|
||||
|
||||
/**
|
||||
* The corner radius of the blurred area
|
||||
*/
|
||||
int32_t corner_radius;
|
||||
|
||||
/**
|
||||
* Sets whether to prefer speed or precision
|
||||
*/
|
||||
lv_blur_quality_t quality;
|
||||
|
||||
} lv_draw_blur_dsc_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize a blur draw descriptor
|
||||
* @param dsc pointer to a draw descriptor
|
||||
*/
|
||||
void lv_draw_blur_dsc_init(lv_draw_blur_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Try to get a blur draw descriptor from a draw task.
|
||||
* @param task draw task
|
||||
* @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_BLUR
|
||||
*/
|
||||
lv_draw_blur_dsc_t * lv_draw_task_get_blur_dsc(lv_draw_task_t * task);
|
||||
|
||||
/**
|
||||
* Create a blur draw task
|
||||
* @param layer pointer to a layer
|
||||
* @param dsc pointer to an initialized `lv_draw_blur_dsc_t` variable
|
||||
* @param coords coordinates of the character
|
||||
*/
|
||||
void lv_draw_blur(lv_layer_t * layer, const lv_draw_blur_dsc_t * dsc, const lv_area_t * coords);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_BLUR_H*/
|
||||
@@ -409,6 +409,9 @@ static void execute_drawing(lv_draw_task_t * t)
|
||||
case LV_DRAW_TASK_TYPE_LINE:
|
||||
lv_draw_sw_line(t, t->draw_dsc);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_BLUR:
|
||||
lv_draw_sw_blur(t, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_TRIANGLE:
|
||||
lv_draw_sw_triangle(t, t->draw_dsc);
|
||||
break;
|
||||
|
||||
@@ -26,6 +26,7 @@ extern "C" {
|
||||
#include "../lv_draw_image.h"
|
||||
#include "../lv_draw_line.h"
|
||||
#include "../lv_draw_arc.h"
|
||||
#include "../lv_draw_blur.h"
|
||||
#include "lv_draw_sw_utils.h"
|
||||
#include "blend/lv_draw_sw_blend.h"
|
||||
|
||||
@@ -121,6 +122,15 @@ void lv_draw_sw_layer(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc,
|
||||
*/
|
||||
void lv_draw_sw_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc);
|
||||
|
||||
|
||||
/**
|
||||
* Blur an area with SW render
|
||||
* @param t pointer to a draw task
|
||||
* @param dsc the draw descriptor
|
||||
* @param coords the area to blur
|
||||
*/
|
||||
void lv_draw_sw_blur(lv_draw_task_t * t, const lv_draw_blur_dsc_t * dsc, const lv_area_t * coords);
|
||||
|
||||
/**
|
||||
* Mask out a rectangle with radius from a current layer
|
||||
* @param t pointer to a draw task
|
||||
|
||||
@@ -0,0 +1,395 @@
|
||||
/**
|
||||
* @file lv_draw_sw_blur.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../misc/lv_area_private.h"
|
||||
#include "lv_draw_sw_mask_private.h"
|
||||
#include "../lv_draw_private.h"
|
||||
#include "lv_draw_sw.h"
|
||||
|
||||
#if LV_USE_DRAW_SW
|
||||
|
||||
#include "../../misc/lv_math.h"
|
||||
#include "../../misc/lv_types.h"
|
||||
#include "../../core/lv_refr_private.h"
|
||||
#include "../../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define BLUR_INTENSITY_BITS 12
|
||||
#define BLUR_INTENSITY_MAX (1 << 12)
|
||||
#define BLUR_INTENSITY_HALF ((1 << 12) / 2)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void blur_2_bytes_init(uint32_t * sum, lv_color16_t * buf, uint32_t sample_len, int32_t stride);
|
||||
static inline uint16_t blur_2_bytes(uint32_t * sum, uint16_t px, uint32_t intensity);
|
||||
|
||||
static void blur_3_bytes_init(uint32_t * sum, volatile uint8_t * buf, uint32_t sample_len, int32_t stride);
|
||||
static inline void blur_3_bytes(uint32_t * sum, volatile uint8_t * buf, uint32_t intensity);
|
||||
|
||||
static int32_t get_rounded_edge_point(int32_t p_start, int32_t p_end, int32_t p, int32_t r);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_sw_blur(lv_draw_task_t * t, const lv_draw_blur_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->blur_radius == 0) return;
|
||||
LV_PROFILER_DRAW_BEGIN;
|
||||
|
||||
lv_area_t clipped_coords;
|
||||
if(!lv_area_intersect(&clipped_coords, coords, &t->clip_area)) return;
|
||||
lv_area_move(&clipped_coords, -t->target_layer->buf_area.x1, -t->target_layer->buf_area.y1);
|
||||
|
||||
uint32_t blur_radius = dsc->blur_radius;
|
||||
|
||||
/*On larger radius skip some pixels as the result is a blob anyways, so not all pixels matter
|
||||
*This only every 2nd or 3rd px will be blurred, the result will be stored in the layers buffers,
|
||||
*and finally the missing pixels are set to nearest blurred pixel. We loose precision but it looks ok
|
||||
*and and it's very fast.
|
||||
*/
|
||||
int32_t skip_cnt = 1;
|
||||
if(dsc->quality == LV_BLUR_QUALITY_AUTO) {
|
||||
if(blur_radius >= 32 && dsc->corner_radius == 0) skip_cnt = 3;
|
||||
else if(blur_radius >= 8) skip_cnt = 2;
|
||||
}
|
||||
else if(dsc->quality == LV_BLUR_QUALITY_SPEED) {
|
||||
if(blur_radius >= 24) skip_cnt = 3;
|
||||
else skip_cnt = 2;
|
||||
}
|
||||
|
||||
/*The blurring are must be multiples of skip_cnt so the blurring is all directions
|
||||
* blur the same pixels if some pixels are skipped*/
|
||||
clipped_coords.x1 = ((clipped_coords.x1 + (skip_cnt - 1)) / skip_cnt) * skip_cnt;
|
||||
clipped_coords.x2 = ((clipped_coords.x2 - (skip_cnt - 1)) / skip_cnt) * skip_cnt;
|
||||
clipped_coords.y1 = ((clipped_coords.y1 + (skip_cnt - 1)) / skip_cnt) * skip_cnt;
|
||||
clipped_coords.y2 = ((clipped_coords.y2 - (skip_cnt - 1)) / skip_cnt) * skip_cnt;
|
||||
if(lv_area_get_width(&clipped_coords) < 0) return;
|
||||
if(lv_area_get_height(&clipped_coords) < 0) return;
|
||||
|
||||
blur_radius = blur_radius / skip_cnt;
|
||||
|
||||
/*We will use an IIR low pass filer in all 4 direction: top to bottom, bottom to top, left to right, right to left.
|
||||
*Approximate the the filter coefficient from the radius.
|
||||
*The filter is like: this_px = mix(prev_px, this_px, intensity)
|
||||
*/
|
||||
uint32_t intensity = (BLUR_INTENSITY_MAX * blur_radius) / (blur_radius + 4);
|
||||
|
||||
int32_t sample_len = LV_MAX(blur_radius / 2, 1);
|
||||
int32_t radius = dsc->corner_radius;
|
||||
int32_t w = lv_area_get_width(coords);
|
||||
int32_t h = lv_area_get_height(coords);
|
||||
int32_t short_side = LV_MIN(w, h);
|
||||
if(radius > short_side >> 1) radius = short_side >> 1;
|
||||
|
||||
uint32_t px_size = lv_color_format_get_size(t->target_layer->draw_buf->header.cf);
|
||||
int32_t stride_byte = t->target_layer->draw_buf->header.stride;
|
||||
int32_t stride_px = stride_byte / px_size;
|
||||
int32_t next_px_ofs_byte = px_size * skip_cnt;
|
||||
|
||||
uint32_t sum[3];
|
||||
int32_t y;
|
||||
int32_t x;
|
||||
|
||||
/*Blur each column top to bottom and bottom to top.*/
|
||||
for(x = clipped_coords.x1; x <= clipped_coords.x2; x += skip_cnt) {
|
||||
int32_t cir_y = get_rounded_edge_point(coords->x1, coords->x2, x, radius);
|
||||
int32_t y_start = LV_CLAMP(clipped_coords.y1, coords->y1 + cir_y, clipped_coords.y2);
|
||||
int32_t y_end = LV_CLAMP(clipped_coords.y1, coords->y2 - cir_y, clipped_coords.y2);
|
||||
|
||||
/*Make sure that the width and height is a multiple of skip_cnt so that back and forth blurring
|
||||
*surely affects the same pixels */
|
||||
y_start = (y_start / skip_cnt) * skip_cnt;
|
||||
y_end = (y_end / skip_cnt) * skip_cnt;
|
||||
if(y_start > y_end) continue;
|
||||
|
||||
uint32_t sample_len_limited = LV_MIN((y_end - y_start) / skip_cnt + 1, sample_len);
|
||||
|
||||
if(px_size >= 3) {
|
||||
/*Compiler optimization might mishandle it, so add volatile*/
|
||||
volatile uint8_t * buf_column = lv_draw_buf_goto_xy(t->target_layer->draw_buf, x, y_start);
|
||||
blur_3_bytes_init(sum, buf_column, sample_len_limited, stride_byte * skip_cnt);
|
||||
|
||||
for(y = y_start; y <= y_end; y += skip_cnt) {
|
||||
blur_3_bytes(sum, buf_column, intensity);
|
||||
buf_column += stride_byte * skip_cnt;
|
||||
}
|
||||
|
||||
buf_column = lv_draw_buf_goto_xy(t->target_layer->draw_buf, x, y_end);
|
||||
blur_3_bytes_init(sum, buf_column, sample_len_limited, -stride_byte * skip_cnt);
|
||||
for(y = y_start; y <= y_end; y += skip_cnt) {
|
||||
blur_3_bytes(sum, buf_column, intensity);
|
||||
buf_column -= stride_byte * skip_cnt;
|
||||
}
|
||||
}
|
||||
else if(px_size == 2) {
|
||||
uint16_t * buf16_column = lv_draw_buf_goto_xy(t->target_layer->draw_buf, x, y_start);
|
||||
blur_2_bytes_init(sum, (lv_color16_t *)buf16_column, sample_len_limited, stride_px * skip_cnt);
|
||||
uint16_t buf16_prev = buf16_column[0] + 1; /*Make sure that it's not equal in the first round*/
|
||||
|
||||
for(y = y_start; y <= y_end; y += skip_cnt) {
|
||||
if(buf16_prev != *buf16_column) {
|
||||
*buf16_column = blur_2_bytes(sum, *buf16_column, intensity);
|
||||
buf16_prev = *buf16_column;
|
||||
}
|
||||
buf16_column += stride_px * skip_cnt;
|
||||
}
|
||||
|
||||
buf16_column = lv_draw_buf_goto_xy(t->target_layer->draw_buf, x, y_end);
|
||||
blur_2_bytes_init(sum, (lv_color16_t *)buf16_column, sample_len_limited, -stride_px * skip_cnt);
|
||||
buf16_prev = buf16_column[0] + 1; /*Make sure that it's not equal in the first round*/
|
||||
|
||||
for(y = y_start; y <= y_end; y += skip_cnt) {
|
||||
if(buf16_prev != *buf16_column) {
|
||||
*buf16_column = blur_2_bytes(sum, *buf16_column, intensity);
|
||||
buf16_prev = *buf16_column;
|
||||
}
|
||||
buf16_column -= stride_px * skip_cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Blur each line from left to right and right to left.
|
||||
*Also fill the gap in each line because of skipped pixels*/
|
||||
for(y = clipped_coords.y1; y <= clipped_coords.y2; y += skip_cnt) {
|
||||
int32_t cir_x = get_rounded_edge_point(coords->y1, coords->y2, y, radius);
|
||||
int32_t x_start = LV_CLAMP(clipped_coords.x1, coords->x1 + cir_x, clipped_coords.x2);
|
||||
int32_t x_end = LV_CLAMP(clipped_coords.x1, coords->x2 - cir_x, clipped_coords.x2);
|
||||
|
||||
/*Make sure that the width and height is a multiple of skip_cnt so that back and forth blurring
|
||||
*surely affects the same pixels */
|
||||
x_start = (x_start / skip_cnt) * skip_cnt;
|
||||
x_end = (x_end / skip_cnt) * skip_cnt;
|
||||
|
||||
if(x_start > x_end) continue;
|
||||
uint32_t line_len_byte = (x_end - x_start + skip_cnt) * px_size;
|
||||
uint32_t sample_len_limited = LV_MIN((x_end - x_start) / skip_cnt + 1, sample_len);
|
||||
|
||||
if(px_size >= 3) {
|
||||
/*Compiler optimization might mishandle it, so add volatile*/
|
||||
volatile uint8_t * buf_line = lv_draw_buf_goto_xy(t->target_layer->draw_buf, x_start, y);
|
||||
|
||||
blur_3_bytes_init(sum, buf_line, sample_len_limited, px_size * skip_cnt);
|
||||
buf_line += px_size * skip_cnt;
|
||||
for(x = x_start + skip_cnt; x <= x_end; x += skip_cnt) {
|
||||
blur_3_bytes(sum, buf_line, intensity);
|
||||
buf_line += next_px_ofs_byte;
|
||||
}
|
||||
|
||||
buf_line = lv_draw_buf_goto_xy(t->target_layer->draw_buf, x_end, y);
|
||||
blur_3_bytes_init(sum, buf_line, sample_len_limited, - px_size * skip_cnt);
|
||||
for(x = x_start; x <= x_end; x += skip_cnt) {
|
||||
blur_3_bytes(sum, buf_line, intensity);
|
||||
|
||||
/*This is the final pixel, fill the gaps in the line by just repeating the pixel (simple upscale)*/
|
||||
if(skip_cnt == 2) {
|
||||
buf_line[px_size + 0] = buf_line[0];
|
||||
buf_line[px_size + 1] = buf_line[1];
|
||||
buf_line[px_size + 2] = buf_line[2];
|
||||
}
|
||||
else if(skip_cnt == 3) {
|
||||
buf_line[px_size + 0] = buf_line[0];
|
||||
buf_line[px_size + 1] = buf_line[1];
|
||||
buf_line[px_size + 2] = buf_line[2];
|
||||
buf_line[px_size * 2 + 0] = buf_line[0];
|
||||
buf_line[px_size * 2 + 1] = buf_line[1];
|
||||
buf_line[px_size * 2 + 2] = buf_line[2];
|
||||
}
|
||||
|
||||
/*Fill the empty lines by duplicating a the finished filled lines to the gaps*/
|
||||
if(skip_cnt > 1 && x + skip_cnt > x_end) {
|
||||
uint8_t * buf_copy_from = lv_draw_buf_goto_xy(t->target_layer->draw_buf, x_start, y);
|
||||
lv_memcpy(buf_copy_from + stride_byte, buf_copy_from, line_len_byte);
|
||||
if(skip_cnt == 3) {
|
||||
lv_memcpy(buf_copy_from + stride_byte * 2, buf_copy_from, line_len_byte);
|
||||
}
|
||||
}
|
||||
|
||||
buf_line -= next_px_ofs_byte;
|
||||
}
|
||||
|
||||
}
|
||||
else if(px_size == 2) {
|
||||
uint16_t * buf16_line = lv_draw_buf_goto_xy(t->target_layer->draw_buf, x_start, y);
|
||||
blur_2_bytes_init(sum, (lv_color16_t *)buf16_line, sample_len_limited, skip_cnt);
|
||||
uint16_t buf16_prev = buf16_line[0] + 1; /*Make sure that it's not equal in the first round*/
|
||||
|
||||
for(x = x_start; x <= x_end; x += skip_cnt) {
|
||||
if(buf16_prev != *buf16_line) {
|
||||
*buf16_line = blur_2_bytes(sum, *buf16_line, intensity);
|
||||
buf16_prev = *buf16_line;
|
||||
}
|
||||
buf16_line += skip_cnt;
|
||||
}
|
||||
|
||||
buf16_line = lv_draw_buf_goto_xy(t->target_layer->draw_buf, x_end, y);
|
||||
blur_2_bytes_init(sum, (lv_color16_t *)buf16_line, sample_len_limited, - skip_cnt);
|
||||
buf16_prev = buf16_line[0] + 1; /*Make sure that it's not equal in the first round*/
|
||||
|
||||
for(x = x_start; x <= x_end; x += skip_cnt) {
|
||||
if(buf16_prev != *buf16_line) {
|
||||
*buf16_line = blur_2_bytes(sum, *buf16_line, intensity);
|
||||
buf16_prev = *buf16_line;
|
||||
}
|
||||
|
||||
/*This is the final pixel, fill the gaps in the line by just repeating the pixel (simple upscale)*/
|
||||
if(skip_cnt == 2) {
|
||||
/*Fill the empty lines by duplicating a the finished filled lines to the gaps*/
|
||||
buf16_line[1] = buf16_line[0];
|
||||
}
|
||||
else if(skip_cnt == 3) {
|
||||
/*Fill the empty lines by duplicating a the finished filled lines to the gaps*/
|
||||
buf16_line[1] = buf16_line[0];
|
||||
buf16_line[2] = buf16_line[0];
|
||||
}
|
||||
|
||||
/*Fill the empty lines by duplicating a the finished filled lines to the gaps*/
|
||||
if(skip_cnt > 1 && x + skip_cnt > x_end) {
|
||||
uint8_t * buf_copy_from = lv_draw_buf_goto_xy(t->target_layer->draw_buf, x_start, y);
|
||||
lv_memcpy(buf_copy_from + stride_byte, buf_copy_from, line_len_byte);
|
||||
if(skip_cnt == 3) {
|
||||
lv_memcpy(buf_copy_from + stride_byte * 2, buf_copy_from, line_len_byte);
|
||||
}
|
||||
}
|
||||
|
||||
buf16_line -= skip_cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LV_PROFILER_DRAW_END;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void blur_3_bytes_init(uint32_t * sum, volatile uint8_t * buf, uint32_t sample_len, int32_t stride)
|
||||
{
|
||||
uint32_t s;
|
||||
|
||||
sum[0] = 0;
|
||||
sum[1] = 0;
|
||||
sum[2] = 0;
|
||||
|
||||
for(s = 0; s < sample_len; s++) {
|
||||
sum[0] += buf[0];
|
||||
sum[1] += buf[1];
|
||||
sum[2] += buf[2];
|
||||
buf += stride;
|
||||
}
|
||||
sum[0] = (sum[0] << BLUR_INTENSITY_BITS) / sample_len;
|
||||
sum[1] = (sum[1] << BLUR_INTENSITY_BITS) / sample_len;
|
||||
sum[2] = (sum[2] << BLUR_INTENSITY_BITS) / sample_len;
|
||||
}
|
||||
|
||||
static void blur_2_bytes_init(uint32_t * sum, lv_color16_t * buf, uint32_t sample_len, int32_t stride)
|
||||
{
|
||||
uint32_t s;
|
||||
|
||||
sum[0] = 0;
|
||||
sum[1] = 0;
|
||||
sum[2] = 0;
|
||||
for(s = 0; s < sample_len; s++) {
|
||||
sum[0] += buf->red;
|
||||
sum[1] += buf->green;
|
||||
sum[2] += buf->blue;
|
||||
buf += stride;
|
||||
}
|
||||
|
||||
sum[0] = (sum[0] << BLUR_INTENSITY_BITS) / sample_len;
|
||||
sum[1] = (sum[1] << BLUR_INTENSITY_BITS) / sample_len;
|
||||
sum[2] = (sum[2] << BLUR_INTENSITY_BITS) / sample_len;
|
||||
}
|
||||
|
||||
static inline uint16_t blur_2_bytes(uint32_t * sum, uint16_t px, uint32_t intensity)
|
||||
{
|
||||
const uint32_t inv = BLUR_INTENSITY_MAX - intensity;
|
||||
const uint32_t half = BLUR_INTENSITY_MAX >> 1;
|
||||
const uint32_t shift = BLUR_INTENSITY_BITS;
|
||||
|
||||
/* unpack */
|
||||
uint32_t r = px >> 11;
|
||||
uint32_t g = (px >> 5) & 0x3F;
|
||||
uint32_t b = px & 0x1F;
|
||||
|
||||
uint32_t s0 = sum[0];
|
||||
uint32_t s1 = sum[1];
|
||||
uint32_t s2 = sum[2];
|
||||
|
||||
/* fused multiply-accumulate pattern */
|
||||
s0 = (s0 * intensity >> shift) + (r * inv);
|
||||
s1 = (s1 * intensity >> shift) + (g * inv);
|
||||
s2 = (s2 * intensity >> shift) + (b * inv);
|
||||
|
||||
sum[0] = s0;
|
||||
sum[1] = s1;
|
||||
sum[2] = s2;
|
||||
|
||||
/* final */
|
||||
r = (s0 + half) >> shift;
|
||||
g = (s1 + half) >> shift;
|
||||
b = (s2 + half) >> shift;
|
||||
|
||||
return (uint16_t)((r << 11) | (g << 5) | b);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline void blur_3_bytes(uint32_t * sum, volatile uint8_t * buf, uint32_t intensity)
|
||||
{
|
||||
uint32_t intensity_inv = BLUR_INTENSITY_MAX - intensity;
|
||||
|
||||
sum[0] = ((sum[0] * intensity) >> BLUR_INTENSITY_BITS) + ((buf[0] * intensity_inv));
|
||||
buf[0] = sum[0] >> BLUR_INTENSITY_BITS;
|
||||
|
||||
sum[1] = ((sum[1] * intensity) >> BLUR_INTENSITY_BITS) + ((buf[1] * intensity_inv));
|
||||
buf[1] = sum[1] >> BLUR_INTENSITY_BITS;
|
||||
|
||||
sum[2] = ((sum[2] * intensity) >> BLUR_INTENSITY_BITS) + ((buf[2] * intensity_inv));
|
||||
buf[2] = sum[2] >> BLUR_INTENSITY_BITS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the X or Y point for a rounded edge.
|
||||
* If the X coordinates are used Y will be returned and vice versa
|
||||
* Calculates the left or top edge
|
||||
* @param p_start the edge's X1 or Y1 coordinate
|
||||
* @param p_end the edge's X2 or Y2 coordinate
|
||||
* @param p the X or Y coordinate on the edge for which the related X or X should be returned
|
||||
* @param r the radius of the corner
|
||||
* @return the X or Y coordinate corresponding to the provided coordinates
|
||||
*/
|
||||
static int32_t get_rounded_edge_point(int32_t p_start, int32_t p_end, int32_t p, int32_t r)
|
||||
{
|
||||
if(p < p_start + r) p = r - (p - p_start);
|
||||
else if(p > p_end - r) p = r - (p_end - p);
|
||||
else return 0;
|
||||
|
||||
uint32_t res = lv_sqrt32(r * r - p * p);
|
||||
return r - res;
|
||||
}
|
||||
|
||||
|
||||
#endif /*LV_USE_DRAW_SW*/
|
||||
@@ -118,6 +118,12 @@ typedef enum {
|
||||
LV_BORDER_SIDE_INTERNAL = 0x10, /**< FOR matrix-like objects (e.g. Button matrix)*/
|
||||
} lv_border_side_t;
|
||||
|
||||
typedef enum {
|
||||
LV_BLUR_QUALITY_AUTO = 0, /**< Set the quality automatically */
|
||||
LV_BLUR_QUALITY_SPEED, /**< Prefer speed over precision */
|
||||
LV_BLUR_QUALITY_PRECISION, /**< Prefer precision over speed*/
|
||||
} lv_blur_quality_t;
|
||||
|
||||
/** A image colorkey definition.
|
||||
* The transparency within the color range of [low, high] will be set to LV_OPA_TRANSP If the "enable" flag is set to true.
|
||||
*/
|
||||
@@ -293,7 +299,11 @@ enum _lv_style_id_t {
|
||||
LV_STYLE_GRID_CELL_Y_ALIGN = 136,
|
||||
LV_STYLE_IMAGE_COLORKEY = 137,
|
||||
|
||||
LV_STYLE_LAST_BUILT_IN_PROP = 138,
|
||||
LV_STYLE_BLUR_RADIUS = 138,
|
||||
LV_STYLE_BLUR_BACKDROP = 139,
|
||||
LV_STYLE_BLUR_QUALITY = 140,
|
||||
|
||||
LV_STYLE_LAST_BUILT_IN_PROP,
|
||||
|
||||
LV_STYLE_NUM_BUILT_IN_PROPS = LV_STYLE_LAST_BUILT_IN_PROP + 1,
|
||||
|
||||
|
||||
@@ -778,6 +778,30 @@ void lv_style_set_recolor_opa(lv_style_t * style, lv_opa_t value)
|
||||
lv_style_set_prop(style, LV_STYLE_RECOLOR_OPA, v);
|
||||
}
|
||||
|
||||
void lv_style_set_blur_radius(lv_style_t * style, int32_t value)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_style_set_prop(style, LV_STYLE_BLUR_RADIUS, v);
|
||||
}
|
||||
|
||||
void lv_style_set_blur_backdrop(lv_style_t * style, bool value)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_style_set_prop(style, LV_STYLE_BLUR_BACKDROP, v);
|
||||
}
|
||||
|
||||
void lv_style_set_blur_quality(lv_style_t * style, lv_blur_quality_t value)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_style_set_prop(style, LV_STYLE_BLUR_QUALITY, v);
|
||||
}
|
||||
|
||||
void lv_style_set_anim(lv_style_t * style, const lv_anim_t * value)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
|
||||
@@ -110,6 +110,9 @@ void lv_style_set_color_filter_dsc(lv_style_t * style, const lv_color_filter_dsc
|
||||
void lv_style_set_color_filter_opa(lv_style_t * style, lv_opa_t value);
|
||||
void lv_style_set_recolor(lv_style_t * style, lv_color_t value);
|
||||
void lv_style_set_recolor_opa(lv_style_t * style, lv_opa_t value);
|
||||
void lv_style_set_blur_radius(lv_style_t * style, int32_t value);
|
||||
void lv_style_set_blur_backdrop(lv_style_t * style, bool value);
|
||||
void lv_style_set_blur_quality(lv_style_t * style, lv_blur_quality_t value);
|
||||
void lv_style_set_anim(lv_style_t * style, const lv_anim_t * value);
|
||||
void lv_style_set_anim_duration(lv_style_t * style, uint32_t value);
|
||||
void lv_style_set_transition(lv_style_t * style, const lv_style_transition_dsc_t * value);
|
||||
@@ -620,6 +623,21 @@ void lv_style_set_grid_cell_row_span(lv_style_t * style, int32_t value);
|
||||
.prop = LV_STYLE_RECOLOR_OPA, .value = { .num = (int32_t)val } \
|
||||
}
|
||||
|
||||
#define LV_STYLE_CONST_BLUR_RADIUS(val) \
|
||||
{ \
|
||||
.prop = LV_STYLE_BLUR_RADIUS, .value = { .num = (int32_t)val } \
|
||||
}
|
||||
|
||||
#define LV_STYLE_CONST_BLUR_BACKDROP(val) \
|
||||
{ \
|
||||
.prop = LV_STYLE_BLUR_BACKDROP, .value = { .num = (int32_t)val } \
|
||||
}
|
||||
|
||||
#define LV_STYLE_CONST_BLUR_QUALITY(val) \
|
||||
{ \
|
||||
.prop = LV_STYLE_BLUR_QUALITY, .value = { .num = (int32_t)val } \
|
||||
}
|
||||
|
||||
#define LV_STYLE_CONST_ANIM(val) \
|
||||
{ \
|
||||
.prop = LV_STYLE_ANIM, .value = { .ptr = val } \
|
||||
|
||||
@@ -978,7 +978,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
|
||||
}
|
||||
else if(lv_obj_check_type(obj, &lv_dropdownlist_class)) {
|
||||
lv_obj_add_style(obj, &theme->styles.card, 0);
|
||||
lv_obj_add_style(obj, &theme->styles.clip_corner, 0);
|
||||
lv_obj_add_style(obj, &theme->styles.line_space_large, 0);
|
||||
lv_obj_add_style(obj, &theme->styles.dropdown_list, 0);
|
||||
lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
|
||||
@@ -1133,18 +1132,18 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
|
||||
return;
|
||||
}
|
||||
else if(lv_obj_check_type(obj, &lv_msgbox_header_class)) {
|
||||
lv_obj_add_style(obj, &theme->styles.pad_tiny, 0);
|
||||
lv_obj_add_style(obj, &theme->styles.pad_small, 0);
|
||||
lv_obj_add_style(obj, &theme->styles.bg_color_grey, 0);
|
||||
return;
|
||||
}
|
||||
else if(lv_obj_check_type(obj, &lv_msgbox_footer_class)) {
|
||||
lv_obj_add_style(obj, &theme->styles.pad_tiny, 0);
|
||||
lv_obj_add_style(obj, &theme->styles.pad_small, 0);
|
||||
return;
|
||||
}
|
||||
else if(lv_obj_check_type(obj, &lv_msgbox_content_class)) {
|
||||
lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
|
||||
lv_obj_add_style(obj, &theme->styles.scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED);
|
||||
lv_obj_add_style(obj, &theme->styles.pad_tiny, 0);
|
||||
lv_obj_add_style(obj, &theme->styles.pad_small, 0);
|
||||
return;
|
||||
}
|
||||
else if(lv_obj_check_type(obj, &lv_msgbox_header_button_class) ||
|
||||
|
||||
@@ -509,10 +509,18 @@ static void draw_indic(lv_event_t * e)
|
||||
draw_rect_dsc.base.layer = layer;
|
||||
lv_obj_init_draw_rect_dsc(obj, LV_PART_INDICATOR, &draw_rect_dsc);
|
||||
|
||||
|
||||
int32_t bg_radius = lv_obj_get_style_radius(obj, LV_PART_MAIN);
|
||||
int32_t short_side = LV_MIN(barw, barh);
|
||||
if(bg_radius > short_side >> 1) bg_radius = short_side >> 1;
|
||||
|
||||
bool backdrop_blur = lv_obj_get_style_blur_backdrop(obj, LV_PART_INDICATOR);
|
||||
lv_draw_blur_dsc_t draw_blur_dsc;
|
||||
lv_draw_blur_dsc_init(&draw_blur_dsc);
|
||||
draw_blur_dsc.corner_radius = draw_rect_dsc.radius;
|
||||
lv_obj_init_draw_blur_dsc(obj, LV_PART_INDICATOR, &draw_blur_dsc);
|
||||
if(backdrop_blur) lv_draw_blur(layer, &draw_blur_dsc, &indic_area);
|
||||
|
||||
int32_t indic_radius = draw_rect_dsc.radius;
|
||||
short_side = LV_MIN(lv_area_get_width(&bar->indic_area), lv_area_get_height(&bar->indic_area));
|
||||
if(indic_radius > short_side >> 1) indic_radius = short_side >> 1;
|
||||
@@ -556,12 +564,12 @@ static void draw_indic(lv_event_t * e)
|
||||
if(radius_issue || mask_needed) {
|
||||
if(!radius_issue) {
|
||||
/*Draw only the shadow*/
|
||||
lv_draw_rect_dsc_t draw_tmp_dsc = draw_rect_dsc;
|
||||
draw_tmp_dsc.border_opa = 0;
|
||||
draw_tmp_dsc.outline_opa = 0;
|
||||
draw_tmp_dsc.bg_opa = 0;
|
||||
draw_tmp_dsc.bg_image_opa = 0;
|
||||
lv_draw_rect(layer, &draw_tmp_dsc, &indic_area);
|
||||
lv_draw_rect_dsc_t draw_rect_tmp_dsc = draw_rect_dsc;
|
||||
draw_rect_tmp_dsc.border_opa = 0;
|
||||
draw_rect_tmp_dsc.outline_opa = 0;
|
||||
draw_rect_tmp_dsc.bg_opa = 0;
|
||||
draw_rect_tmp_dsc.bg_image_opa = 0;
|
||||
lv_draw_rect(layer, &draw_rect_tmp_dsc, &indic_area);
|
||||
}
|
||||
else {
|
||||
draw_rect_dsc.border_opa = 0;
|
||||
@@ -617,10 +625,13 @@ static void draw_indic(lv_event_t * e)
|
||||
draw_tmp_dsc.bg_opa = 0;
|
||||
draw_tmp_dsc.bg_image_opa = 0;
|
||||
lv_draw_rect(layer, &draw_tmp_dsc, &indic_area);
|
||||
|
||||
}
|
||||
else {
|
||||
lv_draw_rect(layer, &draw_rect_dsc, &indic_area);
|
||||
}
|
||||
|
||||
if(!backdrop_blur) lv_draw_blur(layer, &draw_blur_dsc, &indic_area);
|
||||
}
|
||||
|
||||
static void lv_bar_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
extern const lv_property_name_t lv_obj_property_names[75];
|
||||
extern const lv_property_name_t lv_roller_property_names[3];
|
||||
extern const lv_property_name_t lv_slider_property_names[8];
|
||||
extern const lv_property_name_t lv_style_property_names[121];
|
||||
extern const lv_property_name_t lv_style_property_names[123];
|
||||
extern const lv_property_name_t lv_textarea_property_names[15];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* Generated code from properties.py
|
||||
*/
|
||||
/* *INDENT-OFF* */
|
||||
const lv_property_name_t lv_style_property_names[121] = {
|
||||
const lv_property_name_t lv_style_property_names[123] = {
|
||||
{"align", LV_PROPERTY_STYLE_ALIGN,},
|
||||
{"anim", LV_PROPERTY_STYLE_ANIM,},
|
||||
{"anim_duration", LV_PROPERTY_STYLE_ANIM_DURATION,},
|
||||
@@ -40,6 +40,9 @@ const lv_property_name_t lv_style_property_names[121] = {
|
||||
{"bg_opa", LV_PROPERTY_STYLE_BG_OPA,},
|
||||
{"bitmap_mask_src", LV_PROPERTY_STYLE_BITMAP_MASK_SRC,},
|
||||
{"blend_mode", LV_PROPERTY_STYLE_BLEND_MODE,},
|
||||
{"blur_backdrop", LV_PROPERTY_STYLE_BLUR_BACKDROP,},
|
||||
{"blur_quality", LV_PROPERTY_STYLE_BLUR_QUALITY,},
|
||||
{"blur_radius", LV_PROPERTY_STYLE_BLUR_RADIUS,},
|
||||
{"border_color", LV_PROPERTY_STYLE_BORDER_COLOR,},
|
||||
{"border_opa", LV_PROPERTY_STYLE_BORDER_OPA,},
|
||||
{"border_post", LV_PROPERTY_STYLE_BORDER_POST,},
|
||||
@@ -68,7 +71,6 @@ const lv_property_name_t lv_style_property_names[121] = {
|
||||
{"image_opa", LV_PROPERTY_STYLE_IMAGE_OPA,},
|
||||
{"image_recolor", LV_PROPERTY_STYLE_IMAGE_RECOLOR,},
|
||||
{"image_recolor_opa", LV_PROPERTY_STYLE_IMAGE_RECOLOR_OPA,},
|
||||
{"last_built_in_prop", LV_PROPERTY_STYLE_LAST_BUILT_IN_PROP,},
|
||||
{"layout", LV_PROPERTY_STYLE_LAYOUT,},
|
||||
{"length", LV_PROPERTY_STYLE_LENGTH,},
|
||||
{"line_color", LV_PROPERTY_STYLE_LINE_COLOR,},
|
||||
|
||||
@@ -37,6 +37,9 @@ enum _lv_property_style_id_t {
|
||||
LV_PROPERTY_ID(STYLE, BG_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_OPA),
|
||||
LV_PROPERTY_ID(STYLE, BITMAP_MASK_SRC, LV_PROPERTY_TYPE_POINTER, LV_STYLE_BITMAP_MASK_SRC),
|
||||
LV_PROPERTY_ID(STYLE, BLEND_MODE, LV_PROPERTY_TYPE_INT, LV_STYLE_BLEND_MODE),
|
||||
LV_PROPERTY_ID(STYLE, BLUR_BACKDROP, LV_PROPERTY_TYPE_INT, LV_STYLE_BLUR_BACKDROP),
|
||||
LV_PROPERTY_ID(STYLE, BLUR_QUALITY, LV_PROPERTY_TYPE_INT, LV_STYLE_BLUR_QUALITY),
|
||||
LV_PROPERTY_ID(STYLE, BLUR_RADIUS, LV_PROPERTY_TYPE_INT, LV_STYLE_BLUR_RADIUS),
|
||||
LV_PROPERTY_ID(STYLE, BORDER_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_BORDER_COLOR),
|
||||
LV_PROPERTY_ID(STYLE, BORDER_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BORDER_OPA),
|
||||
LV_PROPERTY_ID(STYLE, BORDER_POST, LV_PROPERTY_TYPE_INT, LV_STYLE_BORDER_POST),
|
||||
@@ -65,7 +68,6 @@ enum _lv_property_style_id_t {
|
||||
LV_PROPERTY_ID(STYLE, IMAGE_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_IMAGE_OPA),
|
||||
LV_PROPERTY_ID(STYLE, IMAGE_RECOLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_IMAGE_RECOLOR),
|
||||
LV_PROPERTY_ID(STYLE, IMAGE_RECOLOR_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_IMAGE_RECOLOR_OPA),
|
||||
LV_PROPERTY_ID(STYLE, LAST_BUILT_IN_PROP, LV_PROPERTY_TYPE_INVALID, LV_STYLE_LAST_BUILT_IN_PROP),
|
||||
LV_PROPERTY_ID(STYLE, LAYOUT, LV_PROPERTY_TYPE_INT, LV_STYLE_LAYOUT),
|
||||
LV_PROPERTY_ID(STYLE, LENGTH, LV_PROPERTY_TYPE_INT, LV_STYLE_LENGTH),
|
||||
LV_PROPERTY_ID(STYLE, LINE_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_LINE_COLOR),
|
||||
|
||||
@@ -238,6 +238,16 @@ lv_blend_mode_t lv_xml_blend_mode_to_enum(const char * txt)
|
||||
return 0; /*Return 0 in lack of a better option. */
|
||||
}
|
||||
|
||||
lv_blur_quality_t lv_xml_blur_quality_to_enum(const char * txt)
|
||||
{
|
||||
if(lv_streq("auto", txt)) return LV_BLUR_QUALITY_AUTO;
|
||||
if(lv_streq("speed", txt)) return LV_BLUR_QUALITY_SPEED;
|
||||
if(lv_streq("precision", txt)) return LV_BLUR_QUALITY_PRECISION;
|
||||
|
||||
LV_LOG_WARN("%s is an unknown value for blur_quality", txt);
|
||||
return 0; /*Return 0 in lack of a better option. */
|
||||
}
|
||||
|
||||
lv_event_code_t lv_xml_trigger_text_to_enum_value(const char * txt)
|
||||
{
|
||||
if(lv_streq("all", txt)) return LV_EVENT_ALL;
|
||||
|
||||
@@ -139,6 +139,13 @@ lv_layout_t lv_xml_layout_to_enum(const char * txt);
|
||||
*/
|
||||
lv_blend_mode_t lv_xml_blend_mode_to_enum(const char * txt);
|
||||
|
||||
/**
|
||||
* Convert a blur quality string to enum
|
||||
* @param txt e.g. "auto"
|
||||
* @return the related enum, e.g. `LV_BLUR_QUALITY_AUTO`
|
||||
*/
|
||||
lv_blur_quality_t lv_xml_blur_quality_to_enum(const char * txt);
|
||||
|
||||
/**
|
||||
* Convert an event trigger string to enum
|
||||
* @param txt e.g. "clicked"
|
||||
|
||||
@@ -267,6 +267,10 @@ lv_result_t lv_xml_register_style(lv_xml_component_scope_t * scope, const char *
|
||||
else SET_STYLE_IF(recolor, lv_xml_to_color(value));
|
||||
else SET_STYLE_IF(recolor_opa, lv_xml_to_opa(value));
|
||||
|
||||
else SET_STYLE_IF(blur_radius, lv_xml_atoi(value));
|
||||
else SET_STYLE_IF(blur_backdrop, lv_xml_to_bool(value));
|
||||
else SET_STYLE_IF(blur_quality, lv_xml_blur_quality_to_enum(value));
|
||||
|
||||
else SET_STYLE_IF(layout, lv_xml_layout_to_enum(value));
|
||||
|
||||
else SET_STYLE_IF(flex_flow, lv_xml_flex_flow_to_enum(value));
|
||||
|
||||
@@ -953,6 +953,9 @@ static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const ch
|
||||
else SET_STYLE_IF(rotary_sensitivity, lv_xml_atoi(value));
|
||||
else SET_STYLE_IF(recolor, lv_xml_to_color(value));
|
||||
else SET_STYLE_IF(recolor_opa, lv_xml_to_opa(value));
|
||||
else SET_STYLE_IF(blur_radius, lv_xml_atoi(value));
|
||||
else SET_STYLE_IF(blur_backdrop, lv_xml_to_bool(value));
|
||||
else SET_STYLE_IF(blur_quality, lv_xml_blur_quality_to_enum(value));
|
||||
|
||||
else SET_STYLE_IF(layout, lv_xml_layout_to_enum(value));
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 119 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 110 KiB |