From 3dd0a72ed8fd9a31f476a32b1182a1dcf57593e7 Mon Sep 17 00:00:00 2001 From: "kkoenig1@optonline.com" Date: Mon, 7 Feb 2022 13:20:37 -0500 Subject: [PATCH] implementation of choice and filechoice using lvgl --- radio/src/thirdparty/libopenui/src/choice.cpp | 72 +++++++++++++++---- radio/src/thirdparty/libopenui/src/choice.h | 4 ++ .../thirdparty/libopenui/src/filechoice.cpp | 10 ++- .../src/thirdparty/libopenui/src/filechoice.h | 1 + radio/src/thirdparty/libopenui/src/menu.cpp | 2 +- 5 files changed, 74 insertions(+), 15 deletions(-) diff --git a/radio/src/thirdparty/libopenui/src/choice.cpp b/radio/src/thirdparty/libopenui/src/choice.cpp index ffc1e2871..0c1ab0826 100644 --- a/radio/src/thirdparty/libopenui/src/choice.cpp +++ b/radio/src/thirdparty/libopenui/src/choice.cpp @@ -21,14 +21,62 @@ #include "menu.h" #include "theme.h" +void choicePaintCallback(lv_event_t *e) +{ + auto code = lv_event_get_code(e); + + if (code == LV_EVENT_DRAW_MAIN_BEGIN) { + lv_obj_t *target = lv_event_get_target(e); + if (target != nullptr) { + ChoiceBase *cb = (ChoiceBase*)lv_obj_get_user_data(target); + std::string text = cb->getLabelText(); + lv_label_set_text(cb->label, text.c_str()); + } + } +} + ChoiceBase::ChoiceBase(FormGroup * parent, const rect_t & rect, ChoiceType type, WindowFlags windowFlags): FormField(parent, rect, windowFlags), type(type) { + lv_obj_add_event_cb(lvobj, choicePaintCallback, LV_EVENT_DRAW_MAIN_BEGIN, lvobj); + label = lv_label_create(lvobj); + // Normal font and background color + lv_obj_set_style_bg_color(lvobj, makeLvColor(COLOR_THEME_PRIMARY2), LV_PART_MAIN); + lv_obj_set_style_bg_opa(lvobj, LV_OPA_100, LV_PART_MAIN); + lv_obj_set_style_pad_right(lvobj, 5, LV_PART_MAIN); + lv_obj_set_style_border_width(lvobj, 1, LV_PART_MAIN); + lv_obj_set_style_border_color(lvobj, makeLvColor(COLOR_THEME_SECONDARY2), LV_PART_MAIN); + lv_obj_set_style_text_color(lvobj, makeLvColor(COLOR_THEME_SECONDARY1), LV_PART_MAIN); + lv_obj_set_style_text_font(lvobj, &lv_font_roboto_13, LV_PART_MAIN); + // focused + lv_obj_set_style_bg_color(lvobj, makeLvColor(COLOR_THEME_FOCUS), LV_PART_MAIN | LV_STATE_FOCUSED); + lv_obj_set_style_text_color(lvobj, makeLvColor(COLOR_THEME_PRIMARY2), LV_PART_MAIN | LV_STATE_FOCUSED); + + lv_obj_set_width(label, lv_pct(80)); + lv_obj_set_style_pad_left(label, FIELD_PADDING_LEFT, LV_PART_MAIN); + lv_obj_set_style_pad_top(label, FIELD_PADDING_TOP, LV_PART_MAIN); + + + // add the image + lv_obj_t *img = lv_img_create(lvobj); + lv_img_set_src(img, type == CHOICE_TYPE_DROPOWN ? LV_SYMBOL_DOWN : LV_SYMBOL_DIRECTORY); + lv_obj_set_align(img, LV_ALIGN_RIGHT_MID); } +std::string Choice::getLabelText() +{ + std::string text = ""; + if (textHandler != nullptr) + text = textHandler(getValue()); + else if (getValue() < values.size()) + text = values[getValue()]; + + return text; +} + Choice::Choice(FormGroup * parent, const rect_t & rect, int vmin, int vmax, std::function getValue, std::function setValue, WindowFlags windowFlags) : ChoiceBase(parent, rect, CHOICE_TYPE_DROPOWN, windowFlags), @@ -111,20 +159,20 @@ void Choice::setValues(const char * const values[]) void Choice::paint(BitmapBuffer * dc) { - FormField::paint(dc); - auto val = getValue(); + // FormField::paint(dc); + // auto val = getValue(); - std::string str = ""; - if (textHandler) { - str = textHandler(val); - } else { - val -= vmin; - if (val >= 0 && val < (int)values.size()) { - str = values[val]; - } - } + // std::string str = ""; + // if (textHandler) { + // str = textHandler(val); + // } else { + // val -= vmin; + // if (val >= 0 && val < (int)values.size()) { + // str = values[val]; + // } + // } - theme->drawChoice(dc, this, str.c_str()); + // theme->drawChoice(dc, this, str.c_str()); } #if defined(HARDWARE_KEYS) diff --git a/radio/src/thirdparty/libopenui/src/choice.h b/radio/src/thirdparty/libopenui/src/choice.h index d6bfc2af3..1406747b4 100644 --- a/radio/src/thirdparty/libopenui/src/choice.h +++ b/radio/src/thirdparty/libopenui/src/choice.h @@ -40,7 +40,10 @@ class ChoiceBase : public FormField } protected: + friend void choicePaintCallback(lv_event_t *e); ChoiceType type; + lv_obj_t *label; + virtual std::string getLabelText() { return ""; }; }; class Choice: public ChoiceBase { @@ -150,6 +153,7 @@ class Choice: public ChoiceBase { } protected: + std::string getLabelText() override; std::vector values; int vmin = 0; int vmax = 0; diff --git a/radio/src/thirdparty/libopenui/src/filechoice.cpp b/radio/src/thirdparty/libopenui/src/filechoice.cpp index 0e289b9be..36443b80a 100644 --- a/radio/src/thirdparty/libopenui/src/filechoice.cpp +++ b/radio/src/thirdparty/libopenui/src/filechoice.cpp @@ -48,10 +48,16 @@ FileChoice::FileChoice(FormGroup *parent, const rect_t &rect, { } +std::string FileChoice::getLabelText() +{ + return getValue(); +} + + void FileChoice::paint(BitmapBuffer * dc) { - FormField::paint(dc); - theme->drawChoice(dc, this, getValue().c_str()); + // FormField::paint(dc); + // theme->drawChoice(dc, this, getValue().c_str()); } bool FileChoice::openMenu() diff --git a/radio/src/thirdparty/libopenui/src/filechoice.h b/radio/src/thirdparty/libopenui/src/filechoice.h index 5e5f57c51..dd7befa59 100644 --- a/radio/src/thirdparty/libopenui/src/filechoice.h +++ b/radio/src/thirdparty/libopenui/src/filechoice.h @@ -46,6 +46,7 @@ public: #endif protected: + std::string getLabelText() override; std::string folder; const char* extension; int maxlen; diff --git a/radio/src/thirdparty/libopenui/src/menu.cpp b/radio/src/thirdparty/libopenui/src/menu.cpp index 3ec5a384d..420ea53ea 100644 --- a/radio/src/thirdparty/libopenui/src/menu.cpp +++ b/radio/src/thirdparty/libopenui/src/menu.cpp @@ -102,7 +102,7 @@ void MenuBody::setIndex(int index) btn = lv_obj_get_child(lvobj, selectedIndex); if (btn != nullptr) { lv_obj_add_state(btn, LV_STATE_CHECKED); - lv_obj_scroll_to_view(btn, LV_ANIM_ON); + lv_obj_scroll_to_view(btn, LV_ANIM_OFF); } } }