fix(ui): make card view scrollable via rotary encoder with pinned header and footer
All checks were successful
ESP32 Build & Release / build (push) Successful in 1m11s
All checks were successful
ESP32 Build & Release / build (push) Successful in 1m11s
This commit is contained in:
106
main/ui_task.c
106
main/ui_task.c
@@ -119,6 +119,9 @@ static lv_obj_t *s_ota_bar = NULL;
|
|||||||
static lv_obj_t *s_ota_pct_lbl = NULL;
|
static lv_obj_t *s_ota_pct_lbl = NULL;
|
||||||
static lv_obj_t *s_ota_bytes_lbl = NULL;
|
static lv_obj_t *s_ota_bytes_lbl = NULL;
|
||||||
|
|
||||||
|
/* Card view scrollable container */
|
||||||
|
static lv_obj_t *s_card_scroll_cont = NULL;
|
||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
static void view_menu(void);
|
static void view_menu(void);
|
||||||
static void view_scanner(void);
|
static void view_scanner(void);
|
||||||
@@ -248,6 +251,7 @@ static const char *get_json_str(cJSON *root, const char *key, const char *fallba
|
|||||||
static void ui_clean_screen(void)
|
static void ui_clean_screen(void)
|
||||||
{
|
{
|
||||||
free_art_buffer();
|
free_art_buffer();
|
||||||
|
s_card_scroll_cont = NULL;
|
||||||
s_ota_bar = NULL;
|
s_ota_bar = NULL;
|
||||||
s_ota_pct_lbl = NULL;
|
s_ota_pct_lbl = NULL;
|
||||||
s_ota_bytes_lbl = NULL;
|
s_ota_bytes_lbl = NULL;
|
||||||
@@ -1425,9 +1429,10 @@ static void view_card(void)
|
|||||||
lv_obj_set_style_border_width(card_box, 2, 0);
|
lv_obj_set_style_border_width(card_box, 2, 0);
|
||||||
lv_obj_set_style_radius(card_box, 6, 0);
|
lv_obj_set_style_radius(card_box, 6, 0);
|
||||||
lv_obj_set_style_pad_all(card_box, 6, 0);
|
lv_obj_set_style_pad_all(card_box, 6, 0);
|
||||||
|
lv_obj_clear_flag(card_box, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
lv_obj_set_scrollbar_mode(card_box, LV_SCROLLBAR_MODE_OFF);
|
lv_obj_set_scrollbar_mode(card_box, LV_SCROLLBAR_MODE_OFF);
|
||||||
|
|
||||||
/* Name */
|
/* Pinned Header: Name */
|
||||||
lv_obj_t *name_lbl = lv_label_create(card_box);
|
lv_obj_t *name_lbl = lv_label_create(card_box);
|
||||||
lv_label_set_text(name_lbl, name);
|
lv_label_set_text(name_lbl, name);
|
||||||
lv_obj_set_style_text_font(name_lbl, &lv_font_montserrat_14, 0);
|
lv_obj_set_style_text_font(name_lbl, &lv_font_montserrat_14, 0);
|
||||||
@@ -1437,7 +1442,7 @@ static void view_card(void)
|
|||||||
lv_label_set_long_mode(name_lbl, LV_LABEL_LONG_DOT);
|
lv_label_set_long_mode(name_lbl, LV_LABEL_LONG_DOT);
|
||||||
lv_obj_align(name_lbl, LV_ALIGN_TOP_LEFT, 0, 0);
|
lv_obj_align(name_lbl, LV_ALIGN_TOP_LEFT, 0, 0);
|
||||||
|
|
||||||
/* Mana */
|
/* Pinned Header: Mana */
|
||||||
if (mana[0]) {
|
if (mana[0]) {
|
||||||
lv_obj_t *mana_lbl = lv_label_create(card_box);
|
lv_obj_t *mana_lbl = lv_label_create(card_box);
|
||||||
lv_label_set_text(mana_lbl, mana);
|
lv_label_set_text(mana_lbl, mana);
|
||||||
@@ -1446,41 +1451,7 @@ static void view_card(void)
|
|||||||
lv_obj_align(mana_lbl, LV_ALIGN_TOP_RIGHT, 0, 0);
|
lv_obj_align(mana_lbl, LV_ALIGN_TOP_RIGHT, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cur_y = 20;
|
/* Pinned Footer: P/T or Loyalty */
|
||||||
|
|
||||||
/* Art Crop Image */
|
|
||||||
if (has_art) {
|
|
||||||
lv_obj_t *img = lv_img_create(card_box);
|
|
||||||
lv_img_set_src(img, &s_art_img_dsc);
|
|
||||||
lv_obj_align(img, LV_ALIGN_TOP_MID, 0, cur_y);
|
|
||||||
lv_obj_set_style_border_color(img, lv_color_hex(0x8B6508), 0);
|
|
||||||
lv_obj_set_style_border_width(img, 1, 0);
|
|
||||||
lv_obj_set_style_radius(img, 3, 0);
|
|
||||||
cur_y += s_art_img_dsc.header.h + 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Type */
|
|
||||||
lv_obj_t *type_lbl = lv_label_create(card_box);
|
|
||||||
lv_label_set_text(type_lbl, type);
|
|
||||||
lv_obj_set_style_text_font(type_lbl, &lv_font_montserrat_14, 0);
|
|
||||||
lv_obj_set_style_text_color(type_lbl, lv_color_white(), 0);
|
|
||||||
lv_obj_set_width(type_lbl, DISP_W - 28);
|
|
||||||
lv_label_set_long_mode(type_lbl, LV_LABEL_LONG_DOT);
|
|
||||||
lv_obj_align(type_lbl, LV_ALIGN_TOP_LEFT, 0, cur_y);
|
|
||||||
cur_y += 18;
|
|
||||||
|
|
||||||
/* Oracle text */
|
|
||||||
if (oracle[0]) {
|
|
||||||
lv_obj_t *oracle_lbl = lv_label_create(card_box);
|
|
||||||
lv_label_set_text(oracle_lbl, oracle);
|
|
||||||
lv_label_set_long_mode(oracle_lbl, LV_LABEL_LONG_WRAP);
|
|
||||||
lv_obj_set_width(oracle_lbl, DISP_W - 32);
|
|
||||||
lv_obj_set_style_text_font(oracle_lbl, &lv_font_montserrat_14, 0);
|
|
||||||
lv_obj_set_style_text_color(oracle_lbl, lv_color_hex(COLOR_AMBER), 0);
|
|
||||||
lv_obj_align(oracle_lbl, LV_ALIGN_TOP_LEFT, 0, cur_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bottom: P/T, Loyalty, and Price */
|
|
||||||
if (power[0] || tough[0]) {
|
if (power[0] || tough[0]) {
|
||||||
lv_obj_t *pt_lbl = lv_label_create(card_box);
|
lv_obj_t *pt_lbl = lv_label_create(card_box);
|
||||||
lv_label_set_text_fmt(pt_lbl, "%s / %s", power, tough);
|
lv_label_set_text_fmt(pt_lbl, "%s / %s", power, tough);
|
||||||
@@ -1495,6 +1466,7 @@ static void view_card(void)
|
|||||||
lv_obj_align(loy_lbl, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
|
lv_obj_align(loy_lbl, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Pinned Footer: Price */
|
||||||
if (price[0]) {
|
if (price[0]) {
|
||||||
lv_obj_t *pr_lbl = lv_label_create(card_box);
|
lv_obj_t *pr_lbl = lv_label_create(card_box);
|
||||||
lv_label_set_text_fmt(pr_lbl, "$%s", price);
|
lv_label_set_text_fmt(pr_lbl, "$%s", price);
|
||||||
@@ -1503,6 +1475,56 @@ static void view_card(void)
|
|||||||
lv_obj_align(pr_lbl, LV_ALIGN_BOTTOM_LEFT, 0, 0);
|
lv_obj_align(pr_lbl, LV_ALIGN_BOTTOM_LEFT, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Middle Scrollable Container (Art + Type + Oracle Text) */
|
||||||
|
s_card_scroll_cont = lv_obj_create(card_box);
|
||||||
|
lv_obj_set_size(s_card_scroll_cont, lv_pct(100), 250);
|
||||||
|
lv_obj_set_pos(s_card_scroll_cont, 0, 22);
|
||||||
|
lv_obj_set_style_bg_opa(s_card_scroll_cont, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_border_width(s_card_scroll_cont, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(s_card_scroll_cont, 0, 0);
|
||||||
|
lv_obj_set_style_pad_right(s_card_scroll_cont, 6, 0);
|
||||||
|
lv_obj_set_style_pad_bottom(s_card_scroll_cont, 24, 0);
|
||||||
|
lv_obj_set_scrollbar_mode(s_card_scroll_cont, LV_SCROLLBAR_MODE_AUTO);
|
||||||
|
lv_obj_set_scroll_dir(s_card_scroll_cont, LV_DIR_VER);
|
||||||
|
lv_obj_set_style_bg_color(s_card_scroll_cont, lv_color_hex(COLOR_GOLD), LV_PART_SCROLLBAR);
|
||||||
|
lv_obj_set_style_bg_opa(s_card_scroll_cont, LV_OPA_70, LV_PART_SCROLLBAR);
|
||||||
|
lv_obj_set_style_width(s_card_scroll_cont, 4, LV_PART_SCROLLBAR);
|
||||||
|
|
||||||
|
int cur_y = 0;
|
||||||
|
|
||||||
|
/* Art Crop Image */
|
||||||
|
if (has_art) {
|
||||||
|
lv_obj_t *img = lv_img_create(s_card_scroll_cont);
|
||||||
|
lv_img_set_src(img, &s_art_img_dsc);
|
||||||
|
lv_obj_align(img, LV_ALIGN_TOP_MID, 0, cur_y);
|
||||||
|
lv_obj_set_style_border_color(img, lv_color_hex(0x8B6508), 0);
|
||||||
|
lv_obj_set_style_border_width(img, 1, 0);
|
||||||
|
lv_obj_set_style_radius(img, 3, 0);
|
||||||
|
cur_y += s_art_img_dsc.header.h + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Type */
|
||||||
|
lv_obj_t *type_lbl = lv_label_create(s_card_scroll_cont);
|
||||||
|
lv_label_set_text(type_lbl, type);
|
||||||
|
lv_obj_set_style_text_font(type_lbl, &lv_font_montserrat_14, 0);
|
||||||
|
lv_obj_set_style_text_color(type_lbl, lv_color_white(), 0);
|
||||||
|
lv_obj_set_width(type_lbl, DISP_W - 32);
|
||||||
|
lv_label_set_long_mode(type_lbl, LV_LABEL_LONG_WRAP);
|
||||||
|
lv_obj_align(type_lbl, LV_ALIGN_TOP_LEFT, 0, cur_y);
|
||||||
|
lv_obj_update_layout(type_lbl);
|
||||||
|
cur_y += lv_obj_get_height(type_lbl) + 4;
|
||||||
|
|
||||||
|
/* Oracle text */
|
||||||
|
if (oracle[0]) {
|
||||||
|
lv_obj_t *oracle_lbl = lv_label_create(s_card_scroll_cont);
|
||||||
|
lv_label_set_text(oracle_lbl, oracle);
|
||||||
|
lv_label_set_long_mode(oracle_lbl, LV_LABEL_LONG_WRAP);
|
||||||
|
lv_obj_set_width(oracle_lbl, DISP_W - 36);
|
||||||
|
lv_obj_set_style_text_font(oracle_lbl, &lv_font_montserrat_14, 0);
|
||||||
|
lv_obj_set_style_text_color(oracle_lbl, lv_color_hex(COLOR_AMBER), 0);
|
||||||
|
lv_obj_align(oracle_lbl, LV_ALIGN_TOP_LEFT, 0, cur_y);
|
||||||
|
}
|
||||||
|
|
||||||
lvgl_port_unlock();
|
lvgl_port_unlock();
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
}
|
}
|
||||||
@@ -1855,6 +1877,16 @@ static void handle_encoder_rotation(int32_t delta)
|
|||||||
if (delta == 0) return;
|
if (delta == 0) return;
|
||||||
|
|
||||||
app_state_t cur = app_get_view();
|
app_state_t cur = app_get_view();
|
||||||
|
if (cur == APP_STATE_CARD_VIEW) {
|
||||||
|
if (s_card_scroll_cont != NULL) {
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
lv_obj_scroll_by_bounded(s_card_scroll_cont, 0, -delta * 35, LV_ANIM_ON);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
buzzer_chirp(600, 10);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t dir = (delta > 0) ? 1 : -1;
|
int32_t dir = (delta > 0) ? 1 : -1;
|
||||||
int32_t count = (delta > 0) ? delta : -delta;
|
int32_t count = (delta > 0) ? delta : -delta;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user