mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-14 06:42:58 +08:00
feat(demos): High Resolution Demo Improvements (#7566)
This commit is contained in:
parent
137a2a647c
commit
f47879b67e
@ -88,12 +88,15 @@ typedef void (*lv_demo_high_res_exit_cb_t)(lv_demo_high_res_api_t * api);
|
||||
* `LV_FS_DEFAULT_DRIVE_LETTER` set. The display size should be
|
||||
* 800x480, 1280x720, or 1920x1080.
|
||||
* @param assets_path Folder where the image assets are.
|
||||
* If `NULL`, "lvgl/demos/high_res/assets/" will be used.
|
||||
* If `NULL`, "lvgl/demos/high_res/assets" will be used.
|
||||
* @param logo_path A path to a logo to display in the bottom-left
|
||||
* of the home screen. If `NULL`, an LVGL logo is used.
|
||||
* @param slides_path Folder where the "About" app slideshow slides are.
|
||||
* If `NULL`, "about_app_slides/" will be used.
|
||||
* The images should be named like 1.png, 2.png, etc.
|
||||
* If `NULL`, "about_app_slides" will be used.
|
||||
* The images should be named like Slide1.png, Slide2.png, etc.
|
||||
* They will be scaled to nine sixteenths the height of the
|
||||
* display. I.e., a slide will not be scaled if it is
|
||||
* 405 px high and the display is 720 px high.
|
||||
* @param exit_cb A callback function which will be called when the
|
||||
* "logout" button is clicked, or `NULL` to do nothing.
|
||||
* @return A struct with subjects to control the UI
|
||||
@ -112,12 +115,15 @@ lv_demo_high_res_api_t * lv_demo_high_res(const char * assets_path,
|
||||
* `LV_FS_DEFAULT_DRIVE_LETTER` set. The display size should be
|
||||
* 800x480, 1280x720, or 1920x1080.
|
||||
* @param assets_path Folder where the image assets are.
|
||||
* If `NULL`, "lvgl/demos/high_res/assets/" will be used.
|
||||
* If `NULL`, "lvgl/demos/high_res/assets" will be used.
|
||||
* @param logo_path A path to a logo to display in the bottom-left
|
||||
* of the home screen. If `NULL`, an LVGL logo is used.
|
||||
* @param slides_path Folder where the "About" app slideshow slides are.
|
||||
* If `NULL`, "about_app_slides/" will be used.
|
||||
* The images should be named like 1.png, 2.png, etc.
|
||||
* If `NULL`, "about_app_slides" will be used.
|
||||
* The images should be named like Slide1.png, Slide2.png, etc.
|
||||
* They will be scaled to nine sixteenths the height of the
|
||||
* display. I.e., a slide will not be scaled if it is
|
||||
* 405 px high and the display is 720 px high.
|
||||
*/
|
||||
void lv_demo_high_res_api_example(const char * assets_path, const char * logo_path, const char * slides_path);
|
||||
|
||||
|
@ -34,7 +34,6 @@ static bool advance_slides(lv_obj_t * slide_deck);
|
||||
static void right_clicked_cb(lv_event_t * e);
|
||||
static void play_pause_timer_cb(lv_timer_t * t);
|
||||
static void play_pause_clicked_cb(lv_event_t * e);
|
||||
static void slide_free_draw_buf_cb(lv_event_t * e);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@ -99,18 +98,19 @@ void lv_demo_high_res_app_about(lv_obj_t * base_obj)
|
||||
|
||||
/* slides */
|
||||
|
||||
lv_fs_res_t res;
|
||||
|
||||
lv_fs_dir_t dir;
|
||||
res = lv_fs_dir_open(&dir, c->slides_path);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
if(lv_array_is_empty(&c->about_slides_array)) {
|
||||
lv_obj_t * label = lv_label_create(bg_cont);
|
||||
lv_label_set_text_fmt(label, "Couldn't open the '%s' folder to load the images", c->slides_path);
|
||||
if(c->about_slides_dir_exists) {
|
||||
lv_label_set_text_fmt(label, "Couldn't find images named Slide1.png, Slide2.png, etc. in the '%s' folder",
|
||||
c->slides_path);
|
||||
}
|
||||
else {
|
||||
lv_label_set_text_fmt(label, "Couldn't open the '%s' folder to load the images", c->slides_path);
|
||||
}
|
||||
lv_obj_center(label);
|
||||
lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
|
||||
return;
|
||||
}
|
||||
res = lv_fs_dir_close(&dir);
|
||||
LV_ASSERT(res == LV_FS_RES_OK);
|
||||
|
||||
lv_obj_t * slides_cont = lv_obj_create(bg_cont);
|
||||
lv_obj_remove_style_all(slides_cont);
|
||||
@ -148,21 +148,11 @@ void lv_demo_high_res_app_about(lv_obj_t * base_obj)
|
||||
|
||||
lv_obj_t * slide;
|
||||
|
||||
char buf[256];
|
||||
for(int32_t i = 1; ; i++) {
|
||||
lv_snprintf(buf, sizeof(buf), "%s/Slide%"PRId32".png", c->slides_path, i);
|
||||
lv_fs_file_t file;
|
||||
res = lv_fs_open(&file, buf, LV_FS_MODE_RD);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
break;
|
||||
}
|
||||
res = lv_fs_close(&file);
|
||||
LV_ASSERT(res == LV_FS_RES_OK);
|
||||
|
||||
uint32_t about_slides_count = lv_array_size(&c->about_slides_array);
|
||||
for(uint32_t i = 0; i < about_slides_count; i++) {
|
||||
lv_image_dsc_t ** slide_src = lv_array_at(&c->about_slides_array, i);
|
||||
slide = lv_image_create(slide_deck);
|
||||
lv_image_dsc_t * loaded_draw_buf = lv_demo_high_res_image_preload(buf, LV_COLOR_FORMAT_NATIVE);
|
||||
lv_image_set_src(slide, loaded_draw_buf);
|
||||
lv_obj_add_event_cb(slide, slide_free_draw_buf_cb, LV_EVENT_DELETE, loaded_draw_buf);
|
||||
lv_image_set_src(slide, *slide_src);
|
||||
}
|
||||
|
||||
slide = lv_obj_get_child(slide_deck, 0);
|
||||
@ -292,10 +282,4 @@ static void play_pause_clicked_cb(lv_event_t * e)
|
||||
}
|
||||
}
|
||||
|
||||
static void slide_free_draw_buf_cb(lv_event_t * e)
|
||||
{
|
||||
lv_image_dsc_t * loaded_draw_buf = lv_event_get_user_data(e);
|
||||
lv_draw_buf_destroy((lv_draw_buf_t *)loaded_draw_buf);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DEMO_HIGH_RES*/
|
||||
|
@ -201,6 +201,8 @@ typedef struct {
|
||||
lv_subject_t top_margin_setting_subject;
|
||||
lv_demo_high_res_api_t api;
|
||||
lv_demo_high_res_subject_groups_t subject_groups;
|
||||
lv_array_t about_slides_array;
|
||||
bool about_slides_dir_exists;
|
||||
} lv_demo_high_res_ctx_t;
|
||||
|
||||
LV_ATTRIBUTE_EXTERN_DATA extern const lv_demo_high_res_theme_t lv_demo_high_res_theme_light;
|
||||
@ -231,7 +233,7 @@ lv_obj_t * lv_demo_high_res_simple_container_create(lv_obj_t * parent, bool vert
|
||||
void lv_demo_high_res_label_bind_temperature(lv_obj_t * label, lv_subject_t * subject, lv_demo_high_res_ctx_t * c);
|
||||
void lv_demo_high_res_theme_observer_image_src_cb(lv_observer_t * observer, lv_subject_t * subject);
|
||||
void lv_demo_high_res_theme_observer_obj_bg_image_src_cb(lv_observer_t * observer, lv_subject_t * subject);
|
||||
lv_image_dsc_t * lv_demo_high_res_image_preload(const void * src, lv_color_format_t cf);
|
||||
lv_image_dsc_t * lv_demo_high_res_image_preload(const void * src, lv_color_format_t cf, int32_t scale);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
@ -260,7 +260,7 @@ lv_obj_t * lv_demo_high_res_base_obj_create(const char * assets_path,
|
||||
int chars = lv_snprintf(path_buf, sizeof(path_buf), "%s/img_lv_demo_high_res_%s_%s.png",
|
||||
assets_path, image_details[i].name, size_prefix);
|
||||
LV_ASSERT(chars < (int)sizeof(path_buf));
|
||||
c->imgs[i] = lv_demo_high_res_image_preload(path_buf, image_details[i].cf);
|
||||
c->imgs[i] = lv_demo_high_res_image_preload(path_buf, image_details[i].cf, LV_SCALE_NONE);
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) {
|
||||
@ -274,7 +274,7 @@ lv_obj_t * lv_demo_high_res_base_obj_create(const char * assets_path,
|
||||
}
|
||||
c->sz->init_fonts_cb(c->fonts);
|
||||
|
||||
lv_subject_init_pointer(&c->th, (void *)&lv_demo_high_res_theme_light);
|
||||
lv_subject_init_pointer(&c->th, (void *)&lv_demo_high_res_theme_dark);
|
||||
c->th.user_data = c;
|
||||
lv_subject_add_observer(&c->th, theme_observer_cb, c);
|
||||
|
||||
@ -333,6 +333,43 @@ lv_obj_t * lv_demo_high_res_base_obj_create(const char * assets_path,
|
||||
lv_subject_init_group(&c->subject_groups.wifi.group, c->subject_groups.wifi.members,
|
||||
ARRAY_LEN(c->subject_groups.wifi.members));
|
||||
|
||||
lv_array_init(&c->about_slides_array, 1, sizeof(lv_image_dsc_t *));
|
||||
lv_fs_dir_t dir;
|
||||
lv_fs_res_t fs_res = lv_fs_dir_open(&dir, slides_path);
|
||||
if(fs_res == LV_FS_RES_OK) {
|
||||
fs_res = lv_fs_dir_close(&dir);
|
||||
LV_ASSERT(fs_res == LV_FS_RES_OK);
|
||||
|
||||
c->about_slides_dir_exists = true;
|
||||
|
||||
for(int32_t i = 1; ; i++) {
|
||||
char buf[256];
|
||||
lv_snprintf(buf, sizeof(buf), "%s/Slide%"LV_PRId32".png", slides_path, i);
|
||||
lv_fs_file_t file;
|
||||
fs_res = lv_fs_open(&file, buf, LV_FS_MODE_RD);
|
||||
if(fs_res != LV_FS_RES_OK) {
|
||||
break;
|
||||
}
|
||||
fs_res = lv_fs_close(&file);
|
||||
LV_ASSERT(fs_res == LV_FS_RES_OK);
|
||||
|
||||
lv_image_header_t header;
|
||||
lv_result_t res = lv_image_decoder_get_info(buf, &header);
|
||||
if(res == LV_RESULT_INVALID) {
|
||||
LV_LOG_WARN("Couldn't read the header info of slide image");
|
||||
continue;
|
||||
}
|
||||
/* the ratio of a slide's height to the display's height will be 9:16 */
|
||||
int32_t scale = (9 * 256 * vres) / (16 * header.h);
|
||||
|
||||
lv_image_dsc_t * loaded_draw_buf = lv_demo_high_res_image_preload(buf, LV_COLOR_FORMAT_NATIVE, scale);
|
||||
if(loaded_draw_buf == NULL) continue;
|
||||
lv_array_push_back(&c->about_slides_array, &loaded_draw_buf);
|
||||
|
||||
if(scale != LV_SCALE_NONE) LV_LOG_INFO("A slide was scaled by %"LV_PRId32" (256 means 1:1)", scale);
|
||||
}
|
||||
}
|
||||
|
||||
return base_obj;
|
||||
}
|
||||
|
||||
@ -391,7 +428,7 @@ void lv_demo_high_res_theme_observer_obj_bg_image_src_cb(lv_observer_t * observe
|
||||
}
|
||||
}
|
||||
|
||||
lv_image_dsc_t * lv_demo_high_res_image_preload(const void * src, lv_color_format_t cf)
|
||||
lv_image_dsc_t * lv_demo_high_res_image_preload(const void * src, lv_color_format_t cf, int32_t scale)
|
||||
{
|
||||
lv_image_header_t header;
|
||||
lv_result_t res = lv_image_decoder_get_info(src, &header);
|
||||
@ -401,7 +438,9 @@ lv_image_dsc_t * lv_demo_high_res_image_preload(const void * src, lv_color_forma
|
||||
}
|
||||
|
||||
lv_draw_buf_t * dest;
|
||||
dest = lv_draw_buf_create(header.w, header.h, cf, LV_STRIDE_AUTO);
|
||||
int32_t dest_w = header.w * scale / 256;
|
||||
int32_t dest_h = header.h * scale / 256;
|
||||
dest = lv_draw_buf_create(dest_w, dest_h, cf, LV_STRIDE_AUTO);
|
||||
|
||||
lv_obj_t * canvas = lv_canvas_create(lv_screen_active());
|
||||
lv_canvas_set_draw_buf(canvas, dest);
|
||||
@ -413,8 +452,10 @@ lv_image_dsc_t * lv_demo_high_res_image_preload(const void * src, lv_color_forma
|
||||
lv_draw_image_dsc_t dsc;
|
||||
lv_draw_image_dsc_init(&dsc);
|
||||
dsc.src = src;
|
||||
dsc.scale_x = scale;
|
||||
dsc.scale_y = scale;
|
||||
|
||||
lv_area_t coords = {0, 0, LV_MIN(header.w, dest->header.w) - 1, LV_MIN(header.h, dest->header.h) - 1};
|
||||
lv_area_t coords = {0, 0, header.w - 1, header.h - 1};
|
||||
lv_draw_image(&layer, &dsc, &coords);
|
||||
lv_canvas_finish_layer(canvas, &layer);
|
||||
|
||||
@ -545,6 +586,13 @@ static void free_ctx_event_cb(lv_event_t * e)
|
||||
lv_subject_deinit(&subjects[i]);
|
||||
}
|
||||
|
||||
uint32_t about_slides_count = lv_array_size(&c->about_slides_array);
|
||||
for(uint32_t i = 0; i < about_slides_count; i++) {
|
||||
lv_image_dsc_t ** slide = lv_array_at(&c->about_slides_array, i);
|
||||
lv_draw_buf_destroy((lv_draw_buf_t *) *slide);
|
||||
}
|
||||
lv_array_deinit(&c->about_slides_array);
|
||||
|
||||
lv_free(c);
|
||||
|
||||
lv_obj_set_user_data(base_obj, NULL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user