loading is lazy evaluated now, swish animation needed to go because one image is loaded at a time, animation was not visually noticable beside that (esp speed)
This commit is contained in:
+118
-116
@@ -21,40 +21,29 @@
|
|||||||
#define UI_IMAGE_PROBE_HEADER_LENGTH 16
|
#define UI_IMAGE_PROBE_HEADER_LENGTH 16
|
||||||
#define UI_SLIDESHOW_PERIOD_MS 3000
|
#define UI_SLIDESHOW_PERIOD_MS 3000
|
||||||
|
|
||||||
static lv_obj_t *image_tileview = NULL;
|
static lv_obj_t *image_view = NULL;
|
||||||
|
static lv_obj_t *image_widget = NULL;
|
||||||
|
static lv_obj_t *image_caption = NULL;
|
||||||
|
static lv_obj_t *image_error_label = NULL;
|
||||||
static lv_timer_t *image_slideshow_timer = NULL;
|
static lv_timer_t *image_slideshow_timer = NULL;
|
||||||
static size_t image_browser_image_count = 0;
|
static size_t image_browser_image_count = 0;
|
||||||
static size_t image_browser_current_index = 0;
|
static size_t image_browser_current_index = 0;
|
||||||
static const char **image_browser_names = NULL;
|
static const char **image_browser_names = NULL;
|
||||||
static size_t image_browser_last_logged_index = SIZE_MAX;
|
|
||||||
static const char *TAG = "ui";
|
static const char *TAG = "ui";
|
||||||
|
|
||||||
static void ui_image_browser_log_current(void){
|
static void ui_image_browser_load_current(void);
|
||||||
if(image_browser_current_index == image_browser_last_logged_index) return;
|
|
||||||
image_browser_last_logged_index = image_browser_current_index;
|
|
||||||
|
|
||||||
const char *filename = "?";
|
static void ui_image_browser_show_index(size_t image_index){
|
||||||
if(image_browser_names != NULL && image_browser_current_index < image_browser_image_count){
|
if(image_widget == NULL || image_browser_image_count == 0) return;
|
||||||
filename = image_browser_names[image_browser_current_index];
|
|
||||||
}
|
|
||||||
ui_log_appendf("Show %u/%u: %s",
|
|
||||||
(unsigned int)(image_browser_current_index + 1),
|
|
||||||
(unsigned int)image_browser_image_count,
|
|
||||||
filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ui_image_browser_set_index(size_t image_index, lv_anim_enable_t anim_en){
|
|
||||||
if(image_tileview == NULL || image_browser_image_count == 0) return;
|
|
||||||
|
|
||||||
image_browser_current_index = image_index % image_browser_image_count;
|
image_browser_current_index = image_index % image_browser_image_count;
|
||||||
lv_tileview_set_tile_by_index(image_tileview, 0, (uint32_t)image_browser_current_index, anim_en);
|
ui_image_browser_load_current();
|
||||||
ui_image_browser_log_current();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ui_image_slideshow_timer_cb(lv_timer_t *timer){
|
static void ui_image_slideshow_timer_cb(lv_timer_t *timer){
|
||||||
(void)timer;
|
(void)timer;
|
||||||
if(ui_current_view() != UI_VIEW_IMAGE_BROWSER) return;
|
if(ui_current_view() != UI_VIEW_IMAGE_BROWSER) return;
|
||||||
ui_image_browser_set_index(image_browser_current_index + 1, LV_ANIM_ON);
|
ui_image_browser_show_index(image_browser_current_index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ui_start_image_slideshow(void){
|
static void ui_start_image_slideshow(void){
|
||||||
@@ -62,15 +51,22 @@ static void ui_start_image_slideshow(void){
|
|||||||
image_slideshow_timer = lv_timer_create(ui_image_slideshow_timer_cb, UI_SLIDESHOW_PERIOD_MS, NULL);
|
image_slideshow_timer = lv_timer_create(ui_image_slideshow_timer_cb, UI_SLIDESHOW_PERIOD_MS, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ui_image_browser_value_changed_event_cb(lv_event_t *event){
|
static void ui_image_browser_gesture_event_cb(lv_event_t *event){
|
||||||
if(lv_event_get_code(event) != LV_EVENT_VALUE_CHANGED) return;
|
if(lv_event_get_code(event) != LV_EVENT_GESTURE) return;
|
||||||
|
if(image_browser_image_count <= 1) return;
|
||||||
|
|
||||||
lv_obj_t *tileview = lv_event_get_current_target(event);
|
lv_indev_t *indev = lv_indev_active();
|
||||||
lv_obj_t *active_tile = lv_tileview_get_tile_active(tileview);
|
if(indev == NULL) return;
|
||||||
if(active_tile == NULL) return;
|
|
||||||
|
|
||||||
image_browser_current_index = (size_t)(uintptr_t)lv_obj_get_user_data(active_tile);
|
const lv_dir_t gesture_dir = lv_indev_get_gesture_dir(indev);
|
||||||
ui_image_browser_log_current();
|
if(gesture_dir == LV_DIR_TOP){
|
||||||
|
lv_indev_wait_release(indev);
|
||||||
|
ui_image_browser_show_index(image_browser_current_index + 1);
|
||||||
|
}
|
||||||
|
else if(gesture_dir == LV_DIR_BOTTOM){
|
||||||
|
lv_indev_wait_release(indev);
|
||||||
|
ui_image_browser_show_index(image_browser_current_index + image_browser_image_count - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ui_char_equals_ignore_case(char left_char, char right_char){
|
static bool ui_char_equals_ignore_case(char left_char, char right_char){
|
||||||
@@ -203,92 +199,55 @@ static void ui_create_empty_image_browser(lv_obj_t *screen){
|
|||||||
lv_obj_center(label);
|
lv_obj_center(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
static lv_dir_t ui_get_tile_directions(size_t image_index, size_t image_count){
|
static void ui_collect_image_names(size_t image_count){
|
||||||
if(image_count <= 1) return LV_DIR_NONE;
|
if(image_browser_names == NULL) return;
|
||||||
if(image_index == 0) return LV_DIR_BOTTOM;
|
|
||||||
if(image_index + 1 == image_count) return LV_DIR_TOP;
|
|
||||||
return (lv_dir_t)(LV_DIR_TOP | LV_DIR_BOTTOM);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ui_create_image_tile(lv_obj_t *tile, const char *filename, size_t image_index, size_t image_count){
|
|
||||||
ui_attach_toggle(tile);
|
|
||||||
lv_obj_set_style_bg_color(tile, lv_color_hex(0x070a0d), 0);
|
|
||||||
lv_obj_set_style_pad_all(tile, 0, 0);
|
|
||||||
lv_obj_remove_flag(tile, LV_OBJ_FLAG_SCROLLABLE);
|
|
||||||
|
|
||||||
lv_obj_t *image_frame = lv_obj_create(tile);
|
|
||||||
ui_attach_toggle(image_frame);
|
|
||||||
lv_obj_set_size(image_frame, LV_PCT(100), LV_PCT(100));
|
|
||||||
lv_obj_set_style_bg_color(image_frame, lv_color_black(), 0);
|
|
||||||
lv_obj_set_style_border_width(image_frame, 0, 0);
|
|
||||||
lv_obj_set_style_radius(image_frame, 0, 0);
|
|
||||||
lv_obj_set_style_pad_all(image_frame, 0, 0);
|
|
||||||
lv_obj_remove_flag(image_frame, LV_OBJ_FLAG_SCROLLABLE);
|
|
||||||
lv_obj_center(image_frame);
|
|
||||||
|
|
||||||
lv_obj_t *image = lv_image_create(image_frame);
|
|
||||||
ui_attach_toggle(image);
|
|
||||||
lv_obj_set_size(image, LV_PCT(100), LV_PCT(100));
|
|
||||||
lv_image_set_inner_align(image, LV_IMAGE_ALIGN_CONTAIN);
|
|
||||||
|
|
||||||
char image_source[UI_IMAGE_PATH_MAX_LENGTH];
|
|
||||||
snprintf(image_source, sizeof(image_source), "%s%s", UI_IMAGE_PATH_PREFIX, filename);
|
|
||||||
ui_lowercase_path_extension(image_source);
|
|
||||||
lv_image_set_src(image, image_source);
|
|
||||||
lv_obj_center(image);
|
|
||||||
|
|
||||||
lv_obj_t *info_bar = lv_obj_create(tile);
|
|
||||||
ui_attach_toggle(info_bar);
|
|
||||||
lv_obj_set_size(info_bar, LV_PCT(100), UI_IMAGE_INFO_BAR_HEIGHT);
|
|
||||||
lv_obj_align(info_bar, LV_ALIGN_BOTTOM_MID, 0, -UI_IMAGE_INFO_BAR_BOTTOM_OFFSET);
|
|
||||||
lv_obj_set_style_bg_color(info_bar, lv_color_hex(0x101418), 0);
|
|
||||||
lv_obj_set_style_bg_opa(info_bar, LV_OPA_80, 0);
|
|
||||||
lv_obj_set_style_border_width(info_bar, 0, 0);
|
|
||||||
lv_obj_set_style_radius(info_bar, 0, 0);
|
|
||||||
lv_obj_set_style_pad_hor(info_bar, 14, 0);
|
|
||||||
lv_obj_set_style_pad_ver(info_bar, 0, 0);
|
|
||||||
lv_obj_remove_flag(info_bar, LV_OBJ_FLAG_SCROLLABLE);
|
|
||||||
|
|
||||||
lv_obj_t *caption = lv_label_create(info_bar);
|
|
||||||
ui_attach_toggle(caption);
|
|
||||||
lv_label_set_long_mode(caption, LV_LABEL_LONG_DOT);
|
|
||||||
lv_obj_set_width(caption, LV_PCT(100));
|
|
||||||
lv_obj_set_style_text_color(caption, lv_color_hex(0xdde7ef), 0);
|
|
||||||
lv_label_set_text_fmt(caption, "%u/%u %s", (unsigned int)(image_index + 1), (unsigned int)image_count, filename);
|
|
||||||
lv_obj_center(caption);
|
|
||||||
|
|
||||||
if(lv_image_get_src_width(image) <= 0 || lv_image_get_src_height(image) <= 0){
|
|
||||||
const char *load_reason = ui_probe_image_load_failure(filename, image_source);
|
|
||||||
ESP_LOGW(TAG, "Image cannot be loaded by LVGL: %s reason=%s", image_source, load_reason);
|
|
||||||
ui_log_appendf("Image load failed: %s (%s)", filename, load_reason);
|
|
||||||
lv_obj_t *error_label = lv_label_create(tile);
|
|
||||||
ui_attach_toggle(error_label);
|
|
||||||
lv_label_set_text_fmt(error_label, "Image cannot be loaded\n%s\n%s", filename, load_reason);
|
|
||||||
lv_obj_set_style_text_color(error_label, lv_color_hex(0xffd166), 0);
|
|
||||||
lv_obj_set_style_text_align(error_label, LV_TEXT_ALIGN_CENTER, 0);
|
|
||||||
lv_obj_set_width(error_label, LV_PCT(86));
|
|
||||||
lv_obj_align(error_label, LV_ALIGN_CENTER, 0, -18);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
ui_log_appendf("Loaded %u/%u: %s (%dx%d)",
|
|
||||||
(unsigned int)(image_index + 1), (unsigned int)image_count, filename,
|
|
||||||
(int)lv_image_get_src_width(image), (int)lv_image_get_src_height(image));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ui_create_image_browser_tiles(size_t image_count){
|
|
||||||
const size_t file_count = sd_get_file_count();
|
const size_t file_count = sd_get_file_count();
|
||||||
size_t image_index = 0;
|
size_t image_index = 0;
|
||||||
|
|
||||||
for(size_t file_index = 0; file_index < file_count && image_index < image_count; file_index++){
|
for(size_t file_index = 0; file_index < file_count && image_index < image_count; file_index++){
|
||||||
const char *filename = sd_get_next_file();
|
const char *filename = sd_get_next_file();
|
||||||
if(!ui_is_image_file(filename)) continue;
|
if(!ui_is_image_file(filename)) continue;
|
||||||
|
image_browser_names[image_index++] = filename;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lv_obj_t *tile = lv_tileview_add_tile(image_tileview, 0, (uint32_t)image_index, ui_get_tile_directions(image_index, image_count));
|
static void ui_image_browser_load_current(void){
|
||||||
lv_obj_set_user_data(tile, (void *)(uintptr_t)image_index);
|
if(image_widget == NULL || image_browser_names == NULL || image_browser_image_count == 0) return;
|
||||||
if(image_browser_names != NULL) image_browser_names[image_index] = filename;
|
|
||||||
ui_create_image_tile(tile, filename, image_index, image_count);
|
const char *filename = image_browser_names[image_browser_current_index];
|
||||||
image_index++;
|
|
||||||
|
char image_source[UI_IMAGE_PATH_MAX_LENGTH];
|
||||||
|
snprintf(image_source, sizeof(image_source), "%s%s", UI_IMAGE_PATH_PREFIX, filename);
|
||||||
|
ui_lowercase_path_extension(image_source);
|
||||||
|
lv_image_set_src(image_widget, image_source);
|
||||||
|
|
||||||
|
if(image_caption != NULL){
|
||||||
|
lv_label_set_text_fmt(image_caption, "%u/%u %s",
|
||||||
|
(unsigned int)(image_browser_current_index + 1),
|
||||||
|
(unsigned int)image_browser_image_count, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lv_image_get_src_width(image_widget) <= 0 || lv_image_get_src_height(image_widget) <= 0){
|
||||||
|
const char *load_reason = ui_probe_image_load_failure(filename, image_source);
|
||||||
|
ESP_LOGW(TAG, "Image cannot be loaded by LVGL: %s reason=%s", image_source, load_reason);
|
||||||
|
ui_log_appendf("Image load failed: %s (%s)", filename, load_reason);
|
||||||
|
|
||||||
|
lv_obj_add_flag(image_widget, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if(image_error_label != NULL){
|
||||||
|
lv_label_set_text_fmt(image_error_label, "Image cannot be loaded\n%s\n%s", filename, load_reason);
|
||||||
|
lv_obj_remove_flag(image_error_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
ui_log_appendf("Loaded %u/%u: %s (%dx%d)",
|
||||||
|
(unsigned int)(image_browser_current_index + 1),
|
||||||
|
(unsigned int)image_browser_image_count, filename,
|
||||||
|
(int)lv_image_get_src_width(image_widget),
|
||||||
|
(int)lv_image_get_src_height(image_widget));
|
||||||
|
|
||||||
|
lv_obj_remove_flag(image_widget, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if(image_error_label != NULL) lv_obj_add_flag(image_error_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,18 +263,59 @@ void ui_image_browser_build_view(lv_obj_t *screen){
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
image_tileview = lv_tileview_create(screen);
|
|
||||||
lv_obj_set_size(image_tileview, LV_PCT(100), LV_PCT(100));
|
|
||||||
lv_obj_set_style_bg_color(image_tileview, lv_color_hex(0x070a0d), 0);
|
|
||||||
lv_obj_set_style_border_width(image_tileview, 0, 0);
|
|
||||||
lv_obj_set_style_pad_all(image_tileview, 0, 0);
|
|
||||||
lv_obj_set_scrollbar_mode(image_tileview, LV_SCROLLBAR_MODE_OFF);
|
|
||||||
lv_obj_add_event_cb(image_tileview, ui_image_browser_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
|
||||||
image_browser_image_count = image_count;
|
image_browser_image_count = image_count;
|
||||||
|
image_browser_current_index = 0;
|
||||||
image_browser_names = calloc(image_count, sizeof(const char *));
|
image_browser_names = calloc(image_count, sizeof(const char *));
|
||||||
|
ui_collect_image_names(image_count);
|
||||||
|
|
||||||
ui_create_image_browser_tiles(image_count);
|
image_view = lv_obj_create(screen);
|
||||||
ui_image_browser_set_index(0, LV_ANIM_OFF);
|
ui_attach_toggle(image_view);
|
||||||
|
lv_obj_set_size(image_view, LV_PCT(100), LV_PCT(100));
|
||||||
|
lv_obj_center(image_view);
|
||||||
|
lv_obj_set_style_bg_color(image_view, lv_color_hex(0x070a0d), 0);
|
||||||
|
lv_obj_set_style_bg_opa(image_view, LV_OPA_COVER, 0);
|
||||||
|
lv_obj_set_style_border_width(image_view, 0, 0);
|
||||||
|
lv_obj_set_style_radius(image_view, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(image_view, 0, 0);
|
||||||
|
lv_obj_remove_flag(image_view, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
lv_obj_remove_flag(image_view, LV_OBJ_FLAG_GESTURE_BUBBLE);
|
||||||
|
lv_obj_add_event_cb(image_view, ui_image_browser_gesture_event_cb, LV_EVENT_GESTURE, NULL);
|
||||||
|
|
||||||
|
image_widget = lv_image_create(image_view);
|
||||||
|
ui_attach_toggle(image_widget);
|
||||||
|
lv_obj_set_size(image_widget, LV_PCT(100), LV_PCT(100));
|
||||||
|
lv_image_set_inner_align(image_widget, LV_IMAGE_ALIGN_CONTAIN);
|
||||||
|
lv_obj_center(image_widget);
|
||||||
|
|
||||||
|
lv_obj_t *info_bar = lv_obj_create(image_view);
|
||||||
|
ui_attach_toggle(info_bar);
|
||||||
|
lv_obj_set_size(info_bar, LV_PCT(100), UI_IMAGE_INFO_BAR_HEIGHT);
|
||||||
|
lv_obj_align(info_bar, LV_ALIGN_BOTTOM_MID, 0, -UI_IMAGE_INFO_BAR_BOTTOM_OFFSET);
|
||||||
|
lv_obj_set_style_bg_color(info_bar, lv_color_hex(0x101418), 0);
|
||||||
|
lv_obj_set_style_bg_opa(info_bar, LV_OPA_80, 0);
|
||||||
|
lv_obj_set_style_border_width(info_bar, 0, 0);
|
||||||
|
lv_obj_set_style_radius(info_bar, 0, 0);
|
||||||
|
lv_obj_set_style_pad_hor(info_bar, 14, 0);
|
||||||
|
lv_obj_set_style_pad_ver(info_bar, 0, 0);
|
||||||
|
lv_obj_remove_flag(info_bar, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
|
||||||
|
image_caption = lv_label_create(info_bar);
|
||||||
|
ui_attach_toggle(image_caption);
|
||||||
|
lv_label_set_long_mode(image_caption, LV_LABEL_LONG_DOT);
|
||||||
|
lv_obj_set_width(image_caption, LV_PCT(100));
|
||||||
|
lv_obj_set_style_text_color(image_caption, lv_color_hex(0xdde7ef), 0);
|
||||||
|
lv_obj_center(image_caption);
|
||||||
|
|
||||||
|
image_error_label = lv_label_create(image_view);
|
||||||
|
ui_attach_toggle(image_error_label);
|
||||||
|
lv_label_set_text(image_error_label, "");
|
||||||
|
lv_obj_set_style_text_color(image_error_label, lv_color_hex(0xffd166), 0);
|
||||||
|
lv_obj_set_style_text_align(image_error_label, LV_TEXT_ALIGN_CENTER, 0);
|
||||||
|
lv_obj_set_width(image_error_label, LV_PCT(86));
|
||||||
|
lv_obj_align(image_error_label, LV_ALIGN_CENTER, 0, -18);
|
||||||
|
lv_obj_add_flag(image_error_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
|
||||||
|
ui_image_browser_show_index(0);
|
||||||
ui_start_image_slideshow();
|
ui_start_image_slideshow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,10 +327,12 @@ void ui_image_browser_reset(void){
|
|||||||
|
|
||||||
free((void *)image_browser_names);
|
free((void *)image_browser_names);
|
||||||
image_browser_names = NULL;
|
image_browser_names = NULL;
|
||||||
image_tileview = NULL;
|
image_view = NULL;
|
||||||
|
image_widget = NULL;
|
||||||
|
image_caption = NULL;
|
||||||
|
image_error_label = NULL;
|
||||||
image_browser_image_count = 0;
|
image_browser_image_count = 0;
|
||||||
image_browser_current_index = 0;
|
image_browser_current_index = 0;
|
||||||
image_browser_last_logged_index = SIZE_MAX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ui_image_browser_get_image_count(void){
|
size_t ui_image_browser_get_image_count(void){
|
||||||
|
|||||||
Reference in New Issue
Block a user