From 78e921853ebb7872d12a1110f19bffa40b272fcd Mon Sep 17 00:00:00 2001 From: eshifri <46511024+eshifri@users.noreply.github.com> Date: Thu, 14 Jul 2022 02:02:30 -0700 Subject: [PATCH] fix(lvgl): Text viewer functionality restored (#2070) * view text functionality restored * Cleanup * chore: Automatic code formatting * Fix Windows line break problem * Cleaner version Co-authored-by: Peter Feerick --- radio/src/gui/colorlcd/radio_sdmanager.cpp | 2 +- .../src/gui/colorlcd/themes/etx_lv_theme.cpp | 208 +++++------ radio/src/gui/colorlcd/view_text.cpp | 340 ++++++------------ radio/src/gui/colorlcd/view_text.h | 70 ++-- 4 files changed, 240 insertions(+), 380 deletions(-) diff --git a/radio/src/gui/colorlcd/radio_sdmanager.cpp b/radio/src/gui/colorlcd/radio_sdmanager.cpp index 357f0df40..a6306abd9 100644 --- a/radio/src/gui/colorlcd/radio_sdmanager.cpp +++ b/radio/src/gui/colorlcd/radio_sdmanager.cpp @@ -32,7 +32,7 @@ #include "file_preview.h" #include "file_browser.h" -constexpr int WARN_FILE_LENGTH = 16; +constexpr int WARN_FILE_LENGTH = 40 * 1024; #define CELL_CTRL_DIR LV_TABLE_CELL_CTRL_CUSTOM_1 #define CELL_CTRL_FILE LV_TABLE_CELL_CTRL_CUSTOM_2 diff --git a/radio/src/gui/colorlcd/themes/etx_lv_theme.cpp b/radio/src/gui/colorlcd/themes/etx_lv_theme.cpp index 200cc73e8..6854fb8aa 100644 --- a/radio/src/gui/colorlcd/themes/etx_lv_theme.cpp +++ b/radio/src/gui/colorlcd/themes/etx_lv_theme.cpp @@ -13,6 +13,7 @@ #include "libopenui_config.h" #include "widgets/field_edit.h" #include "widgets/edgetx_table.h" +#include "widgets/window_base.h" #include "lvgl_widgets/input_mix_line.h" #include "lvgl_widgets/input_mix_group.h" @@ -830,29 +831,34 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, &styles.menu_pressed, LV_STATE_PRESSED); } #endif + } + else if (lv_obj_check_type(obj, &window_base_class)) { + lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); + lv_obj_add_style(obj, &styles.scrollbar_scrolled, + LV_PART_SCROLLBAR | LV_STATE_SCROLLED); } - else if(lv_obj_check_type(obj, &input_mix_line_class)) { - lv_obj_add_style(obj, &styles.line_btn, 0); - lv_obj_add_style(obj, &styles.pad_small, 0); - lv_obj_set_style_bg_color(obj, makeLvColor(COLOR_THEME_SECONDARY3), LV_STATE_CHECKED); - lv_obj_add_style(obj, &styles.focus_border, LV_STATE_FOCUSED); + else if (lv_obj_check_type(obj, &input_mix_line_class)) { + lv_obj_add_style(obj, &styles.line_btn, 0); + lv_obj_add_style(obj, &styles.pad_small, 0); + lv_obj_set_style_bg_color(obj, makeLvColor(COLOR_THEME_SECONDARY3), + LV_STATE_CHECKED); + lv_obj_add_style(obj, &styles.focus_border, LV_STATE_FOCUSED); } #endif - else if(lv_obj_check_type(obj, &input_mix_group_class)) { + else if (lv_obj_check_type(obj, &input_mix_group_class)) { lv_obj_add_style(obj, &styles.line_btn, 0); lv_obj_add_style(obj, &styles.pad_small, 0); lv_obj_set_style_text_color(obj, makeLvColor(COLOR_THEME_SECONDARY1), 0); lv_obj_set_style_text_font(obj, getFont(FONT(BOLD)), 0); } - #if LV_USE_LINE - else if(lv_obj_check_type(obj, &lv_line_class)) { + else if (lv_obj_check_type(obj, &lv_line_class)) { lv_obj_add_style(obj, &styles.line, 0); } #endif #if LV_USE_BTNMATRIX - else if(lv_obj_check_type(obj, &lv_btnmatrix_class)) { + else if (lv_obj_check_type(obj, &lv_btnmatrix_class)) { // main lv_obj_add_style(obj, &styles.rounded, 0); // lv_obj_add_style(obj, &styles.focus_border, LV_STATE_FOCUS_KEY); @@ -866,7 +872,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif #if LV_USE_BAR - else if(lv_obj_check_type(obj, &lv_bar_class)) { + else if (lv_obj_check_type(obj, &lv_bar_class)) { lv_obj_add_style(obj, &styles.bg_color_primary_muted, 0); lv_obj_add_style(obj, &styles.circle, 0); lv_obj_add_style(obj, &styles.outline_primary, LV_STATE_FOCUS_KEY); @@ -877,7 +883,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif #if LV_USE_SLIDER - else if(lv_obj_check_type(obj, &lv_slider_class)) { + else if (lv_obj_check_type(obj, &lv_slider_class)) { lv_obj_add_style(obj, &styles.bg_color_primary_muted, 0); lv_obj_add_style(obj, &styles.circle, 0); lv_obj_add_style(obj, &styles.circle, LV_PART_INDICATOR); @@ -886,7 +892,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif #if LV_USE_TABLE - else if(lv_obj_check_type(obj, &lv_table_class) || lv_obj_check_type(obj, &table_class)) { + else if (lv_obj_check_type(obj, &lv_table_class) || lv_obj_check_type(obj, &table_class)) { lv_obj_add_style(obj, &styles.pad_zero, 0); lv_obj_add_style(obj, &styles.no_radius, 0); lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); @@ -900,7 +906,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif #if LV_USE_CHECKBOX - else if(lv_obj_check_type(obj, &lv_checkbox_class)) { + else if (lv_obj_check_type(obj, &lv_checkbox_class)) { lv_obj_add_style(obj, &styles.pad_gap, 0); lv_obj_add_style(obj, &styles.outline_primary, LV_STATE_FOCUS_KEY); lv_obj_add_style(obj, &styles.disabled, LV_PART_INDICATOR | LV_STATE_DISABLED); @@ -917,7 +923,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif #if LV_USE_SWITCH - else if(lv_obj_check_type(obj, &lv_switch_class)) { + else if (lv_obj_check_type(obj, &lv_switch_class)) { lv_obj_add_style(obj, &styles.bg_color_grey, 0); lv_obj_add_style(obj, &styles.circle, 0); lv_obj_add_style(obj, &styles.anim_fast, 0); @@ -935,7 +941,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif #if LV_USE_CHART - else if(lv_obj_check_type(obj, &lv_chart_class)) { + else if (lv_obj_check_type(obj, &lv_chart_class)) { // lv_obj_add_style(obj, &styles.card, 0); lv_obj_add_style(obj, &styles.pad_small, 0); lv_obj_add_style(obj, &styles.chart_bg, 0); @@ -949,7 +955,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif #if LV_USE_ROLLER - else if(lv_obj_check_type(obj, &lv_roller_class)) { + else if (lv_obj_check_type(obj, &lv_roller_class)) { // lv_obj_add_style(obj, &styles.card, 0); lv_obj_add_style(obj, &styles.anim, 0); lv_obj_add_style(obj, &styles.line_space_large, 0); @@ -961,7 +967,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif #if LV_USE_DROPDOWN - else if(lv_obj_check_type(obj, &lv_dropdown_class)) { + else if (lv_obj_check_type(obj, &lv_dropdown_class)) { // lv_obj_add_style(obj, &styles.card, 0); lv_obj_add_style(obj, &styles.pad_small, 0); lv_obj_add_style(obj, &styles.transition_delayed, 0); @@ -970,22 +976,24 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, &styles.outline_primary, LV_STATE_FOCUS_KEY); lv_obj_add_style(obj, &styles.outline_secondary, LV_STATE_EDITED); lv_obj_add_style(obj, &styles.transition_normal, LV_PART_INDICATOR); - } - else if(lv_obj_check_type(obj, &lv_dropdownlist_class)) { - // lv_obj_add_style(obj, &styles.card, 0); - lv_obj_add_style(obj, &styles.clip_corner, 0); - lv_obj_add_style(obj, &styles.line_space_large, 0); - lv_obj_add_style(obj, &styles.dropdown_list, 0); - lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); - lv_obj_add_style(obj, &styles.scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED); - lv_obj_add_style(obj, &styles.bg_color_white, LV_PART_SELECTED); - lv_obj_add_style(obj, &styles.bg_color_primary, LV_PART_SELECTED | LV_STATE_CHECKED); - lv_obj_add_style(obj, &styles.pressed, LV_PART_SELECTED | LV_STATE_PRESSED); + } else if (lv_obj_check_type(obj, &lv_dropdownlist_class)) { + // lv_obj_add_style(obj, &styles.card, 0); + lv_obj_add_style(obj, &styles.clip_corner, 0); + lv_obj_add_style(obj, &styles.line_space_large, 0); + lv_obj_add_style(obj, &styles.dropdown_list, 0); + lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); + lv_obj_add_style(obj, &styles.scrollbar_scrolled, + LV_PART_SCROLLBAR | LV_STATE_SCROLLED); + lv_obj_add_style(obj, &styles.bg_color_white, LV_PART_SELECTED); + lv_obj_add_style(obj, &styles.bg_color_primary, + LV_PART_SELECTED | LV_STATE_CHECKED); + lv_obj_add_style(obj, &styles.pressed, + LV_PART_SELECTED | LV_STATE_PRESSED); } #endif #if LV_USE_ARC - else if(lv_obj_check_type(obj, &lv_arc_class)) { + else if (lv_obj_check_type(obj, &lv_arc_class)) { lv_obj_add_style(obj, &styles.arc_indic, 0); lv_obj_add_style(obj, &styles.arc_indic, LV_PART_INDICATOR); lv_obj_add_style(obj, &styles.arc_indic_primary, LV_PART_INDICATOR); @@ -995,7 +1003,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #if LV_USE_SPINNER - else if(lv_obj_check_type(obj, &lv_spinner_class)) { + else if (lv_obj_check_type(obj, &lv_spinner_class)) { lv_obj_add_style(obj, &styles.arc_indic, 0); lv_obj_add_style(obj, &styles.arc_indic, LV_PART_INDICATOR); lv_obj_add_style(obj, &styles.arc_indic_primary, LV_PART_INDICATOR); @@ -1003,7 +1011,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif #if LV_USE_METER - else if(lv_obj_check_type(obj, &lv_meter_class)) { + else if (lv_obj_check_type(obj, &lv_meter_class)) { // lv_obj_add_style(obj, &styles.card, 0); lv_obj_add_style(obj, &styles.circle, 0); lv_obj_add_style(obj, &styles.meter_indic, LV_PART_INDICATOR); @@ -1011,7 +1019,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif #if LV_USE_TEXTAREA - else if(lv_obj_check_type(obj, &lv_textarea_class)) { + else if (lv_obj_check_type(obj, &lv_textarea_class)) { lv_obj_add_style(obj, &styles.card, 0); lv_obj_add_style(obj, &styles.pad_small, 0); lv_obj_add_style(obj, &styles.outline_primary, LV_STATE_FOCUS_KEY); @@ -1020,38 +1028,38 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, &styles.scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED); lv_obj_add_style(obj, &styles.ta_cursor, LV_PART_CURSOR | LV_STATE_FOCUSED); lv_obj_add_style(obj, &styles.ta_placeholder, LV_PART_TEXTAREA_PLACEHOLDER); - } - else if(lv_obj_check_type(obj, &field_edit_class)) { - lv_obj_add_style(obj, &styles.field, 0); - lv_obj_add_style(obj, &styles.bg_color_focus, LV_STATE_FOCUSED); - lv_obj_add_style(obj, &styles.bg_color_edit, LV_STATE_EDITED); + } else if (lv_obj_check_type(obj, &field_edit_class)) { + lv_obj_add_style(obj, &styles.field, 0); + lv_obj_add_style(obj, &styles.bg_color_focus, LV_STATE_FOCUSED); + lv_obj_add_style(obj, &styles.bg_color_edit, LV_STATE_EDITED); - lv_obj_add_style(obj, &styles.field_cursor, LV_PART_CURSOR); - lv_obj_add_style(obj, &styles.edit_cursor, LV_PART_CURSOR | LV_STATE_EDITED); + lv_obj_add_style(obj, &styles.field_cursor, LV_PART_CURSOR); + lv_obj_add_style(obj, &styles.edit_cursor, + LV_PART_CURSOR | LV_STATE_EDITED); } #endif #if LV_USE_CALENDAR - else if(lv_obj_check_type(obj, &lv_calendar_class)) { + else if (lv_obj_check_type(obj, &lv_calendar_class)) { // lv_obj_add_style(obj, &styles.card, 0); lv_obj_add_style(obj, &styles.pad_zero, 0); } #endif #if LV_USE_CALENDAR_HEADER_ARROW - else if(lv_obj_check_type(obj, &lv_calendar_header_arrow_class)) { + else if (lv_obj_check_type(obj, &lv_calendar_header_arrow_class)) { lv_obj_add_style(obj, &styles.calendar_header, 0); } #endif #if LV_USE_CALENDAR_HEADER_DROPDOWN - else if(lv_obj_check_type(obj, &lv_calendar_header_dropdown_class)) { + else if (lv_obj_check_type(obj, &lv_calendar_header_dropdown_class)) { lv_obj_add_style(obj, &styles.calendar_header, 0); } #endif #if LV_USE_KEYBOARD - else if(lv_obj_check_type(obj, &lv_keyboard_class)) { + else if (lv_obj_check_type(obj, &lv_keyboard_class)) { lv_obj_add_style(obj, &styles.scr, 0); lv_obj_add_style(obj, disp_size == DISP_LARGE ? &styles.pad_small : &styles.pad_tiny, 0); // lv_obj_add_style(obj, &styles.outline_primary, LV_STATE_FOCUS_KEY); @@ -1067,77 +1075,71 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) } #endif #if LV_USE_LIST - else if(lv_obj_check_type(obj, &lv_list_class)) { + else if (lv_obj_check_type(obj, &lv_list_class)) { // lv_obj_add_style(obj, &styles.card, 0); lv_obj_add_style(obj, &styles.list_bg, 0); lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); lv_obj_add_style(obj, &styles.scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED); return; - } - else if(lv_obj_check_type(obj, &lv_list_text_class)) { - lv_obj_add_style(obj, &styles.bg_color_grey, 0); - lv_obj_add_style(obj, &styles.list_item_grow, 0); - } - else if(lv_obj_check_type(obj, &lv_list_btn_class)) { - lv_obj_add_style(obj, &styles.bg_color_white, 0); - lv_obj_add_style(obj, &styles.list_btn, 0); - lv_obj_add_style(obj, &styles.bg_color_primary, LV_STATE_FOCUS_KEY); - lv_obj_add_style(obj, &styles.list_item_grow, LV_STATE_FOCUS_KEY); - lv_obj_add_style(obj, &styles.list_item_grow, LV_STATE_PRESSED); - lv_obj_add_style(obj, &styles.pressed, LV_STATE_PRESSED); + } else if (lv_obj_check_type(obj, &lv_list_text_class)) { + lv_obj_add_style(obj, &styles.bg_color_grey, 0); + lv_obj_add_style(obj, &styles.list_item_grow, 0); + } else if (lv_obj_check_type(obj, &lv_list_btn_class)) { + lv_obj_add_style(obj, &styles.bg_color_white, 0); + lv_obj_add_style(obj, &styles.list_btn, 0); + lv_obj_add_style(obj, &styles.bg_color_primary, LV_STATE_FOCUS_KEY); + lv_obj_add_style(obj, &styles.list_item_grow, LV_STATE_FOCUS_KEY); + lv_obj_add_style(obj, &styles.list_item_grow, LV_STATE_PRESSED); + lv_obj_add_style(obj, &styles.pressed, LV_STATE_PRESSED); } #endif #if LV_USE_MENU - else if(lv_obj_check_type(obj, &lv_menu_class)) { + else if (lv_obj_check_type(obj, &lv_menu_class)) { // lv_obj_add_style(obj, &styles.card, 0); lv_obj_add_style(obj, &styles.menu_bg, 0); - } - else if(lv_obj_check_type(obj, &lv_menu_sidebar_cont_class)) { - lv_obj_add_style(obj, &styles.menu_sidebar_cont, 0); - lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); - lv_obj_add_style(obj, &styles.scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED); - } - else if(lv_obj_check_type(obj, &lv_menu_main_cont_class)) { - lv_obj_add_style(obj, &styles.menu_main_cont, 0); - lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); - lv_obj_add_style(obj, &styles.scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED); - } - else if(lv_obj_check_type(obj, &lv_menu_cont_class)) { - lv_obj_add_style(obj, &styles.menu_cont, 0); - lv_obj_add_style(obj, &styles.menu_pressed, LV_STATE_PRESSED); - lv_obj_add_style(obj, &styles.bg_color_primary_muted, LV_STATE_PRESSED | LV_STATE_CHECKED); - lv_obj_add_style(obj, &styles.bg_color_primary_muted, LV_STATE_CHECKED); - } - else if(lv_obj_check_type(obj, &lv_menu_sidebar_header_cont_class) || - lv_obj_check_type(obj, &lv_menu_main_header_cont_class)) { - lv_obj_add_style(obj, &styles.menu_header_cont, 0); - lv_obj_add_style(obj, &styles.menu_pressed, LV_STATE_PRESSED); - } - else if(lv_obj_check_type(obj, &lv_menu_page_class)) { - lv_obj_add_style(obj, &styles.menu_page, 0); - lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); - lv_obj_add_style(obj, &styles.scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED); - } - else if(lv_obj_check_type(obj, &lv_menu_section_class)) { - lv_obj_add_style(obj, &styles.menu_section, 0); - } - else if(lv_obj_check_type(obj, &lv_menu_separator_class)) { - lv_obj_add_style(obj, &styles.menu_separator, 0); + } else if (lv_obj_check_type(obj, &lv_menu_sidebar_cont_class)) { + lv_obj_add_style(obj, &styles.menu_sidebar_cont, 0); + lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); + lv_obj_add_style(obj, &styles.scrollbar_scrolled, + LV_PART_SCROLLBAR | LV_STATE_SCROLLED); + } else if (lv_obj_check_type(obj, &lv_menu_main_cont_class)) { + lv_obj_add_style(obj, &styles.menu_main_cont, 0); + lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); + lv_obj_add_style(obj, &styles.scrollbar_scrolled, + LV_PART_SCROLLBAR | LV_STATE_SCROLLED); + } else if (lv_obj_check_type(obj, &lv_menu_cont_class)) { + lv_obj_add_style(obj, &styles.menu_cont, 0); + lv_obj_add_style(obj, &styles.menu_pressed, LV_STATE_PRESSED); + lv_obj_add_style(obj, &styles.bg_color_primary_muted, + LV_STATE_PRESSED | LV_STATE_CHECKED); + lv_obj_add_style(obj, &styles.bg_color_primary_muted, LV_STATE_CHECKED); + } else if (lv_obj_check_type(obj, &lv_menu_sidebar_header_cont_class) || + lv_obj_check_type(obj, &lv_menu_main_header_cont_class)) { + lv_obj_add_style(obj, &styles.menu_header_cont, 0); + lv_obj_add_style(obj, &styles.menu_pressed, LV_STATE_PRESSED); + } else if (lv_obj_check_type(obj, &lv_menu_page_class)) { + lv_obj_add_style(obj, &styles.menu_page, 0); + lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); + lv_obj_add_style(obj, &styles.scrollbar_scrolled, + LV_PART_SCROLLBAR | LV_STATE_SCROLLED); + } else if (lv_obj_check_type(obj, &lv_menu_section_class)) { + lv_obj_add_style(obj, &styles.menu_section, 0); + } else if (lv_obj_check_type(obj, &lv_menu_separator_class)) { + lv_obj_add_style(obj, &styles.menu_separator, 0); } #endif #if LV_USE_MSGBOX - else if(lv_obj_check_type(obj, &lv_msgbox_class)) { + else if (lv_obj_check_type(obj, &lv_msgbox_class)) { // lv_obj_add_style(obj, &styles.card, 0); lv_obj_add_style(obj, &styles.msgbox_bg, 0); return; - } - else if(lv_obj_check_type(obj, &lv_msgbox_backdrop_class)) { - lv_obj_add_style(obj, &styles.msgbox_backdrop_bg, 0); + } else if (lv_obj_check_type(obj, &lv_msgbox_backdrop_class)) { + lv_obj_add_style(obj, &styles.msgbox_backdrop_bg, 0); } #endif #if LV_USE_SPINBOX - else if(lv_obj_check_type(obj, &lv_spinbox_class)) { + else if (lv_obj_check_type(obj, &lv_spinbox_class)) { // lv_obj_add_style(obj, &styles.card, 0); lv_obj_add_style(obj, &styles.pad_small, 0); // lv_obj_add_style(obj, &styles.outline_primary, LV_STATE_FOCUS_KEY); @@ -1146,32 +1148,32 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) } #endif #if LV_USE_TILEVIEW - else if(lv_obj_check_type(obj, &lv_tileview_class)) { + else if (lv_obj_check_type(obj, &lv_tileview_class)) { lv_obj_add_style(obj, &styles.scr, 0); lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); lv_obj_add_style(obj, &styles.scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED); - } - else if(lv_obj_check_type(obj, &lv_tileview_tile_class)) { - lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); - lv_obj_add_style(obj, &styles.scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED); + } else if (lv_obj_check_type(obj, &lv_tileview_tile_class)) { + lv_obj_add_style(obj, &styles.scrollbar, LV_PART_SCROLLBAR); + lv_obj_add_style(obj, &styles.scrollbar_scrolled, + LV_PART_SCROLLBAR | LV_STATE_SCROLLED); } #endif #if LV_USE_TABVIEW - else if(lv_obj_check_type(obj, &lv_tabview_class)) { + else if (lv_obj_check_type(obj, &lv_tabview_class)) { lv_obj_add_style(obj, &styles.scr, 0); lv_obj_add_style(obj, &styles.pad_zero, 0); } #endif #if LV_USE_WIN - else if(lv_obj_check_type(obj, &lv_win_class)) { + else if (lv_obj_check_type(obj, &lv_win_class)) { lv_obj_add_style(obj, &styles.clip_corner, 0); } #endif #if LV_USE_COLORWHEEL - else if(lv_obj_check_type(obj, &lv_colorwheel_class)) { + else if (lv_obj_check_type(obj, &lv_colorwheel_class)) { lv_obj_add_style(obj, &styles.colorwheel_main, 0); lv_obj_add_style(obj, &styles.pad_normal, 0); lv_obj_add_style(obj, &styles.bg_color_white, LV_PART_KNOB); @@ -1180,7 +1182,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif #if LV_USE_LED - else if(lv_obj_check_type(obj, &lv_led_class)) { + else if (lv_obj_check_type(obj, &lv_led_class)) { lv_obj_add_style(obj, &styles.led, 0); } #endif diff --git a/radio/src/gui/colorlcd/view_text.cpp b/radio/src/gui/colorlcd/view_text.cpp index 8f5780d77..799509ea8 100644 --- a/radio/src/gui/colorlcd/view_text.cpp +++ b/radio/src/gui/colorlcd/view_text.cpp @@ -25,28 +25,13 @@ #include "opentx.h" #include "sdcard.h" -#define CASE_EVT_KEY_NEXT_LINE \ - case EVT_ROTARY_RIGHT: \ - case EVT_KEY_BREAK(KEY_PGDN) -// case EVT_KEY_BREAK(KEY_DOWN) - -#define CASE_EVT_KEY_PREVIOUS_LINE \ - case EVT_ROTARY_LEFT: \ - case EVT_KEY_BREAK(KEY_PGUP): \ - case EVT_KEY_BREAK(KEY_UP) - -#define CASE_EVT_START \ - case EVT_ENTRY: \ - case EVT_KEY_BREAK(KEY_ENTER): \ - case EVT_KEY_BREAK(KEY_TELEM) - void ViewTextWindow::extractNameSansExt() { uint8_t nameLength; uint8_t extLength; const char *ext = - getFileExtension(name.data(), 0, 0, &nameLength, &extLength); + getFileExtension(name.c_str(), 0, 0, &nameLength, &extLength); extension = std::string(ext); if (nameLength > TEXT_FILENAME_MAXLEN) nameLength = TEXT_FILENAME_MAXLEN; @@ -57,236 +42,139 @@ void ViewTextWindow::extractNameSansExt() void ViewTextWindow::buildBody(Window *window) { - GridLayout grid(window); - grid.spacer(); - int i; - FIL file; + FILINFO info; - // assume average characte is 10 pixels wide, round the string length to tens. - // Font is not fixed width, so this is for the worst case... - maxLineLength = static_cast(window->width() / 10 / 10) * 10 - 2; - maxScreenLines = window->height() / (PAGE_LINE_HEIGHT + PAGE_LINE_SPACING); - // window->setFocus(); - readLinesCount = 0; - lastLoadedLine = 0; - - lines = new char *[maxScreenLines]; - for (i = 0; i < maxScreenLines; i++) { - lines[i] = new char[maxLineLength + 1]; - memclear(lines[i], maxLineLength + 1); + if (buffer) { + free(buffer); + buffer = nullptr; + bufSize = 0; } - if (isInSetup) { - if (FR_OK == - f_open(&file, (TCHAR *)fullPath.c_str(), FA_OPEN_EXISTING | FA_READ)) { - const int fileLenght = file.obj.objsize; - maxLines = 20 * fileLenght / maxLineLength; - f_close(&file); + auto res = f_stat((TCHAR *)fullPath.c_str(), &info); + if (res == FR_OK) { + fileLength = int(info.fsize); + bufSize = std::min(fileLength, maxTxtBuffSize) + 1; - textBottom = false; - longestLine = 0; - loadOneScreen(maxLines); + buffer = (char *)malloc(bufSize); + if (buffer) { + offset = + std::max(int(openFromEnd ? int(info.fsize) - bufSize + 1 : 0), 0); + TRACE("info.fsize=%d\tbufSize=%d\toffset=%d", info.fsize, bufSize, + int(info.fsize) - bufSize + 1); + if (sdReadTextFileBlock(fullPath.c_str(), bufSize, offset) == FR_OK) { + auto obj = window->getLvObj(); + lv_obj_add_flag( + obj, LV_OBJ_FLAG_SCROLLABLE | LV_OBJ_FLAG_SCROLL_WITH_ARROW | + LV_OBJ_FLAG_SCROLL_MOMENTUM | LV_OBJ_FLAG_CLICK_FOCUSABLE); + lv_obj_set_scrollbar_mode(obj, LV_SCROLLBAR_MODE_AUTO); + // prevents resetting the group's edit mode + lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICK_FOCUSABLE); - maxPos = - (maxLines - maxScreenLines) * (PAGE_LINE_HEIGHT + PAGE_LINE_SPACING); - if (maxPos < body.getRect().h) maxPos = body.getRect().h; - } - } + auto g = lv_group_get_default(); + lb = lv_label_create(obj); + lv_obj_set_size(lb, lv_pct(100), LV_SIZE_CONTENT); + lv_obj_set_style_pad_all(lb, lv_dpx(8), 0); - isInSetup = false; - textVerticalOffset = 0; - loadOneScreen(openFromEnd ? (maxLines - maxScreenLines) : 0); + lv_group_add_obj(g, obj); + lv_group_set_editing(g, true); + lv_label_set_text_static(lb, buffer); - for (i = 0; i < maxScreenLines; i++) { - new DynamicText(window, grid.getSlot(), [=]() { - std::string str = - (lines[i][0]) ? std::string(lines[i]) : std::string(" "); - return std::string(str); - }); - grid.nextLine(); - } -} - -#if defined(HARDWARE_TOUCH) -bool ViewTextWindow::onTouchSlide(coord_t x, coord_t y, coord_t startX, - coord_t startY, coord_t slideX, - coord_t slideY) -{ - // if (&body == Window::focusWindow) { - // const int step = PAGE_LINE_HEIGHT + PAGE_LINE_SPACING; - // int deltaY = -slideY; - // int lineStep = deltaY / step; - - // textVerticalOffset += lineStep; - // if (textVerticalOffset < 0) textVerticalOffset = 0; - - // if (textVerticalOffset > maxLines - maxScreenLines) - // textVerticalOffset = maxLines - maxScreenLines; - // sdReadTextFileBlock(fullPath.c_str(), readLinesCount); - // } - // return Page::onTouchSlide(x, y, startX, startY, slideX, slideY); - return true; -} -#endif - -void ViewTextWindow::checkEvents() -{ -// if (&body == Window::focusWindow) { -// const int step = PAGE_LINE_HEIGHT + PAGE_LINE_SPACING; -// coord_t deltaY; -// event_t event = getWindowEvent(); - -// #if defined(ROTARY_ENCODER_NAVIGATION) -// if (event == EVT_ROTARY_LEFT || event == EVT_ROTARY_RIGHT) { -// deltaY = ROTARY_ENCODER_SPEED() * step; -// } else { -// deltaY = step; -// } -// #else -// deltaY = step; -// #endif - -// int lineStep = deltaY / step; -// if (lineStep > (maxScreenLines >> 1)) lineStep = maxScreenLines >> 1; - -// switch (event) { -// CASE_EVT_START: -// textVerticalOffset = 0; -// readLinesCount = 0; -// sdReadTextFileBlock(fullPath.c_str(), readLinesCount); -// break; - -// CASE_EVT_KEY_NEXT_LINE: -// if (textBottom && textVerticalOffset) -// break; -// else { -// textVerticalOffset += lineStep; -// if (textVerticalOffset > maxLines) textVerticalOffset = maxLines; -// } -// sdReadTextFileBlock(fullPath.c_str(), readLinesCount); -// break; - -// CASE_EVT_KEY_PREVIOUS_LINE: -// if (textVerticalOffset == 0) -// break; -// else { -// textVerticalOffset -= lineStep; -// if (textVerticalOffset < 0) textVerticalOffset = 0; -// } - -// sdReadTextFileBlock(fullPath.c_str(), readLinesCount); -// break; - -// default: -// Page::onEvent(event); -// break; -// } -// } -// Page::checkEvents(); -} - -void ViewTextWindow::loadOneScreen(int offset) -{ - textVerticalOffset = offset; - readLinesCount = 0; - sdReadTextFileBlock(fullPath.c_str(), readLinesCount); -} - -void ViewTextWindow::sdReadTextFileBlock(const char *filename, int &lines_count) -{ - FIL file; - int result; - char c; - unsigned int sz = 0; - int line_length = 1; - uint8_t escape = 0; - char escape_chars[4] = {0}; - int current_line = 0; - textBottom = false; - - for (int i = 0; i < maxScreenLines; i++) { - memclear(lines[i], maxLineLength + 1); - lines[i][0] = ' '; - } - - result = f_open(&file, (TCHAR *)filename, FA_OPEN_EXISTING | FA_READ); - if (result == FR_OK) { - while (f_read(&file, &c, 1, &sz) == FR_OK && sz == 1 && - (lines_count == 0 || - current_line - textVerticalOffset < maxScreenLines)) - { - if (c == '\n' || line_length >= maxLineLength) { - ++current_line; - line_length = 1; - escape = 0; + if (openFromEnd) + lv_obj_scroll_to_y(obj, LV_COORD_MAX, LV_ANIM_OFF); + else + lv_obj_scroll_to_y(obj, 0, LV_ANIM_OFF); } - if (c != '\r' && c != '\n' && current_line >= textVerticalOffset && - current_line - textVerticalOffset < maxScreenLines && - line_length < maxLineLength) { - if (c == '\\' && escape == 0) { - escape = 1; - continue; - } else if (c != '\\' && escape > 0 && escape < sizeof(escape_chars)) { - escape_chars[escape - 1] = c; - if (escape == 2 && !strncmp(escape_chars, "up", 2)) { - lines[current_line - textVerticalOffset][line_length++] = STR_CHAR_UP[0]; - c = STR_CHAR_UP[1]; - } else if (escape == 2 && !strncmp(escape_chars, "dn", 2)) { - lines[current_line - textVerticalOffset][line_length++] = STR_CHAR_DOWN[0]; - c = STR_CHAR_DOWN[1]; - } else if (escape == 3) { - int val = atoi(escape_chars); - if (val >= 200 && val < 225) { - lines[current_line - textVerticalOffset][line_length++] = '\302'; - c = '\200' + val - 200; + } + } +} + +FRESULT ViewTextWindow::sdReadTextFileBlock(const char *filename, + const uint32_t bufSize, + const uint32_t offset) +{ + FIL file; + char escape_chars[4]; + int escape = 0; + + auto res = f_open(&file, (TCHAR *)filename, FA_OPEN_EXISTING | FA_READ); + if (res == FR_OK) { + res = f_lseek(&file, offset); + if (res == FR_OK) { + UINT br; + char c; + char *ptr = buffer; + for (int i = 0; i < (int)bufSize; i++) { + res = f_read(&file, &c, 1, &br); + if (res == FR_OK && br == 1) { + if (c == '\\' && escape == 0) { + escape = 1; + continue; + } else if (c != '\\' && escape > 0 && + escape < (int)sizeof(escape_chars)) { + escape_chars[escape - 1] = c; + + if (escape == 2 && !strncmp(escape_chars, "up", 2)) { + *ptr++ = STR_CHAR_UP[0]; + c = STR_CHAR_UP[1]; + escape = 0; + } else if (escape == 2 && !strncmp(escape_chars, "dn", 2)) { + *ptr++ = STR_CHAR_DOWN[0]; + c = STR_CHAR_DOWN[1]; + escape = 0; + } else if (escape == 3) { + int val = atoi(escape_chars); + if (val >= 200 && val < 225) { + *ptr++ = '\302'; + c = '\200' + val - 200; + } + } else if (escape == 1 && c == '~') { + c = 'z' + 1; + } else { + escape++; + continue; } - } else { - escape++; + } else if (c == '\t') { + c = 0x1D; // tab + } + escape = 0; + + if (c == 0xA && *(ptr - 1) == 0xD) { + *(ptr - 1) = '\n'; continue; } - } else if (c == '~') { - c = 'z' + 1; - } else if (c == '\t') { - c = 0x1D; // tab + *ptr++ = c; } - escape = 0; - - lines[current_line - textVerticalOffset][line_length++] = c; - if (longestLine < line_length) longestLine = line_length; - } else if (current_line < textVerticalOffset) { - ++line_length; } + *ptr = '\0'; } - if (c != '\n') { - ++current_line; - } - - if (f_eof(&file)) { - textBottom = true; - if (isInSetup) maxLines = current_line; - } - f_close(&file); } - - if (lastLoadedLine < textVerticalOffset) lastLoadedLine = textVerticalOffset; - - if (lines_count == 0) { - lines_count = current_line; - } + return res; } -void ViewTextWindow::drawVerticalScrollbar(BitmapBuffer *dc) +void ViewTextWindow::onEvent(event_t event) { - int readPos = textVerticalOffset * (PAGE_LINE_HEIGHT + PAGE_LINE_SPACING); +#if defined(HARDWARE_KEYS) + if (int(bufSize) < fileLength) { + TRACE("BEFORE offset=%d", offset); + if (event == EVT_KEY_BREAK(KEY_PGDN)) { + offset += bufSize; + TRACE("event=DOWN"); + } - coord_t yofs = divRoundClosest(body.getRect().h * readPos, maxPos) - + header.getRect().h + (int)PAGE_LINE_SPACING; - coord_t yhgt = divRoundClosest(body.getRect().h * body.getRect().h, maxPos); - if (yhgt < 15) yhgt = 15; - if (yhgt + yofs > maxPos) yhgt = maxPos - yofs; - dc->drawSolidFilledRect(body.getRect().w - SCROLLBAR_WIDTH, yofs, - SCROLLBAR_WIDTH, yhgt, COLOR_THEME_PRIMARY3); + if (event == EVT_KEY_BREAK(KEY_PGUP)) { + TRACE("event=UP"); + offset -= bufSize; + } + + offset = std::max(offset, 0); + offset = std::min(offset, fileLength - (int)bufSize); + + TRACE("AFTER offset=%d", offset); + sdReadTextFileBlock(fullPath.c_str(), bufSize, offset); + lv_label_set_text_static(lb, buffer); + } +#endif } #include "datastructs.h" diff --git a/radio/src/gui/colorlcd/view_text.h b/radio/src/gui/colorlcd/view_text.h index 640d5324a..99541c300 100644 --- a/radio/src/gui/colorlcd/view_text.h +++ b/radio/src/gui/colorlcd/view_text.h @@ -26,52 +26,35 @@ #include "page.h" #include "static.h" +#include "LvglWrapper.h" + +constexpr int maxTxtBuffSize = 64 * 1024; + class ViewTextWindow : public Page { public: - ViewTextWindow(const std::string iPath, const std::string iName, + ViewTextWindow(const std::string path, const std::string name, unsigned int icon = ICON_RADIO_SD_MANAGER) : - Page(icon), path(std::move(iPath)), name(std::move(iName)), icon(icon) + Page(icon), path(std::move(path)), name(std::move(name)) { - fullPath = path + std::string("/") + name; + fullPath = this->path + std::string("/") + this->name; extractNameSansExt(); - lines = nullptr; - lastLoadedLine = 0; - maxPos = 0; - maxLines = 0; - isInSetup = true; - header.setWindowFlags(NO_SCROLLBAR); - buildHeader(&header); + header.setTitle(this->name); buildBody(&body); }; - void sdReadTextFileBlock(const char* filename, int& lines_count); - void loadOneScreen(int offset); -#if defined(HARDWARE_TOUCH) - bool onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, - coord_t slideX, coord_t slideY) override; -#endif - void drawVerticalScrollbar(BitmapBuffer* dc); + FRESULT sdReadTextFileBlock(const char* filename, const uint32_t bufSize, + const uint32_t offset); ~ViewTextWindow() { - if (lines != nullptr) { - for (int i = 0; i < maxScreenLines; i++) { - delete[] lines[i]; - } - delete[] lines; + if (buffer) { + free(buffer); + buffer = nullptr; } } - void paint(BitmapBuffer* dc) override - { - Page::paint(dc); - drawVerticalScrollbar(dc); - } - - void checkEvents() override; - #if defined(DEBUG_WINDOWS) std::string getName() const override { return "ViewTextWindow"; }; #endif @@ -81,32 +64,19 @@ class ViewTextWindow : public Page std::string name; std::string fullPath; std::string extension; - unsigned int icon; - uint16_t readCount; - int longestLine; + lv_obj_t* lb; - char** lines = nullptr; - int maxScreenLines; - int maxLineLength; - int textVerticalOffset; - int readLinesCount; - int lastLoadedLine; - int maxPos; - int maxLines; - bool textBottom; - bool isInSetup; + int offset = 0; + char* buffer = nullptr; + size_t bufSize = 0; + int fileLength = 0; bool openFromEnd; void extractNameSansExt(void); void buildBody(Window* window); - void buildHeader(Window* window) - { - new StaticText(window, - {PAGE_TITLE_LEFT, PAGE_TITLE_TOP + 10, - LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}, - name, 0, COLOR_THEME_PRIMARY2); - }; + + void onEvent(event_t event) override; }; void readModelNotes();