From 71dd6bca89cca5fe67aa3414f71a82a4e72aa0ee Mon Sep 17 00:00:00 2001 From: Kevin Koenig Date: Sat, 4 Dec 2021 20:09:08 -0500 Subject: [PATCH] More optimisations to Theme Editor (#1210) * fix some minor issues * 1. fixed issue with FullScreenDialog when over a window that processes onTouchStart 2. Fixed Huse and RFB bar positioning 3. added the ability to pause the filecarosell 4. now when the Theme Browser isnt the top of the stack it pauses the FileCarosell. Good for perf 5. Add more preview controls so all colors can be seen 6. Lots of little layout issues fixed * layout changes for nv14 * fix listbox. dont call selection handler if the newly selected item is the same as the selected one. Co-authored-by: kkoenig1@optonline.com --- radio/src/gui/colorlcd/color_editor.cpp | 5 +- radio/src/gui/colorlcd/file_carosell.cpp | 7 ++ radio/src/gui/colorlcd/file_carosell.h | 5 + radio/src/gui/colorlcd/fullscreen_dialog.cpp | 6 ++ radio/src/gui/colorlcd/fullscreen_dialog.h | 1 + radio/src/gui/colorlcd/listbox.cpp | 2 +- radio/src/gui/colorlcd/preview_window.h | 73 +++++++++++---- radio/src/gui/colorlcd/radio_theme.cpp | 98 +++++++++++++++----- radio/src/gui/colorlcd/radio_theme.h | 3 + 9 files changed, 160 insertions(+), 40 deletions(-) diff --git a/radio/src/gui/colorlcd/color_editor.cpp b/radio/src/gui/colorlcd/color_editor.cpp index 70fa56ea3..22f8dc51b 100644 --- a/radio/src/gui/colorlcd/color_editor.cpp +++ b/radio/src/gui/colorlcd/color_editor.cpp @@ -48,10 +48,11 @@ HSVColorType::HSVColorType(FormGroup *window, uint32_t color) : values[2] *= MAX_BRIGHTNESS; auto spacePerBar = (window->width() / MAX_BARS); + int leftPos = 0; for (auto i = 0; i < MAX_BARS; i++) { - barInfo[i].leftPos = leftPos + (i != 0 ? BAR_MARGIN : 0); + barInfo[i].leftPos = leftPos + BAR_MARGIN; barInfo[i].barWidth = spacePerBar - BAR_MARGIN - 5; barInfo[i].maxValue = i == 0 ? MAX_HUE : MAX_BRIGHTNESS; barInfo[i].invert = i != 0; @@ -121,7 +122,7 @@ RGBColorType::RGBColorType(FormGroup *window, uint32_t color) : auto spacePerBar = (window->width() / MAX_BARS); int leftPos = 0; for (auto i = 0; i < MAX_BARS; i++) { - barInfo[i].leftPos = leftPos + (i != 0 ? BAR_MARGIN : 0); + barInfo[i].leftPos = leftPos + BAR_MARGIN; barInfo[i].barWidth = spacePerBar - BAR_MARGIN - 5; barInfo[i].maxValue = 255; barInfo[i].sliding = false; diff --git a/radio/src/gui/colorlcd/file_carosell.cpp b/radio/src/gui/colorlcd/file_carosell.cpp index cdabc5993..9e35a4b8f 100644 --- a/radio/src/gui/colorlcd/file_carosell.cpp +++ b/radio/src/gui/colorlcd/file_carosell.cpp @@ -73,6 +73,13 @@ void FileCarosell::checkEvents() { FormGroup::checkEvents(); + // if we are paused then just update time. we will begin the carosell after + // timeout period once unpaused + if (_paused) { + timer = getTicks(); + return; + } + uint32_t newTicks = getTicks(); if (newTicks - timer > pageInterval && _fileNames.size()) { int newSelected = (selected + 1) % _fileNames.size(); diff --git a/radio/src/gui/colorlcd/file_carosell.h b/radio/src/gui/colorlcd/file_carosell.h index a268f05a4..1122befe5 100644 --- a/radio/src/gui/colorlcd/file_carosell.h +++ b/radio/src/gui/colorlcd/file_carosell.h @@ -37,10 +37,15 @@ class FileCarosell : public FormGroup inline void setSelected(int n); void setFileNames(std::vector fileNames); void checkEvents() override; + inline void pause(bool pause) + { + _paused = pause; + } void paint(BitmapBuffer *dc) override; protected: + bool _paused = false; int selected = -1; std::vector _fileNames; FilePreview *fp; diff --git a/radio/src/gui/colorlcd/fullscreen_dialog.cpp b/radio/src/gui/colorlcd/fullscreen_dialog.cpp index 0c5767561..8bd086d35 100644 --- a/radio/src/gui/colorlcd/fullscreen_dialog.cpp +++ b/radio/src/gui/colorlcd/fullscreen_dialog.cpp @@ -121,6 +121,12 @@ void FullScreenDialog::onEvent(event_t event) #endif #if defined(HARDWARE_TOUCH) +bool FullScreenDialog::onTouchStart(coord_t x, coord_t y) +{ + Window::onTouchStart(x, y); + return true; +} + bool FullScreenDialog::onTouchEnd(coord_t x, coord_t y) { Window::onTouchEnd(x, y); diff --git a/radio/src/gui/colorlcd/fullscreen_dialog.h b/radio/src/gui/colorlcd/fullscreen_dialog.h index ba352ceed..906094529 100644 --- a/radio/src/gui/colorlcd/fullscreen_dialog.h +++ b/radio/src/gui/colorlcd/fullscreen_dialog.h @@ -59,6 +59,7 @@ class FullScreenDialog : public FormGroup #endif #if defined(HARDWARE_TOUCH) + bool onTouchStart(coord_t x, coord_t y) override; bool onTouchEnd(coord_t x, coord_t y) override; #endif diff --git a/radio/src/gui/colorlcd/listbox.cpp b/radio/src/gui/colorlcd/listbox.cpp index 42001496d..3b81b9494 100644 --- a/radio/src/gui/colorlcd/listbox.cpp +++ b/radio/src/gui/colorlcd/listbox.cpp @@ -51,7 +51,7 @@ ListBase::ListBase(Window *parent, const rect_t &rect, std::vector void ListBase::setSelected(int selected) { - if (selected >= 0 && selected < (int)names.size()) { + if (selected >= 0 && selected < (int)names.size() && selected != this->selected) { this->selected = selected; setScrollPositionY(lineHeight * this->selected - lineHeight); if (_setValue != nullptr) { diff --git a/radio/src/gui/colorlcd/preview_window.h b/radio/src/gui/colorlcd/preview_window.h index 3fd2cbb23..95c86ace5 100644 --- a/radio/src/gui/colorlcd/preview_window.h +++ b/radio/src/gui/colorlcd/preview_window.h @@ -70,19 +70,6 @@ class ColorMaintainer extern ColorMaintainer colorMaintainer; // override of controls to draw them using a selected theme -class ThemedTextEdit : public TextEdit -{ - public: - using TextEdit::TextEdit; - - void paint(BitmapBuffer *dc) override - { - colorMaintainer.applyColorValues(); - TextEdit::paint(dc); - colorMaintainer.restoreColorValues(); - } -}; - class ThemedStaticText : public StaticText { public: @@ -189,6 +176,50 @@ class ThemedButton : public TextButton bool _isChecked = true; }; +class ThemedTextEdit : public TextEdit +{ + public: + ThemedTextEdit(Window *parent, const rect_t &rect, char *text, + int colorBackgroundIndex, int colorTextIndex) : + TextEdit(parent, rect, text, strlen(text)), + _colorBackgroundIndex(colorBackgroundIndex), + _colorTextIndex(colorTextIndex) + { + setBackgroundHandler([=] (FormField *field) { + return COLOR(_colorBackgroundIndex); + }); + } + + void paint(BitmapBuffer *dc) override + { + colorMaintainer.applyColorValues(); + FormField::paint(dc); + + dc->drawSizedText(FIELD_PADDING_LEFT, FIELD_PADDING_TOP, value, length, COLOR(_colorTextIndex)); + colorMaintainer.restoreColorValues(); + } + +#if defined(SOFTWARE_KEYBOARD) + bool onTouchEnd(coord_t x, coord_t y) override + { + return true; + } +#endif + + +#if defined(HARDWARE_KEYS) + void onEvent(event_t event) override + { + parent->onEvent(event); + } +#endif + + + protected: + int _colorBackgroundIndex; + int _colorTextIndex; +}; + // display controls using the appropriate theme. class PreviewWindow : public FormGroup @@ -201,11 +232,21 @@ class PreviewWindow : public FormGroup new ThemedStaticText(this, {5, 40, 100, LINE_HEIGHT}, "Checkbox", COLOR_THEME_PRIMARY1_INDEX); new ThemedCheckBox(this, {100 + 15, 40, 20, LINE_HEIGHT}, true); new ThemedCheckBox(this, {140 + 15, 40, 20, LINE_HEIGHT}, false); + new ThemedButton(this, {190, 40, 100, LINE_HEIGHT + 10}, "Active", true, BUTTON_CHECKED, COLOR_THEME_PRIMARY1_INDEX); + new ThemedButton(this, {190, 75, 100, LINE_HEIGHT + 10}, "Regular", false, 0, COLOR_THEME_PRIMARY1_INDEX); new ThemedMainViewHorizontalTrim(this, {5, 65, HORIZONTAL_SLIDERS_WIDTH, 20}, 0); new ThemedMainViewHorizontalSlider(this, {5, 87, HORIZONTAL_SLIDERS_WIDTH, 20}, 0); - new ThemedButton(this, {5, 109, 100, LINE_HEIGHT + 10}, "Checked", true, BUTTON_CHECKED, COLOR_THEME_PRIMARY1_INDEX); - new ThemedButton(this, {110, 109, 100, LINE_HEIGHT + 10}, "Regular", false, 0, COLOR_THEME_PRIMARY1_INDEX); - new ThemedStaticText(this, {5, 145, 100, LINE_HEIGHT}, "Warning Text", COLOR_THEME_WARNING_INDEX); + new ThemedStaticText(this, {5, 115, 100, LINE_HEIGHT}, "Warning Text", COLOR_THEME_WARNING_INDEX); + new ThemedStaticText(this, {5, 140, 100, LINE_HEIGHT}, "Disabled Text", COLOR_THEME_DISABLED_INDEX); + + static char EditText[128]; + strcpy(EditText, "Edit"); + new ThemedTextEdit(this, {5, 160, 100, LINE_HEIGHT + 1}, EditText, + COLOR_THEME_EDIT_INDEX, COLOR_THEME_PRIMARY2_INDEX); + static char FocusText[128]; + strcpy(FocusText, "Focus"); + new ThemedTextEdit(this, {110, 160, 100, LINE_HEIGHT + 1}, FocusText, + COLOR_THEME_FOCUS_INDEX, COLOR_THEME_PRIMARY2_INDEX); ticks = getTicks(); } diff --git a/radio/src/gui/colorlcd/radio_theme.cpp b/radio/src/gui/colorlcd/radio_theme.cpp index a728c2757..184dc509a 100644 --- a/radio/src/gui/colorlcd/radio_theme.cpp +++ b/radio/src/gui/colorlcd/radio_theme.cpp @@ -41,14 +41,18 @@ #define LEFT_LIST_WIDTH (LCD_W / 2) - COLOR_PREVIEW_WIDTH #define LEFT_LIST_HEIGHT (LCD_H - TOPBAR_HEIGHT - 37) #define COLOR_LIST_WIDTH ((LCD_W * 3)/10) - #define COLOR_LIST_HEIGHT (LCD_H - TOPBAR_HEIGHT) + #define COLOR_LIST_HEIGHT (LCD_H - TOPBAR_HEIGHT - 14) + #define TOP_LIST_OFFSET 4 + #define LEFT_LIST_OFFSET 3 #else #define COLOR_PREVIEW_WIDTH LCD_W #define COLOR_PREVIEW_HEIGHT 18 - #define LEFT_LIST_WIDTH LCD_W + #define LEFT_LIST_WIDTH LCD_W - 6 #define LEFT_LIST_HEIGHT (LCD_H / 2 - 38) - #define COLOR_LIST_WIDTH LCD_W - #define COLOR_LIST_HEIGHT (LCD_H / 2 - 38) + #define COLOR_LIST_WIDTH LCD_W - 6 + #define COLOR_LIST_HEIGHT (LCD_H / 2 - 24) + #define TOP_LIST_OFFSET 4 + #define LEFT_LIST_OFFSET 3 #endif #define MARGIN_WIDTH 5 @@ -60,7 +64,7 @@ constexpr LcdFlags textFont = FONT(STD); constexpr rect_t detailsDialogRect = {50, 50, 400, 170}; constexpr int labelWidth = 150; -constexpr int COLOR_BOX_LEFT = 3; +constexpr int COLOR_BOX_LEFT = 5; constexpr int COLOR_BOX_WIDTH = 45; constexpr int COLOR_BOX_HEIGHT = 27; #else @@ -225,7 +229,7 @@ protected: rect_t r; // hexBox - r = { COLOR_BOX_LEFT + COLOR_BOX_WIDTH + 5, 4, 90, 30 }; + r = { COLOR_BOX_LEFT + COLOR_BOX_WIDTH + 5, TOP_LIST_OFFSET, 90, 30 }; _hexBox = new StaticText(window, r, "", 0, COLOR_THEME_PRIMARY1 | FONT(L) | RIGHT); setHexStr(_hexBox, _theme.getColorEntryByIndex(_indexOfColor)->colorValue); @@ -256,8 +260,17 @@ protected: _colorSquare = new ColorSquare(window, r, _theme.getColorEntryByIndex(_indexOfColor)->colorValue); r = LCD_W > LCD_H ? - rect_t { COLOR_LIST_WIDTH + MARGIN_WIDTH, 4, LCD_W - COLOR_LIST_WIDTH - MARGIN_WIDTH * 2, COLOR_LIST_HEIGHT } : - rect_t { 0, LEFT_LIST_HEIGHT + 4, LEFT_LIST_WIDTH, LEFT_LIST_HEIGHT - 4 }; + rect_t { + COLOR_LIST_WIDTH + MARGIN_WIDTH + LEFT_LIST_OFFSET, + TOP_LIST_OFFSET, + LCD_W - COLOR_LIST_WIDTH - LEFT_LIST_OFFSET - MARGIN_WIDTH * 2, + COLOR_LIST_HEIGHT } : + rect_t { + LEFT_LIST_OFFSET, + TOP_LIST_OFFSET + COLOR_LIST_HEIGHT + MARGIN_WIDTH, + LEFT_LIST_WIDTH, + COLOR_LIST_HEIGHT - (MARGIN_WIDTH * 2) + }; _previewWindow = new PreviewWindow(window, r, _theme.getColorList()); } @@ -400,15 +413,25 @@ class ThemeEditPage : public Page void buildBody(FormGroup *window) { - rect_t r = { 0, 4, COLOR_LIST_WIDTH, COLOR_LIST_HEIGHT}; + rect_t r = { LEFT_LIST_OFFSET, TOP_LIST_OFFSET, COLOR_LIST_WIDTH, COLOR_LIST_HEIGHT}; _cList = new ColorList(window, r, _theme.getColorList()); _cList->setLongPressHandler([=] (event_t event) { editColorPage(); }); _cList->setPressHandler([=] (event_t event) { editColorPage(); }); if (LCD_W > LCD_H) { - r = { COLOR_LIST_WIDTH + MARGIN_WIDTH, 4, LCD_W - COLOR_LIST_WIDTH - MARGIN_WIDTH*2, COLOR_LIST_HEIGHT }; + r = { + COLOR_LIST_WIDTH + MARGIN_WIDTH + LEFT_LIST_OFFSET, + TOP_LIST_OFFSET, + LCD_W - COLOR_LIST_WIDTH - LEFT_LIST_OFFSET - MARGIN_WIDTH * 2, + COLOR_LIST_HEIGHT + }; } else { - r = { 0, LEFT_LIST_HEIGHT + 4, LEFT_LIST_WIDTH, LEFT_LIST_HEIGHT - 4}; + r = { + LEFT_LIST_OFFSET, + TOP_LIST_OFFSET + COLOR_LIST_HEIGHT + MARGIN_WIDTH, + LEFT_LIST_WIDTH, + COLOR_LIST_HEIGHT - (MARGIN_WIDTH * 2) + }; } _previewWindow = new PreviewWindow(window, r, _theme.getColorList()); } @@ -429,6 +452,31 @@ ThemeSetupPage::ThemeSetupPage() : PageTab(STR_THEME_EDITOR, ICON_RADIO_EDIT_THE ThemeSetupPage::~ThemeSetupPage() { } +void ThemeSetupPage::setAuthor(ThemeFile *theme) +{ + char author[256]; + strcpy(author, "By: "); + strcat(author, theme->getAuthor()); + authorText->setText(author); +} + + +bool isTopWindow(Window *window) +{ + Window *parent = window->getParent(); + if (parent != nullptr) { + parent = parent->getParent(); + return parent == Layer::stack.back().main; + } + return false; +} + +void ThemeSetupPage::checkEvents() +{ + PageTab::checkEvents(); + + fileCarosell->pause(!isTopWindow(pageWindow)); +} void ThemeSetupPage::displayThemeMenu(Window *window, ThemePersistance *tp) { @@ -467,12 +515,20 @@ void ThemeSetupPage::displayThemeMenu(Window *window, ThemePersistance *tp) n++; } + themeColorPreview->setColorList(theme.getColorList()); + // save it to disk so it will come back the next time. curTheme->serialize(); - // if the active theme was edited then activate it. - if (listBox->getSelected() == tp->getThemeIndex()) + // if the active theme was edited then activate and update + // the UI + if (listBox->getSelected() == tp->getThemeIndex()) { tp->applyTheme(listBox->getSelected()); + setAuthor(&theme); + nameText->setText(theme.getName()); + nameText->setTextFlags(COLOR_THEME_PRIMARY1); + authorText->setTextFlags(COLOR_THEME_PRIMARY1); + } // the list of theme names might have changed listBox->setNames(tp->getNames()); @@ -522,10 +578,10 @@ void ThemeSetupPage::setupListbox(FormWindow *window, rect_t r, ThemePersistance return currentTheme; }, [=](uint8_t value) { - if (themeColorPreview && authorText && nameText && fileCarosell) { + if (themeColorPreview && authorText && nameText && fileCarosell != nullptr) { ThemeFile *theme = tp->getThemeByIndex(value); themeColorPreview->setColorList(theme->getColorList()); - authorText->setText(theme->getAuthor()); + setAuthor(theme); nameText->setText(theme->getName()); fileCarosell->setFileNames(theme->getThemeImageFileNames()); } @@ -542,6 +598,8 @@ void ThemeSetupPage::setupListbox(FormWindow *window, rect_t r, ThemePersistance void ThemeSetupPage::build(FormWindow *window) { + pageWindow = window; + auto tp = ThemePersistance::instance(); auto theme = tp->getCurrentTheme(); currentTheme = tp->getThemeIndex(); @@ -553,12 +611,12 @@ void ThemeSetupPage::build(FormWindow *window) authorText = nullptr; // create listbox and setup menus - rect_t r = { 2, 3, LEFT_LIST_WIDTH, LEFT_LIST_HEIGHT }; + rect_t r = { LEFT_LIST_OFFSET, TOP_LIST_OFFSET, LEFT_LIST_WIDTH, LEFT_LIST_HEIGHT }; setupListbox(window, r, tp); rect_t colorPreviewRect; if (LCD_W > LCD_H) { - r.x = LEFT_LIST_WIDTH + MARGIN_WIDTH; + r.x = LEFT_LIST_WIDTH + MARGIN_WIDTH + LEFT_LIST_OFFSET; r.w = LCD_W - r.x; colorPreviewRect = {LEFT_LIST_WIDTH + 6, 0, COLOR_PREVIEW_WIDTH, COLOR_PREVIEW_HEIGHT}; } else { @@ -592,9 +650,7 @@ void ThemeSetupPage::build(FormWindow *window) COLOR_THEME_PRIMARY1); if (theme != nullptr && strlen(theme->getAuthor())) { r.y += 20; - char author[256]; - strcpy(author, "By: "); - strcat(author, theme->getAuthor()); - authorText = new StaticText(window, r, author, 0, COLOR_THEME_PRIMARY1); + authorText = new StaticText(window, r, "", 0, COLOR_THEME_PRIMARY1); + setAuthor(theme); } } diff --git a/radio/src/gui/colorlcd/radio_theme.h b/radio/src/gui/colorlcd/radio_theme.h index 08407097d..c998030f0 100644 --- a/radio/src/gui/colorlcd/radio_theme.h +++ b/radio/src/gui/colorlcd/radio_theme.h @@ -126,8 +126,10 @@ class ThemeSetupPage: public PageTab { ~ThemeSetupPage(); void build(FormWindow * window) override; + void checkEvents() override; protected: + Window *pageWindow = nullptr; Window *previewWindow = nullptr; FileCarosell *fileCarosell = nullptr; ThemeColorPreview *themeColorPreview = nullptr; @@ -137,4 +139,5 @@ class ThemeSetupPage: public PageTab { int currentTheme = 0; void setupListbox(FormWindow *window, rect_t r, ThemePersistance *tp); void displayThemeMenu(Window *window, ThemePersistance *tp); + void setAuthor(ThemeFile *theme); };