From 25715ed648c16506cb0e27db9c2f465a44780061 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Fri, 27 May 2022 12:38:59 +0200 Subject: [PATCH] Replaced focus handling with LVGL groups --- .../thirdparty/libopenui/src/CMakeLists.txt | 4 +- radio/src/thirdparty/libopenui/src/button.cpp | 57 +---- radio/src/thirdparty/libopenui/src/button.h | 16 +- .../libopenui/src/button_matrix.cpp | 86 ++----- .../thirdparty/libopenui/src/button_matrix.h | 3 +- .../src/thirdparty/libopenui/src/checkbox.cpp | 31 +-- radio/src/thirdparty/libopenui/src/checkbox.h | 60 ++--- radio/src/thirdparty/libopenui/src/choice.cpp | 29 +-- radio/src/thirdparty/libopenui/src/choice.h | 8 +- radio/src/thirdparty/libopenui/src/dialog.cpp | 21 +- radio/src/thirdparty/libopenui/src/dialog.h | 3 +- .../libopenui/src/expansion_panel.cpp | 76 ------ .../libopenui/src/expansion_panel.h | 99 -------- .../thirdparty/libopenui/src/filechoice.cpp | 27 +- .../src/thirdparty/libopenui/src/filechoice.h | 8 +- radio/src/thirdparty/libopenui/src/form.cpp | 237 ++---------------- radio/src/thirdparty/libopenui/src/form.h | 84 +------ .../libopenui/src/keyboard_base.cpp | 65 ++++- .../thirdparty/libopenui/src/keyboard_base.h | 35 +-- .../libopenui/src/keyboard_number.cpp | 114 +++++---- .../libopenui/src/keyboard_number.h | 37 +-- .../libopenui/src/keyboard_text.cpp | 11 + .../thirdparty/libopenui/src/keyboard_text.h | 34 +-- radio/src/thirdparty/libopenui/src/layer.cpp | 64 +++++ radio/src/thirdparty/libopenui/src/layer.h | 68 +---- .../thirdparty/libopenui/src/mainwindow.cpp | 19 +- radio/src/thirdparty/libopenui/src/menu.cpp | 67 ++--- radio/src/thirdparty/libopenui/src/menu.h | 18 +- .../thirdparty/libopenui/src/menutoolbar.h | 62 +++-- .../thirdparty/libopenui/src/modal_window.cpp | 19 +- .../thirdparty/libopenui/src/modal_window.h | 52 ++-- .../thirdparty/libopenui/src/numberedit.cpp | 73 ++---- .../src/thirdparty/libopenui/src/numberedit.h | 35 ++- radio/src/thirdparty/libopenui/src/table.cpp | 33 ++- radio/src/thirdparty/libopenui/src/table.h | 2 +- .../src/thirdparty/libopenui/src/textedit.cpp | 37 +-- radio/src/thirdparty/libopenui/src/textedit.h | 7 +- .../libopenui/src/widgets/simple_btn.c | 38 +++ .../libopenui/src/widgets/simple_btn.h | 36 +++ .../libopenui/src/widgets/window_base.c | 52 ++++ .../libopenui/src/widgets/window_base.h | 36 +++ radio/src/thirdparty/libopenui/src/window.cpp | 181 ++++--------- radio/src/thirdparty/libopenui/src/window.h | 52 ++-- .../src/thirdparty/libopenui/thirdparty/lvgl | 2 +- 44 files changed, 746 insertions(+), 1352 deletions(-) delete mode 100644 radio/src/thirdparty/libopenui/src/expansion_panel.cpp delete mode 100644 radio/src/thirdparty/libopenui/src/expansion_panel.h create mode 100644 radio/src/thirdparty/libopenui/src/widgets/simple_btn.c create mode 100644 radio/src/thirdparty/libopenui/src/widgets/simple_btn.h create mode 100644 radio/src/thirdparty/libopenui/src/widgets/window_base.c create mode 100644 radio/src/thirdparty/libopenui/src/widgets/window_base.h diff --git a/radio/src/thirdparty/libopenui/src/CMakeLists.txt b/radio/src/thirdparty/libopenui/src/CMakeLists.txt index 07c62cea4..13b688369 100644 --- a/radio/src/thirdparty/libopenui/src/CMakeLists.txt +++ b/radio/src/thirdparty/libopenui/src/CMakeLists.txt @@ -35,7 +35,9 @@ set(LIBOPENUI_SRC table.cpp modal_window.cpp dialog.cpp - expansion_panel.cpp + # LVGL widgets + widgets/window_base.c + widgets/simple_btn.c ) if(SOFTWARE_KEYBOARD) diff --git a/radio/src/thirdparty/libopenui/src/button.cpp b/radio/src/thirdparty/libopenui/src/button.cpp index d88ea9456..d3d716136 100644 --- a/radio/src/thirdparty/libopenui/src/button.cpp +++ b/radio/src/thirdparty/libopenui/src/button.cpp @@ -22,14 +22,7 @@ #include "font.h" #include "theme.h" -static void lvglEvent(lv_event_t* e) -{ - Button* btn = (Button*)lv_event_get_user_data(e); - if(btn->deleted()) - return; - - btn->onEvent(e); -} +#include "widgets/simple_btn.h" static void update_checked_flag(lv_obj_t* obj, WindowFlags flags) { @@ -43,11 +36,10 @@ Button::Button(Window* parent, const rect_t& rect, std::function pressHandler, WindowFlags windowFlag, LcdFlags textFlags, LvglCreate objConstruct) : - FormField(parent, rect, windowFlag, textFlags, objConstruct), + FormField(parent, rect, windowFlag, textFlags, + objConstruct ? objConstruct : simple_btn_create), pressHandler(std::move(pressHandler)) { - lv_obj_add_event_cb(lvobj, lvglEvent, LV_EVENT_CLICKED, this); - if (windowFlag & BUTTON_CHECKED) lv_obj_add_state(lvobj, LV_STATE_CHECKED); } @@ -78,55 +70,20 @@ void Button::onPress() update_checked_flag(lvobj, windowFlags); } -#if defined(HARDWARE_KEYS) -void Button::onEvent(event_t event) +void Button::onClicked() { - auto indev_act = lv_indev_get_act(); - switch (event) { - case EVT_KEY_FIRST(KEY_ENTER): - lv_event_send(lvobj, LV_EVENT_PRESSED, indev_act); - break; - - case EVT_KEY_BREAK(KEY_ENTER): - lv_event_send(lvobj, LV_EVENT_RELEASED, indev_act); - lv_event_send(lvobj, LV_EVENT_CLICKED, indev_act); - break; - - default: - FormField::onEvent(event); - break; - } -} -#endif - -void Button::onEvent(lv_event_t* event) -{ - lv_event_code_t code = lv_event_get_code(event); - - TRACE_WINDOWS("%s received lvgl event code 0x%X", getWindowDebugString("Button").c_str(), code); - - if (enabled && code == LV_EVENT_CLICKED) { - if (!(windowFlags & NO_FOCUS)) { - setFocus(SET_FOCUS_DEFAULT); - } - onKeyPress(); - onPress(); - } + onPress(); } #if defined(HARDWARE_TOUCH) // this needs to stay so that viewmain doesnt get the touch event -bool Button::onTouchEnd(coord_t x, coord_t y) -{ - return true; -} +bool Button::onTouchEnd(coord_t x, coord_t y) { return true; } #endif void Button::checkEvents() { Window::checkEvents(); - if (checkHandler) - checkHandler(); + if (checkHandler) checkHandler(); } TextButton::TextButton(Window* parent, const rect_t& rect, std::string text, diff --git a/radio/src/thirdparty/libopenui/src/button.h b/radio/src/thirdparty/libopenui/src/button.h index 17209f7f2..56319ff35 100644 --- a/radio/src/thirdparty/libopenui/src/button.h +++ b/radio/src/thirdparty/libopenui/src/button.h @@ -40,6 +40,10 @@ class Button: public FormField } #endif + virtual void onPress(); + void onClicked() override; + void checkEvents() override; + void check(bool checked = true); bool checked() const; @@ -53,22 +57,18 @@ class Button: public FormField checkHandler = std::move(handler); } -#if defined(HARDWARE_KEYS) - void onEvent(event_t event) override; -#endif - void onEvent(lv_event_t* e);// override; +// #if defined(HARDWARE_KEYS) +// void onEvent(event_t event) override; +// #endif + // void onEvent(lv_event_t* e);// override; #if defined(HARDWARE_TOUCH) bool onTouchEnd(coord_t x, coord_t y) override; #endif - void checkEvents() override; - protected: std::function pressHandler; std::function checkHandler; - - virtual void onPress(); }; diff --git a/radio/src/thirdparty/libopenui/src/button_matrix.cpp b/radio/src/thirdparty/libopenui/src/button_matrix.cpp index 5e774aa0b..fd4ea7fa7 100644 --- a/radio/src/thirdparty/libopenui/src/button_matrix.cpp +++ b/radio/src/thirdparty/libopenui/src/button_matrix.cpp @@ -28,38 +28,47 @@ static const char _map_end[] = ""; static void btn_matrix_event(lv_event_t *e) { - static lv_area_t draw_area; - lv_event_code_t code = lv_event_get_code(e); if (code == LV_EVENT_VALUE_CHANGED) { + lv_obj_t* obj = lv_event_get_target(e); auto btn_id = (uint32_t *)lv_event_get_param(e); auto btnm = (ButtonMatrix*)lv_event_get_user_data(e); - btnm->onPress((uint8_t)*btn_id); + bool edited = lv_obj_has_state(obj, LV_STATE_EDITED); + bool is_pointer = lv_indev_get_type(lv_indev_get_act()) == LV_INDEV_TYPE_POINTER; + if (edited || is_pointer) + btnm->onPress((uint8_t)*btn_id); } else if (code == LV_EVENT_DRAW_PART_BEGIN) { lv_obj_draw_part_dsc_t* dsc = lv_event_get_draw_part_dsc(e); - if (dsc->part != LV_PART_ITEMS) return; - - auto btnm = (ButtonMatrix*)lv_event_get_user_data(e); - if (btnm->isActive((uint8_t)dsc->id)) { - dsc->rect_dsc->bg_color = makeLvColor(COLOR_THEME_ACTIVE); - dsc->label_dsc->color = makeLvColor(COLOR_THEME_PRIMARY2); - } else { - dsc->rect_dsc->bg_color = makeLvColor(COLOR_THEME_PRIMARY2); - dsc->label_dsc->color = makeLvColor(COLOR_THEME_SECONDARY1); + if (dsc->part == LV_PART_ITEMS) { + auto btnm = (ButtonMatrix*)lv_event_get_user_data(e); + if (btnm->isActive((uint8_t)dsc->id)) { + dsc->rect_dsc->bg_color = makeLvColor(COLOR_THEME_ACTIVE); + dsc->label_dsc->color = makeLvColor(COLOR_THEME_PRIMARY2); + } else { + dsc->rect_dsc->bg_color = makeLvColor(COLOR_THEME_PRIMARY2); + dsc->label_dsc->color = makeLvColor(COLOR_THEME_SECONDARY1); + } + } else if (dsc->part == LV_PART_MAIN) { + lv_obj_t* obj = lv_event_get_target(e); + if (lv_obj_has_state(obj, LV_STATE_FOCUS_KEY) && + !lv_obj_has_state(obj, LV_STATE_EDITED)) { + dsc->rect_dsc->bg_color = makeLvColor(COLOR_THEME_FOCUS); + dsc->rect_dsc->bg_opa = LV_OPA_20; + } } - - // backup draw area as it gets modified for the label - lv_area_copy(&draw_area, dsc->draw_area); } } ButtonMatrix::ButtonMatrix(Window* parent, const rect_t& r) : FormField(parent, r, 0, 0, lv_btnmatrix_create) { + lv_obj_add_flag(lvobj, LV_OBJ_FLAG_SCROLL_ON_FOCUS); + lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_CLICK_FOCUSABLE); + lv_obj_add_event_cb(lvobj, btn_matrix_event, LV_EVENT_ALL, this); } @@ -132,49 +141,8 @@ void ButtonMatrix::update() lv_btnmatrix_set_btn_ctrl_all(lvobj, ctrl); } -void ButtonMatrix::onEvent(event_t event) +void ButtonMatrix::onClicked() { - char c = 0; - lv_event_code_t code = LV_EVENT_ALL; - -#if defined (HARDWARE_KEYS) - switch (event) { - case EVT_KEY_FIRST(KEY_ENTER): - code = LV_EVENT_PRESSED; - break; - - case EVT_KEY_BREAK(KEY_ENTER): - code = LV_EVENT_RELEASED; - break; - - case EVT_ROTARY_LEFT: - if (lv_btnmatrix_get_selected_btn(lvobj) != 0) { - code = LV_EVENT_KEY; - c = LV_KEY_LEFT; - } - break; - case EVT_ROTARY_RIGHT: - if (lv_btnmatrix_get_selected_btn(lvobj) < btn_cnt - 1) { - code = LV_EVENT_KEY; - c = LV_KEY_RIGHT; - } - break; - } -#endif - - if ((code == LV_EVENT_KEY) && c != 0) lv_event_send(lvobj, code, &c); - else if (code != LV_EVENT_ALL) lv_event_send(lvobj, code, lv_indev_get_act()); - else FormField::onEvent(event); -} - -void ButtonMatrix::setFocus(uint8_t flag, Window* from) -{ - if (lv_btnmatrix_get_selected_btn(lvobj) == LV_BTNMATRIX_BTN_NONE) { - if (flag == SET_FOCUS_BACKWARD) - lv_btnmatrix_set_selected_btn(lvobj, btn_cnt - 1); - else - lv_btnmatrix_set_selected_btn(lvobj, 0); - } - - FormField::setFocus(flag, from); + lv_group_focus_obj(lvobj); + FormField::onClicked(); } diff --git a/radio/src/thirdparty/libopenui/src/button_matrix.h b/radio/src/thirdparty/libopenui/src/button_matrix.h index 2438b4b0d..2d84ebae7 100644 --- a/radio/src/thirdparty/libopenui/src/button_matrix.h +++ b/radio/src/thirdparty/libopenui/src/button_matrix.h @@ -41,6 +41,5 @@ class ButtonMatrix : public FormField void setText(uint8_t btn_id, const char* txt); void update(); - void onEvent(event_t event) override; - void setFocus(uint8_t flag, Window* from) override; + void onClicked() override; }; diff --git a/radio/src/thirdparty/libopenui/src/checkbox.cpp b/radio/src/thirdparty/libopenui/src/checkbox.cpp index 457e6326a..8bee639ae 100644 --- a/radio/src/thirdparty/libopenui/src/checkbox.cpp +++ b/radio/src/thirdparty/libopenui/src/checkbox.cpp @@ -52,34 +52,7 @@ CheckBox::CheckBox(Window* parent, const rect_t& rect, LV_EVENT_VALUE_CHANGED, this); } -#if defined(HARDWARE_KEYS) -void CheckBox::onEvent(event_t event) +void CheckBox::onClicked() { - TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString("CheckBox").c_str(), event); - - if (enabled && event == EVT_KEY_BREAK(KEY_ENTER)) { - onKeyPress(); - if (lv_obj_get_state(lvobj) & LV_STATE_CHECKED) - lv_obj_clear_state(lvobj, LV_STATE_CHECKED); - else - lv_obj_add_state(lvobj, LV_STATE_CHECKED); - - _setValue(lv_obj_get_state(lvobj) & LV_STATE_CHECKED); - } - else { - FormField::onEvent(event); - } + // prevent FormField::onClicked() } -#endif - -#if defined(HARDWARE_TOUCH) -bool CheckBox::onTouchEnd(coord_t x, coord_t y) -{ - if (!hasFocus()) { - setFocus(SET_FOCUS_DEFAULT); - } - - return true; -} -#endif - diff --git a/radio/src/thirdparty/libopenui/src/checkbox.h b/radio/src/thirdparty/libopenui/src/checkbox.h index 235d08b9c..12c4210cb 100644 --- a/radio/src/thirdparty/libopenui/src/checkbox.h +++ b/radio/src/thirdparty/libopenui/src/checkbox.h @@ -22,52 +22,32 @@ #include #include "form.h" -class CheckBox : public FormField { - public: - CheckBox(Window * parent, const rect_t & rect, std::function getValue, std::function setValue, WindowFlags flags = 0); +class CheckBox : public FormField +{ + public: + CheckBox(Window* parent, const rect_t& rect, + std::function getValue, + std::function setValue, WindowFlags flags = 0); #if defined(DEBUG_WINDOWS) - std::string getName() const override - { - return "CheckBox"; - } + std::string getName() const override { return "CheckBox"; } #endif - const char * getLabel() const - { - return label.c_str(); - } + void onClicked() override; - void setLabel(std::string newLabel) - { - label = std::move(newLabel); - } + const char* getLabel() const { return label.c_str(); } + void setLabel(std::string newLabel) { label = std::move(newLabel); } -#if defined(HARDWARE_KEYS) - void onEvent(event_t event) override; -#endif + uint8_t getValue() const { return _getValue(); } + void setValue(uint8_t value) { _setValue(value); } -#if defined(HARDWARE_TOUCH) - bool onTouchEnd(coord_t x, coord_t y) override; -#endif + void setSetValueHandler(std::function handler) + { + _setValue = std::move(handler); + } - uint8_t getValue() const - { - return _getValue(); - } - - void setValue(uint8_t value) - { - _setValue(value); - } - - void setSetValueHandler(std::function handler) - { - _setValue = std::move(handler); - } - - protected: - std::string label; - std::function _getValue; - std::function _setValue; + protected: + std::string label; + std::function _getValue; + std::function _setValue; }; diff --git a/radio/src/thirdparty/libopenui/src/choice.cpp b/radio/src/thirdparty/libopenui/src/choice.cpp index bfcf73556..760ea2386 100644 --- a/radio/src/thirdparty/libopenui/src/choice.cpp +++ b/radio/src/thirdparty/libopenui/src/choice.cpp @@ -181,20 +181,11 @@ void Choice::setValues(const char * const values[]) } } -#if defined(HARDWARE_KEYS) -void Choice::onEvent(event_t event) +void Choice::onClicked() { - TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event); - - if (event == EVT_KEY_BREAK(KEY_ENTER)) { - onKeyPress(); - openMenu(); - } - else { - FormField::onEvent(event); - } + onKeyPress(); + openMenu(); } -#endif void Choice::openMenu() { @@ -247,17 +238,3 @@ void Choice::openMenu() setEditMode(false); }); } - -#if defined(HARDWARE_TOUCH) -bool Choice::onTouchEnd(coord_t, coord_t) -{ - if (enabled) { - if (!hasFocus()) { - setFocus(SET_FOCUS_DEFAULT); - } - onKeyPress(); - openMenu(); - } - return true; -} -#endif diff --git a/radio/src/thirdparty/libopenui/src/choice.h b/radio/src/thirdparty/libopenui/src/choice.h index c338f5707..14337ee62 100644 --- a/radio/src/thirdparty/libopenui/src/choice.h +++ b/radio/src/thirdparty/libopenui/src/choice.h @@ -81,13 +81,7 @@ class Choice: public ChoiceBase { } #endif -#if defined(HARDWARE_KEYS) - void onEvent(event_t event) override; -#endif - -#if defined(HARDWARE_TOUCH) - bool onTouchEnd(coord_t x, coord_t y) override; -#endif + void onClicked() override; void setBeforeDisplayMenuHandler(std::function handler) { diff --git a/radio/src/thirdparty/libopenui/src/dialog.cpp b/radio/src/thirdparty/libopenui/src/dialog.cpp index 00f599ccd..066fffafd 100644 --- a/radio/src/thirdparty/libopenui/src/dialog.cpp +++ b/radio/src/thirdparty/libopenui/src/dialog.cpp @@ -21,14 +21,16 @@ #include "mainwindow.h" #include "theme.h" +static rect_t _get_form_rect(const rect_t& rect) +{ + return {0, POPUP_HEADER_HEIGHT, rect.w, + coord_t(rect.h - POPUP_HEADER_HEIGHT)}; +} + DialogWindowContent::DialogWindowContent(Dialog* parent, const rect_t& rect) : ModalWindowContent(parent, rect), - form(this, - { 0, POPUP_HEADER_HEIGHT, rect.w, - coord_t(rect.h - POPUP_HEADER_HEIGHT) }, - FORM_NO_BORDER | FORM_FORWARD_FOCUS) + form(this, _get_form_rect(rect), FORM_NO_BORDER) { - form.setFocus(SET_FOCUS_DEFAULT); } void DialogWindowContent::deleteLater(bool detach, bool trash) @@ -58,12 +60,7 @@ Dialog::Dialog(Window* parent, std::string title, const rect_t& rect) : if (!title.empty()) content->setTitle(std::move(title)); } -void Dialog::onEvent(event_t event) +void Dialog::onCancel() { -#if defined(HARDWARE_KEYS) - if (event == EVT_KEY_LONG(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) { - killEvents(event); - deleteLater(); - } -#endif + deleteLater(); } diff --git a/radio/src/thirdparty/libopenui/src/dialog.h b/radio/src/thirdparty/libopenui/src/dialog.h index 3b00520b8..0678fc11b 100644 --- a/radio/src/thirdparty/libopenui/src/dialog.h +++ b/radio/src/thirdparty/libopenui/src/dialog.h @@ -48,6 +48,7 @@ class Dialog : public ModalWindow Dialog(Window* parent, std::string title, const rect_t& rect); protected: - void onEvent(event_t event) override; DialogWindowContent* content; + + void onCancel() override; }; diff --git a/radio/src/thirdparty/libopenui/src/expansion_panel.cpp b/radio/src/thirdparty/libopenui/src/expansion_panel.cpp deleted file mode 100644 index 99a8c7e43..000000000 --- a/radio/src/thirdparty/libopenui/src/expansion_panel.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) OpenTX - * - * Source: - * https://github.com/opentx/libopenui - * - * This file is a part of libopenui library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ - -#include "expansion_panel.h" - -void ExpansionPanel::updateHeight(bool move) -{ - coord_t newHeight = (isOpen ? header->height() + body->height() : header->height()); - if (move) { - parent->moveWindowsTop(bottom(), newHeight - height()); - } - setHeight(newHeight); -} - -void ExpansionPanel::setFocus(uint8_t flag, Window * from) -{ - if (!enabled || isOpen) - FormGroup::setFocus(flag, from); - else - header->setFocus(flag, from); -} - -ExpansionPanelHeader::ExpansionPanelHeader(ExpansionPanel * parent): - FormGroup(parent, {0, 0, parent->width(), parent->height()}, FORWARD_SCROLL) -{ -} - -void ExpansionPanelHeader::onEvent(event_t event) -{ - auto panel = static_cast(parent); - - if (event == EVT_KEY_BREAK(KEY_ENTER)) { - panel->toggle(); - } - else if (event == EVT_ROTARY_RIGHT && !panel->isOpen) { - auto next = panel->getNextField(); - if (next) - next->setFocus(SET_FOCUS_FORWARD, this); - } - else if (event == EVT_ROTARY_LEFT) { - auto previous = panel->getPreviousField(); - if (previous) { - previous->setFocus(SET_FOCUS_BACKWARD, this); - } - } - else { - FormGroup::onEvent(event); - } -} - -#if defined(HARDWARE_TOUCH) -bool ExpansionPanelHeader::onTouchEnd(coord_t, coord_t) -{ - if (enabled) { - static_cast(parent)->toggle(); - setFocus(SET_FOCUS_DEFAULT); - } - return true; -} -#endif diff --git a/radio/src/thirdparty/libopenui/src/expansion_panel.h b/radio/src/thirdparty/libopenui/src/expansion_panel.h deleted file mode 100644 index 9dd965ac5..000000000 --- a/radio/src/thirdparty/libopenui/src/expansion_panel.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) OpenTX - * - * Source: - * https://github.com/opentx/libopenui - * - * This file is a part of libopenui library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ - -#pragma once - -#include "form.h" - -class ExpansionPanel; - -class ExpansionPanelHeader: virtual public FormGroup -{ - public: - explicit ExpansionPanelHeader(ExpansionPanel * parent); - -#if defined(DEBUG_WINDOWS) - std::string getName() const override - { - return "ExpansionPanelHeader"; - } -#endif - - void onEvent(event_t event) override; - -#if defined(HARDWARE_TOUCH) - bool onTouchEnd(coord_t, coord_t) override; -#endif -}; - -class ExpansionPanel: public FormGroup -{ - friend class ExpansionPanelHeader; - - public: - ExpansionPanel(Window * parent, const rect_t & rect): - FormGroup(parent, rect, FORM_NO_BORDER | FORM_FORWARD_FOCUS | FORWARD_SCROLL) - { - } - -#if defined(DEBUG_WINDOWS) - std::string getName() const override - { - return "ExpansionPanel"; - } -#endif - - void toggle() - { - open(!isOpen); - } - - virtual void open(bool state = true) - { - isOpen = state; - updateHeight(); - } - - void setCloseAllowed(bool value = true) - { - header->enable(value); - } - - void enable(bool value = true) - { - FormGroup::enable(value); - header->enable(value); - } - - void disable() - { - open(false); - enable(false); - } - - void updateHeight(bool move = true); - - void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr) override; - - FormGroup * body = nullptr; - - protected: - ExpansionPanelHeader * header = nullptr; - bool isOpen = false; -}; diff --git a/radio/src/thirdparty/libopenui/src/filechoice.cpp b/radio/src/thirdparty/libopenui/src/filechoice.cpp index 0e153fd49..eb6ef25c6 100644 --- a/radio/src/thirdparty/libopenui/src/filechoice.cpp +++ b/radio/src/thirdparty/libopenui/src/filechoice.cpp @@ -120,7 +120,7 @@ bool FileChoice::openMenu() menu->setCloseHandler([=]() { editMode = false; - setFocus(SET_FOCUS_DEFAULT); + // setFocus(SET_FOCUS_DEFAULT); }); return true; @@ -132,29 +132,8 @@ bool FileChoice::openMenu() return false; } -#if defined(HARDWARE_KEYS) -void FileChoice::onEvent(event_t event) +void FileChoice::onClicked() { - TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event); - - if (event == EVT_KEY_BREAK(KEY_ENTER)) { - if (openMenu()) { - editMode = true; - invalidate(); - } - } - else { - FormField::onEvent(event); - } -} -#endif - -#if defined(HARDWARE_TOUCH) -bool FileChoice::onTouchEnd(coord_t, coord_t) -{ - setFocus(SET_FOCUS_DEFAULT); - setEditMode(true); + onKeyPress(); openMenu(); - return true; } -#endif diff --git a/radio/src/thirdparty/libopenui/src/filechoice.h b/radio/src/thirdparty/libopenui/src/filechoice.h index f3003c4c5..e74527107 100644 --- a/radio/src/thirdparty/libopenui/src/filechoice.h +++ b/radio/src/thirdparty/libopenui/src/filechoice.h @@ -35,13 +35,7 @@ public: std::string getName() const override { return "FileChoice"; } #endif -#if defined(HARDWARE_KEYS) - void onEvent(event_t event) override; -#endif - -#if defined(HARDWARE_TOUCH) - bool onTouchEnd(coord_t x, coord_t y) override; -#endif + void onClicked() override; protected: std::string getLabelText() override; diff --git a/radio/src/thirdparty/libopenui/src/form.cpp b/radio/src/thirdparty/libopenui/src/form.cpp index 0c4bb998e..91b2659ee 100644 --- a/radio/src/thirdparty/libopenui/src/form.cpp +++ b/radio/src/thirdparty/libopenui/src/form.cpp @@ -21,71 +21,45 @@ #include "bitmapbuffer.h" #include "libopenui_config.h" +#include "widgets/window_base.h" + FormField::FormField(Window* parent, const rect_t& rect, WindowFlags windowFlags, LcdFlags textFlags, LvglCreate objConstruct) : Window(parent, rect, windowFlags, textFlags, objConstruct) { - if (!(windowFlags & NO_FOCUS) || (windowFlags & FORM_FORWARD_FOCUS)) { - auto cont = dynamic_cast(parent); - if (cont) { - cont->addField(this); - } - } } -#if defined(HARDWARE_KEYS) -void FormField::onEvent(event_t event) +void FormField::setEditMode(bool newEditMode) { - TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString("FormField").c_str(), event); + editMode = newEditMode; - if (event == EVT_ROTARY_RIGHT/*EVT_KEY_BREAK(KEY_DOWN)*/) { - if (next) { - onKeyPress(); - next->setFocus(SET_FOCUS_FORWARD, this); - } + if (lvobj != nullptr) { + lv_group_t* grp = (lv_group_t*)lv_obj_get_group(lvobj); + if (grp != nullptr) lv_group_set_editing(grp, editMode); } - else if (event == EVT_ROTARY_LEFT/*EVT_KEY_BREAK(KEY_UP)*/) { - if (previous) { - onKeyPress(); - previous->setFocus(SET_FOCUS_BACKWARD, this); - } + + if (editMode && lvobj != nullptr) { + lv_obj_add_state(lvobj, LV_STATE_EDITED); + } else if (lvobj != nullptr) { + lv_obj_clear_state(lvobj, LV_STATE_EDITED); } - else if (event == EVT_KEY_BREAK(KEY_ENTER)) { - onKeyPress(); - setEditMode(!editMode); - invalidate(); - } - else if (event == EVT_KEY_BREAK(KEY_EXIT) && editMode) { - onKeyPress(); + invalidate(); +} + +void FormField::onClicked() +{ + setEditMode(!editMode); + invalidate(); +} + +void FormField::onCancel() +{ + if (isEditMode()) { setEditMode(false); invalidate(); - } - else { - Window::onEvent(event); - } -} -#endif -extern lv_group_t* inputGroup; -void FormField::setFocus(uint8_t flag, Window * from) -{ - if (enabled && !lv_obj_has_flag(lvobj, LV_OBJ_FLAG_HIDDEN)) { - Window::setFocus(flag, from); - if(lvobj != nullptr) { - lv_group_focus_obj(lvobj); - } - } - else { - if (flag == SET_FOCUS_BACKWARD) { - if (previous) { - previous->setFocus(flag, this); - } - } - else { - if (next) { - next->setFocus(flag, this); - } - } + } else { + Window::onCancel(); } } @@ -126,35 +100,11 @@ void FormGroup::Line::addChild(Window* window) } } -void FormGroup::Line::addField(FormField *field) -{ - group->addField(field); -} - -void FormGroup::Line::removeField(FormField *field) -{ - auto form = static_cast(parent); - form->removeField(field); -} - FormGroup::FormGroup(Window* parent, const rect_t& rect, WindowFlags windowflags, LvglCreate objConstruct) : - FormField(parent, rect, windowflags, 0, objConstruct) + Window(parent, rect, windowflags, 0, objConstruct) { lv_obj_set_style_bg_opa(lvobj, LV_OPA_TRANSP, LV_PART_MAIN); - - - -} - -void FormGroup::clear() -{ - Window::clear(); - first = nullptr; - last = nullptr; - if (previous && (windowFlags & FORM_FORWARD_FOCUS)) { - previous->setNextField(this); - } } void FormGroup::setFlexLayout(lv_flex_flow_t flow, lv_coord_t padding) @@ -175,136 +125,3 @@ FormGroup::Line* FormGroup::newLine(FlexGridLayout* layout) auto lv_line = window_create(lvobj); return new Line(this, lv_line, layout); } - -void FormGroup::removeField(FormField * field) -{ - FormField* prev = field->getPreviousField(); - FormField* next = field->getNextField(); - - if (prev) { prev->setNextField(next); } - if (next) { next->setPreviousField(prev); } - - if (first == field) { - if (prev && (prev != field)) first = prev; - else if (next && (next != field)) first = next; - else first = nullptr; - } - - if (last == field) { - if (next && (next != field)) last = next; - else if (prev && (prev != field)) last = prev; - else last = nullptr; - } -} - -void FormGroup::addField(FormField * field) -{ - if (field->getWindowFlags() & FORM_DETACHED) - return; - - if (last) - link(last, field); - last = field; - if (!first) - first = field; - - if (WRAP_FORM_FIELDS_WITHIN_PAGE) { - if (previous && (windowFlags & FORM_FORWARD_FOCUS)) { - last->setNextField(this); - link(previous, first); - } - else { - link(last, first); - } - } - else { - if (windowFlags & FORM_FORWARD_FOCUS) { - last->setNextField(this); - if (previous) - link(previous, first); - } - } -} - -void FormGroup::setFocus(uint8_t flag, Window * from) -{ - TRACE_WINDOWS("%s setFocus(%d)", getWindowDebugString("FormGroup").c_str(), flag); - - if (windowFlags & FORM_FORWARD_FOCUS) { - switch (flag) { - case SET_FOCUS_BACKWARD: - if (from && from->isChild(first)) { - if (previous == this) { - last->setFocus(SET_FOCUS_BACKWARD, this); - } - else if (previous) { - previous->setFocus(SET_FOCUS_BACKWARD, this); - } - } - else { - if (last) { - last->setFocus(SET_FOCUS_BACKWARD, this); - } - else if (previous) { - previous->setFocus(SET_FOCUS_BACKWARD, this); - } - } - break; - - case SET_FOCUS_FIRST: - clearFocus(); - // no break; - - case SET_FOCUS_FORWARD: - if (from && from->isChild(this)) { - if (next == this) { - if (first) - first->setFocus(SET_FOCUS_FORWARD, this); - } - else if (next) { - next->setFocus(SET_FOCUS_FORWARD, this); - } - } - else { - if (first) { - first->setFocus(SET_FOCUS_FORWARD, this); - } - else if (next) { - next->setFocus(SET_FOCUS_FORWARD, this); - } - } - break; - - default: - if (from == previous) { - if (first) { - first->setFocus(SET_FOCUS_DEFAULT); - } - else { - clearFocus(); - focusWindow = this; - } - } - else if (next) { - next->setFocus(SET_FOCUS_FORWARD); - } - else { - clearFocus(); - focusWindow = this; - } - break; - } - } - else if (!(windowFlags & NO_FOCUS)) { - FormField::setFocus(flag, from); - } -} - -#if defined(HARDWARE_KEYS) -void FormGroup::onEvent(event_t event) -{ - TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString("FormGroup").c_str(), event); - - FormField::onEvent(event); -} -#endif diff --git a/radio/src/thirdparty/libopenui/src/form.h b/radio/src/thirdparty/libopenui/src/form.h index 8ecc1e617..71a09571e 100644 --- a/radio/src/thirdparty/libopenui/src/form.h +++ b/radio/src/thirdparty/libopenui/src/form.h @@ -36,9 +36,7 @@ class FormField : public Window virtual void changeEnd(bool forceChanged = false) { - if (changeHandler) { - changeHandler(); - } + if (changeHandler) { changeHandler(); } } void setChangeHandler(std::function handler) @@ -51,33 +49,10 @@ class FormField : public Window backgroundHandler = std::move(handler); } - inline void setNextField(FormField *field) { next = field; } - - inline void setPreviousField(FormField *field) { previous = field; } - - inline FormField *getPreviousField() { return previous; } - - inline FormField *getNextField() { return next; } - inline bool isEditMode() const { return editMode; } + virtual void setEditMode(bool newEditMode); - virtual void setEditMode(bool newEditMode) - { - editMode = newEditMode; - - // if (lvobj != nullptr) { - // lv_group_t *grp = (lv_group_t *)lv_obj_get_group(lvobj); - // if (grp != nullptr) lv_group_set_editing(grp, editMode); - // } - - if (editMode && lvobj != nullptr) { - lv_obj_add_state(lvobj, LV_STATE_EDITED); - } else if (lvobj != nullptr) { - lv_obj_clear_state(lvobj, LV_STATE_EDITED); - } - invalidate(); - } - + // TODO: replace with LVGL flags void enable(bool value = true) { enabled = value; @@ -87,45 +62,26 @@ class FormField : public Window bool isEnabled() const { return enabled; } void disable() { enable(false); } - void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, - Window *from = nullptr) override; - void onFocusLost() override { setEditMode(false); Window::onFocusLost(); } - inline static void link(FormField *previous, FormField *next) - { - previous->setNextField(next); - next->setPreviousField(previous); - } - -#if defined(HARDWARE_KEYS) - void onEvent(event_t event) override; -#endif - + void onClicked() override; + void onCancel() override; + protected: - FormField *next = nullptr; - FormField *previous = nullptr; bool editMode = false; bool enabled = true; std::function changeHandler = nullptr; std::function backgroundHandler = nullptr; }; -class FieldContainer +class FormGroup : public Window { public: - virtual void addField(FormField *field) = 0; - virtual void removeField(FormField *field) = 0; -}; - -class FormGroup : public FormField, public FieldContainer -{ - public: - class Line : public Window, public FieldContainer + class Line : public Window { FlexGridLayout* layout; FormGroup* group; @@ -138,8 +94,6 @@ class FormGroup : public FormField, public FieldContainer protected: void addChild(Window* window) override; - void addField(FormField *field) override; - void removeField(FormField *field) override; }; FormGroup(Window *parent, const rect_t &rect, WindowFlags windowflags = 0, @@ -149,30 +103,8 @@ class FormGroup : public FormField, public FieldContainer std::string getName() const override { return "FormGroup"; } #endif - void clear(); - void setFlexLayout(lv_flex_flow_t flow = LV_FLEX_FLOW_COLUMN, lv_coord_t padding = 0); Line* newLine(FlexGridLayout* layout = nullptr); - - void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, - Window *from = nullptr) override; - - void addField(FormField *field) override; - void removeField(FormField *field) override; - - void setFirstField(FormField *field) { first = field; } - void setLastField(FormField *field) { last = field; } - FormField *getFirstField() const { return first; } - FormField *getLastField() const { return last; } - - - protected: - FormField *first = nullptr; - FormField *last = nullptr; - -#if defined(HARDWARE_KEYS) - void onEvent(event_t event) override; -#endif }; class FormWindow : public FormGroup diff --git a/radio/src/thirdparty/libopenui/src/keyboard_base.cpp b/radio/src/thirdparty/libopenui/src/keyboard_base.cpp index 1ac4a3b24..3017c3208 100644 --- a/radio/src/thirdparty/libopenui/src/keyboard_base.cpp +++ b/radio/src/thirdparty/libopenui/src/keyboard_base.cpp @@ -17,6 +17,8 @@ * Lesser General Public License for more details. */ #include "keyboard_base.h" + +#include "form.h" #include "mainwindow.h" Keyboard * Keyboard::activeKeyboard = nullptr; @@ -24,28 +26,66 @@ Keyboard * Keyboard::activeKeyboard = nullptr; static void keyboard_event_cb(lv_event_t * e) { auto code = lv_event_get_code(e); - Keyboard *kb = (Keyboard *) lv_event_get_user_data(e); if (code == LV_EVENT_READY) { pushEvent(EVT_VIRTUAL_KEY('\n')); - kb->hide(); + Keyboard::hide(); + } else if (code == LV_EVENT_CANCEL) { + Keyboard::hide(); + } else if (code == LV_EVENT_KEY) { + int32_t c = *((int32_t *)lv_event_get_param(e)); + if (c == LV_KEY_ESC) { + Keyboard::hide(); + } + } +} + +static void field_focus_leave(lv_event_t* e) +{ + Keyboard::hide(); +} + +static void _assign_lv_group(lv_group_t* g) +{ + // associate it with all input devices + lv_indev_t* indev = lv_indev_get_next(NULL); + while (indev) { + lv_indev_set_group(indev, g); + indev = lv_indev_get_next(indev); } } Keyboard::Keyboard(coord_t height) : - FormWindow(MainWindow::instance(), {0, LCD_H - height, LCD_W, height}, OPAQUE) + Window(MainWindow::instance(), {0, LCD_H - height, LCD_W, height}, OPAQUE) { // set the background of the window and opacity to 100% lv_obj_set_parent(lvobj, lv_layer_top()); // the keyboard is always on top lv_obj_set_style_bg_color(lvobj, lv_color_make(0xE0, 0xE0, 0xE0), LV_PART_MAIN); lv_obj_set_style_bg_opa(lvobj, LV_OPA_100, LV_PART_MAIN); - keyboard = lv_keyboard_create(this->getLvObj()); + // use a separate group for the keyboard + group = lv_group_create(); + lv_group_set_editing(group, true); + + auto old_g = lv_group_get_default(); + lv_group_set_default(group); + + keyboard = lv_keyboard_create(lvobj); + lv_group_set_default(old_g); + lv_obj_add_event_cb(keyboard, keyboard_event_cb, LV_EVENT_ALL, this); + lv_obj_set_pos(keyboard, 0, 0); lv_obj_set_size(keyboard, LCD_W, height); + + // TODO: really needed ??? lv_obj_clear_flag(keyboard, LV_OBJ_FLAG_HIDDEN); } +Keyboard::~Keyboard() +{ + if (group) lv_group_del(group); +} + void Keyboard::clearField() { TRACE("CLEAR FIELD"); @@ -62,10 +102,16 @@ void Keyboard::clearField() } if (field) { + // restore field's group + auto obj = field->getLvObj(); + lv_obj_remove_event_cb(obj, field_focus_leave); + lv_group_t* g = (lv_group_t*)lv_obj_get_group(obj); + if (g) _assign_lv_group(g); + field->setEditMode(false); field->changeEnd(); field = nullptr; - } + } } void Keyboard::hide() @@ -81,7 +127,7 @@ bool Keyboard::attachKeyboard() { if (activeKeyboard) { if (activeKeyboard == this) return false; - activeKeyboard->clearField(); + hide(); } activeKeyboard = this; @@ -113,8 +159,11 @@ void Keyboard::setField(FormField* newField) invalidate(); newField->setEditMode(true); - lv_keyboard_set_textarea(keyboard, newField->getLvObj()); - + + lv_keyboard_set_textarea(keyboard, obj); + lv_obj_add_event_cb(obj, field_focus_leave, LV_EVENT_DEFOCUSED, nullptr); + _assign_lv_group(group); + field = newField; } } diff --git a/radio/src/thirdparty/libopenui/src/keyboard_base.h b/radio/src/thirdparty/libopenui/src/keyboard_base.h index 4ced4488c..8a599dc45 100644 --- a/radio/src/thirdparty/libopenui/src/keyboard_base.h +++ b/radio/src/thirdparty/libopenui/src/keyboard_base.h @@ -19,24 +19,29 @@ #pragma once -#include "form.h" +#include "window.h" -class Keyboard: public FormWindow +class FormField; + +class Keyboard : public Window { - public: - explicit Keyboard(coord_t height); - void clearField(); - static void hide(); + public: + explicit Keyboard(coord_t height); + ~Keyboard(); - protected: - static Keyboard * activeKeyboard; - lv_obj_t * keyboard = nullptr; + void clearField(); + static void hide(); - FormField *field = nullptr; - Window *fieldContainer = nullptr; - lv_coord_t scroll_pos = 0; + protected: + static Keyboard *activeKeyboard; - void setField(FormField *newField); - bool attachKeyboard(); + lv_group_t* group = nullptr; + lv_obj_t* keyboard = nullptr; + + FormField* field = nullptr; + Window* fieldContainer = nullptr; + lv_coord_t scroll_pos = 0; + + void setField(FormField* newField); + bool attachKeyboard(); }; - diff --git a/radio/src/thirdparty/libopenui/src/keyboard_number.cpp b/radio/src/thirdparty/libopenui/src/keyboard_number.cpp index b55c9f174..b23ef7f33 100644 --- a/radio/src/thirdparty/libopenui/src/keyboard_number.cpp +++ b/radio/src/thirdparty/libopenui/src/keyboard_number.cpp @@ -18,64 +18,63 @@ */ #include "keyboard_number.h" -#include "button.h" +#include "numberedit.h" constexpr coord_t KEYBOARD_HEIGHT = 90; NumberKeyboard * NumberKeyboard::_instance = nullptr; +static const char* number_kb_map[] = { + "<<", "-", "+", ">>", "\n", + "MIN", "DEF", "+/-", "MAX", "" +}; + +#define LV_KB_BTN(width) LV_BTNMATRIX_CTRL_POPOVER | width +#define LV_KB_CTRL(width) LV_KEYBOARD_CTRL_BTN_FLAGS | width + +static const lv_btnmatrix_ctrl_t number_kb_ctrl_map[] = { + LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), + LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_CTRL(4), LV_KB_BTN(4) +}; + +static void on_key(lv_event_t* e) +{ + lv_obj_t * obj = lv_event_get_target(e); + NumberEdit* edit = (NumberEdit*)lv_event_get_user_data(e); + if (!obj || !edit) return; + + uint16_t btn_id = lv_btnmatrix_get_selected_btn(obj); + if(btn_id == LV_BTNMATRIX_BTN_NONE) return; + + const char * txt = lv_btnmatrix_get_btn_text(obj, lv_btnmatrix_get_selected_btn(obj)); + if(txt == NULL) return; + + if (strcmp(txt, "<<") == 0) { + edit->onEvent(EVT_VIRTUAL_KEY_BACKWARD); + } else if (strcmp(txt, "-") == 0) { + edit->onEvent(EVT_VIRTUAL_KEY_MINUS); + } else if (strcmp(txt, "+") == 0) { + edit->onEvent(EVT_VIRTUAL_KEY_PLUS); + } else if (strcmp(txt, ">>") == 0) { + edit->onEvent(EVT_VIRTUAL_KEY_FORWARD); + } else if (strcmp(txt, "MIN") == 0) { + edit->onEvent(EVT_VIRTUAL_KEY_MIN); + } else if (strcmp(txt, "DEF") == 0) { + edit->onEvent(EVT_VIRTUAL_KEY_DEFAULT); + } else if (strcmp(txt, "MAX") == 0) { + edit->onEvent(EVT_VIRTUAL_KEY_MAX); + } else if (strcmp(txt, "+/-") == 0) { + edit->onEvent(EVT_VIRTUAL_KEY_SIGN); + } +} + NumberKeyboard::NumberKeyboard() : Keyboard(KEYBOARD_HEIGHT) { - // ToDo: for now we are still using the old keyboard - lv_obj_add_flag(keyboard, LV_OBJ_FLAG_HIDDEN); + // setup custom keyboard + lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1, + number_kb_map, number_kb_ctrl_map); - new TextButton(this, {LCD_W / 2 - 115, 10, 50, 30}, "<<", - [=]() -> uint8_t { - pushEvent(EVT_VIRTUAL_KEY_BACKWARD); - return 0; - }, BUTTON_BACKGROUND | OPAQUE | NO_FOCUS); - - new TextButton(this, {LCD_W / 2 - 55, 10, 50, 30}, "-", - [=]() -> uint8_t { - pushEvent(EVT_VIRTUAL_KEY_MINUS); - return 0; - }, BUTTON_BACKGROUND | OPAQUE | NO_FOCUS); - - new TextButton(this, {LCD_W / 2 + 5, 10, 50, 30}, "+", - [=]() -> uint8_t { - pushEvent(EVT_VIRTUAL_KEY_PLUS); - return 0; - }, BUTTON_BACKGROUND | OPAQUE | NO_FOCUS); - - new TextButton(this, {LCD_W / 2 + 65, 10, 50, 30}, ">>", - [=]() -> uint8_t { - pushEvent(EVT_VIRTUAL_KEY_FORWARD); - return 0; - }, BUTTON_BACKGROUND | OPAQUE | NO_FOCUS); - - new TextButton(this, {LCD_W / 2 - 115, 50, 50, 30}, "MIN", - [=]() -> uint8_t { - pushEvent(EVT_VIRTUAL_KEY_MIN); - return 0; - }, BUTTON_BACKGROUND | OPAQUE | NO_FOCUS); - - new TextButton(this, {LCD_W / 2 + 65, 50, 50, 30}, "MAX", - [=]() -> uint8_t { - pushEvent(EVT_VIRTUAL_KEY_MAX); - return 0; - }, BUTTON_BACKGROUND | OPAQUE | NO_FOCUS); - - new TextButton(this, { LCD_W/2 - 55, 50, 50, 30 }, "DEF", - [=]() -> uint8_t { - pushEvent(EVT_VIRTUAL_KEY_DEFAULT); - return 0; - }, BUTTON_BACKGROUND | OPAQUE | NO_FOCUS); - - new TextButton(this, { LCD_W/2 + 5, 50, 50, 30 }, "+/-", - [=]() -> uint8_t { - pushEvent(EVT_VIRTUAL_KEY_SIGN); - return 0; - }, BUTTON_BACKGROUND | OPAQUE | NO_FOCUS); + lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1); } NumberKeyboard::~NumberKeyboard() @@ -83,3 +82,18 @@ NumberKeyboard::~NumberKeyboard() _instance = nullptr; } +void NumberKeyboard::show(NumberEdit* field) +{ + if (!_instance) _instance = new NumberKeyboard(); + + lv_obj_clear_flag(_instance->lvobj, LV_OBJ_FLAG_HIDDEN); + lv_obj_clear_flag(_instance->keyboard, LV_OBJ_FLAG_HIDDEN); + + _instance->setField(field); + + auto kb = _instance->keyboard; + lv_keyboard_set_textarea(kb, nullptr); + + lv_obj_remove_event_cb(kb, on_key); + lv_obj_add_event_cb(kb, on_key, LV_EVENT_VALUE_CHANGED, field); +} diff --git a/radio/src/thirdparty/libopenui/src/keyboard_number.h b/radio/src/thirdparty/libopenui/src/keyboard_number.h index bd1f764f5..859cd9f7a 100644 --- a/radio/src/thirdparty/libopenui/src/keyboard_number.h +++ b/radio/src/thirdparty/libopenui/src/keyboard_number.h @@ -21,37 +21,20 @@ #include "keyboard_base.h" -class NumberKeyboard : public Keyboard { - public: - NumberKeyboard(); +class NumberEdit; - ~NumberKeyboard() override; +class NumberKeyboard : public Keyboard +{ + public: + NumberKeyboard(); + ~NumberKeyboard() override; #if defined(DEBUG_WINDOWS) - std::string getName() const override - { - return "NumberKeyboard"; - } + std::string getName() const override { return "NumberKeyboard"; } #endif - static void show(FormField * field) - { - if (!_instance) - _instance = new NumberKeyboard(); - // else - // lv_obj_clear_flag(_instance->keyboard, LV_OBJ_FLAG_HIDDEN); + static void show(NumberEdit* field); - // lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_NUMBER); - - lv_obj_clear_flag(_instance->lvobj, LV_OBJ_FLAG_HIDDEN); - // lv_obj_clear_flag(_instance->keyboard, LV_OBJ_FLAG_HIDDEN); - lv_keyboard_set_mode(_instance->keyboard, LV_KEYBOARD_MODE_NUMBER); - lv_obj_move_foreground(_instance->getLvObj()); - - _instance->setField(field); - } - - protected: - static NumberKeyboard * _instance; + protected: + static NumberKeyboard* _instance; }; - diff --git a/radio/src/thirdparty/libopenui/src/keyboard_text.cpp b/radio/src/thirdparty/libopenui/src/keyboard_text.cpp index a449a6cad..2c1b2569b 100644 --- a/radio/src/thirdparty/libopenui/src/keyboard_text.cpp +++ b/radio/src/thirdparty/libopenui/src/keyboard_text.cpp @@ -39,3 +39,14 @@ void TextKeyboard::onEvent(event_t event) { } #endif + +void TextKeyboard::show(FormField* field) +{ + if (!_instance) _instance = new TextKeyboard(); + + lv_obj_clear_flag(_instance->lvobj, LV_OBJ_FLAG_HIDDEN); + lv_obj_clear_flag(_instance->keyboard, LV_OBJ_FLAG_HIDDEN); + lv_keyboard_set_mode(_instance->keyboard, LV_KEYBOARD_MODE_TEXT_LOWER); + + _instance->setField(field); +} diff --git a/radio/src/thirdparty/libopenui/src/keyboard_text.h b/radio/src/thirdparty/libopenui/src/keyboard_text.h index c4e4e8e50..375f0efc4 100644 --- a/radio/src/thirdparty/libopenui/src/keyboard_text.h +++ b/radio/src/thirdparty/libopenui/src/keyboard_text.h @@ -36,36 +36,22 @@ #define KEYBOARD_ENTER_WIDTH 80 #define KEYBOARD_BITMAP_WIDTH 45 -class TextKeyboard : public Keyboard { - public: - TextKeyboard(); - - ~TextKeyboard() override; +class TextKeyboard : public Keyboard +{ + public: + TextKeyboard(); + ~TextKeyboard() override; #if defined(DEBUG_WINDOWS) - std::string getName() const override - { - return "TextKeyboard"; - } + std::string getName() const override { return "TextKeyboard"; } #endif - static void show(FormField * field) - { - if (!_instance) - _instance = new TextKeyboard(); + static void show(FormField* field); - lv_obj_clear_flag(_instance->lvobj, LV_OBJ_FLAG_HIDDEN); - lv_obj_clear_flag(_instance->keyboard, LV_OBJ_FLAG_HIDDEN); - lv_keyboard_set_mode(_instance->keyboard, LV_KEYBOARD_MODE_TEXT_LOWER); - _instance->setField(field); - } - - protected: + protected: #if defined(HARDWARE_KEYS) - void onEvent(event_t event) override; + void onEvent(event_t event) override; #endif - static TextKeyboard * _instance; - // const char * const * layout; + static TextKeyboard* _instance; }; - diff --git a/radio/src/thirdparty/libopenui/src/layer.cpp b/radio/src/thirdparty/libopenui/src/layer.cpp index b40c72bad..98c441cac 100644 --- a/radio/src/thirdparty/libopenui/src/layer.cpp +++ b/radio/src/thirdparty/libopenui/src/layer.cpp @@ -20,3 +20,67 @@ #include "layer.h" std::list Layer::stack; + +Layer::Layer(Window* w, lv_group_t* g) : window(w), group(g) {} +Layer::~Layer() { lv_group_del(group); } + +static void _assign_lv_group(lv_group_t* g) +{ + lv_group_set_default(g); + + // associate it with all input devices + lv_indev_t* indev = lv_indev_get_next(NULL); + while (indev) { + lv_indev_set_group(indev, g); + indev = lv_indev_get_next(indev); + } +} + +void Layer::push(Window* w) +{ + // create a new group + auto g = lv_group_create(); + _assign_lv_group(g); + + // and store + stack.emplace_back(w, g); +} + +void Layer::pop(Window* w) +{ + if (stack.empty()) return; + + if (back() == w) { + stack.pop_back(); + } else { + for (auto layer = stack.crbegin(); layer != stack.crend(); layer++) { + if (layer->window == w) { + stack.erase(layer.base()); + return; + } + } + } + + if (!stack.empty()) { + lv_group_t* g = stack.back().group; + _assign_lv_group(g); + } else { + lv_group_set_default(NULL); + } +} + +Window* Layer::back() +{ + if (stack.empty()) return nullptr; + return stack.back().window; +} + +Window* Layer::getFirstOpaque() +{ + for (auto layer = stack.crbegin(); layer != stack.crend(); layer++) { + auto w = layer->window; + if (w && (w->getWindowFlags() & OPAQUE)) return w; + } + + return nullptr; +} diff --git a/radio/src/thirdparty/libopenui/src/layer.h b/radio/src/thirdparty/libopenui/src/layer.h index f66303ba9..873138855 100644 --- a/radio/src/thirdparty/libopenui/src/layer.h +++ b/radio/src/thirdparty/libopenui/src/layer.h @@ -20,69 +20,21 @@ #pragma once #include "window.h" -extern lv_obj_t * canvas; class Layer { - public: - explicit Layer(Window * main): - main(main) - { - } + static std::list stack; - Window * main; - Window * focus = nullptr; + Window* window; + lv_group_t* group; - static std::list stack; + public: + explicit Layer(Window* w, lv_group_t* g); + ~Layer(); - static void push(Window * window) - { + static void push(Window* window); + static void pop(Window* window); - if (!stack.empty()) { - Layer & parentLayer = stack.back(); - parentLayer.focus = Window::getFocus(); - } - - - stack.emplace_back(Layer(window)); - -#if defined(DEBUG_WINDOWS) - TRACE_WINDOWS("New layer added for %s (%d layers)", window->getWindowDebugString().c_str(), stack.size()); - for (auto & layer: stack) { - TRACE_WINDOWS(" - %s (focus=%s)", layer.main->getWindowDebugString().c_str(), layer.focus ? layer.focus->getWindowDebugString().c_str() : "---"); - } -#endif - } - - static void pop(Window * window) - { - if (stack.back().main == window) { - stack.pop_back(); - const auto & back = stack.back(); - if (back.focus) { - back.focus->setFocus(SET_FOCUS_DEFAULT); - } - } - else { - // TODO it would be better to do it in reverse order - for (auto it = stack.begin(); it != stack.end(); it++) { - if (it->main == window) { - stack.erase(it); - break; - } - } - } - -#if defined(DEBUG_WINDOWS) - TRACE_WINDOWS("Layer removed for %s (%d layers)", window->getWindowDebugString().c_str(), stack.size()); - for (auto & layer: stack) { - TRACE_WINDOWS(" - %s (focus=%s)", layer.main->getWindowDebugString().c_str(), layer.focus ? layer.focus->getWindowDebugString().c_str() : "---"); - } -#endif - } - - static Window* back() - { - return stack.back().main; - } + static Window* back(); + static Window* getFirstOpaque(); }; diff --git a/radio/src/thirdparty/libopenui/src/mainwindow.cpp b/radio/src/thirdparty/libopenui/src/mainwindow.cpp index 3511d1d4f..8efe7a72e 100644 --- a/radio/src/thirdparty/libopenui/src/mainwindow.cpp +++ b/radio/src/thirdparty/libopenui/src/mainwindow.cpp @@ -36,7 +36,7 @@ MainWindow::MainWindow() : Window(nullptr, {0, 0, LCD_W, LCD_H}, OPAQUE), invalidatedRect(rect) { - Layer::push(this); + // Layer::push(this); } void MainWindow::emptyTrash() @@ -98,21 +98,10 @@ void MainWindow::run(bool trash) { auto start = ticksNow(); - // KLK: removed for now. This is now - // called from lvgl event processing when - // necessary - auto layer = Layer::stack.rbegin(); - while (layer != Layer::stack.rend()) { - if (layer->main && (layer->main->getWindowFlags() & OPAQUE)) { - layer->main->checkEvents(); - break; - } - ++layer; - } + auto opaque = Layer::getFirstOpaque(); + if (opaque) opaque->checkEvents(); - if (trash) { - emptyTrash(); - } + if (trash) emptyTrash(); auto delta = ticksNow() - start; if (delta > 10 * SYSTEM_TICKS_1MS) { diff --git a/radio/src/thirdparty/libopenui/src/menu.cpp b/radio/src/thirdparty/libopenui/src/menu.cpp index a880947b5..a97d5dc28 100644 --- a/radio/src/thirdparty/libopenui/src/menu.cpp +++ b/radio/src/thirdparty/libopenui/src/menu.cpp @@ -60,6 +60,9 @@ MenuBody::MenuBody(Window * parent, const rect_t & rect): { setColumnCount(1); setColumnWidth(0, rect.w); + + lv_group_t* g = (lv_group_t*)lv_obj_get_group(lvobj); + if (g) { lv_group_set_editing(g, true); } } void MenuBody::addLine(const std::string &text, std::function onPress, @@ -176,49 +179,11 @@ void MenuBody::selectNext(MENU_DIRECTION direction) } -#if defined(HARDWARE_KEYS) void MenuBody::onEvent(event_t event) { - // TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event); - - // if (event == EVT_ROTARY_RIGHT) { - // if (!lines.empty()) { - // selectNext(DIRECTION_UP); - // onKeyPress(); - // } - // } - // else if (event == EVT_ROTARY_LEFT) { - // if (!lines.empty()) { - // selectNext(DIRECTION_DOWN); - // onKeyPress(); - // } - // } - // else if (event == EVT_KEY_BREAK(KEY_ENTER)) { - // if (!lines.empty()) { - // onKeyPress(); - // if (selectedIndex < 0) { - // setIndex(0); - // } - // else { - // Menu * menu = getParentMenu(); - // if (menu->multiple) { - // lines[selectedIndex].onPress(); - // menu->invalidate(); - // } - // else { - // lines[selectedIndex].onPress(); - // menu->deleteLater(); - // } - // } - // } - // } - // else +#if defined(HARDWARE_KEYS) if (event == EVT_KEY_BREAK(KEY_EXIT)) { - onKeyPress(); - if (onCancel) { - onCancel(); - } - Window::onEvent(event); + onCancel(); } else { TableField::onEvent(event); @@ -226,12 +191,18 @@ void MenuBody::onEvent(event_t event) } #endif +void MenuBody::onCancel() +{ + if(_onCancel) _onCancel(); + TableField::onCancel(); +} + MenuWindowContent::MenuWindowContent(Menu* parent) : ModalWindowContent(parent, {(LCD_W - MENUS_WIDTH) / 2, (LCD_H - MENUS_WIDTH) / 2, MENUS_WIDTH, 0}), body(this, {0, 0, width(), height()}) { - body.setFocus(SET_FOCUS_DEFAULT); + // body.setFocus(SET_FOCUS_DEFAULT); lv_obj_set_style_bg_opa(lvobj, LV_OPA_100, LV_PART_MAIN); } @@ -305,19 +276,17 @@ void Menu::removeLines() updatePosition(); } -#if defined(HARDWARE_KEYS) void Menu::onEvent(event_t event) { +#if defined(HARDWARE_KEYS) if (toolbar && (event == EVT_KEY_BREAK(KEY_PGDN) || event == EVT_KEY_LONG(KEY_PGDN) || event == EVT_KEY_BREAK(KEY_PGUP))) { toolbar->onEvent(event); } - else if (event == EVT_KEY_BREAK(KEY_EXIT)) { - deleteLater(); - } - else if (event == EVT_KEY_BREAK(KEY_ENTER) && !multiple) { - deleteLater(); - } -} #endif +} +void Menu::onCancel() +{ + deleteLater(); +} diff --git a/radio/src/thirdparty/libopenui/src/menu.h b/radio/src/thirdparty/libopenui/src/menu.h index 36b7fc017..b765f681c 100644 --- a/radio/src/thirdparty/libopenui/src/menu.h +++ b/radio/src/thirdparty/libopenui/src/menu.h @@ -92,9 +92,8 @@ class MenuBody: public TableField return lines.size(); } -#if defined(HARDWARE_KEYS) void onEvent(event_t event) override; -#endif + void onCancel() override; void addLine(const std::string &text, std::function onPress, std::function isChecked); @@ -107,7 +106,7 @@ class MenuBody: public TableField void setCancelHandler(std::function handler) { - onCancel = std::move(handler); + _onCancel = std::move(handler); } coord_t getContentHeight(); @@ -124,7 +123,7 @@ class MenuBody: public TableField std::vector lines; int selectedIndex = 0; - std::function onCancel; + std::function _onCancel; inline Menu * getParentMenu(); }; @@ -175,10 +174,10 @@ class Menu: public ModalWindow waitHandler = std::move(handler); } - void setFocusBody(uint8_t flag = SET_FOCUS_DEFAULT) - { - content->body.setFocus(flag); - } + // void setFocusBody(uint8_t flag = SET_FOCUS_DEFAULT) + // { + // content->body.setFocus(flag); + // } void setToolbar(Window * window); @@ -210,9 +209,8 @@ class Menu: public ModalWindow content->body.setIndex(index); } -#if defined(HARDWARE_KEYS) void onEvent(event_t event) override; -#endif + void onCancel() override; void checkEvents() override { diff --git a/radio/src/thirdparty/libopenui/src/menutoolbar.h b/radio/src/thirdparty/libopenui/src/menutoolbar.h index b0d3d39c5..3e1236e06 100644 --- a/radio/src/thirdparty/libopenui/src/menutoolbar.h +++ b/radio/src/thirdparty/libopenui/src/menutoolbar.h @@ -28,11 +28,7 @@ int getFirstAvailable(int min, int max, std::functionisValueAvailable class MenuToolbarButton: public Button { public: MenuToolbarButton(FormGroup * window, const rect_t & rect, const char* picto): -#if defined(HARDWARE_TOUCH) Button(window, rect, nullptr), -#else - Button(window, rect, nullptr), -#endif picto(picto) { } @@ -64,36 +60,36 @@ class MenuToolbar: public FormGroup { #if defined(HARDWARE_KEYS) void onEvent(event_t event) override { - if (event == EVT_KEY_BREAK(KEY_PGDN) || event == EVT_KEY_LONG(KEY_PGDN) || event == EVT_KEY_BREAK(KEY_PGUP)) { -#if defined(HARDWARE_TOUCH) - if (current != children.end()) { - static_cast(*current)->onTouchEnd(0,0); - } -#endif - current = IS_KEY_LONG(event) || event == EVT_KEY_BREAK(KEY_PGUP) ? - current == children.end() ? - --current: - current == children.begin() ? - children.end() : - --current : - current == children.end() ? - children.begin() : - ++current; +// if (event == EVT_KEY_BREAK(KEY_PGDN) || event == EVT_KEY_LONG(KEY_PGDN) || event == EVT_KEY_BREAK(KEY_PGUP)) { +// #if defined(HARDWARE_TOUCH) +// if (current != children.end()) { +// static_cast(*current)->onTouchEnd(0,0); +// } +// #endif +// current = IS_KEY_LONG(event) || event == EVT_KEY_BREAK(KEY_PGUP) ? +// current == children.end() ? +// --current: +// current == children.begin() ? +// children.end() : +// --current : +// current == children.end() ? +// children.begin() : +// ++current; - if (IS_KEY_LONG(event)) - killEvents(event); +// if (IS_KEY_LONG(event)) +// killEvents(event); - if (current != children.end()) { - auto button = static_cast(*current); -#if defined(HARDWARE_TOUCH) - button->onTouchEnd(0,0); -#endif - scrollTo(button); - } - else { - lv_obj_scroll_to_y(lvobj, 0, LV_ANIM_OFF); - } - } +// if (current != children.end()) { +// auto button = static_cast(*current); +// #if defined(HARDWARE_TOUCH) +// button->onTouchEnd(0,0); +// #endif +// scrollTo(button); +// } +// else { +// lv_obj_scroll_to_y(lvobj, 0, LV_ANIM_OFF); +// } +// } } #endif @@ -139,7 +135,7 @@ class MenuToolbar: public FormGroup { } else { choice->fillMenu(menu, val); } - menu->setFocusBody(); + // menu->setFocusBody(); // set current for page key procesing current = std::find_if(children.begin(), children.end(), [button](Window *o) { return o == button; }); diff --git a/radio/src/thirdparty/libopenui/src/modal_window.cpp b/radio/src/thirdparty/libopenui/src/modal_window.cpp index ab5875050..055c4ec0d 100644 --- a/radio/src/thirdparty/libopenui/src/modal_window.cpp +++ b/radio/src/thirdparty/libopenui/src/modal_window.cpp @@ -19,6 +19,7 @@ #include "modal_window.h" +#include "keyboard_base.h" #include "font.h" #include "layer.h" @@ -26,30 +27,25 @@ ModalWindow::ModalWindow(Window * parent, bool closeWhenClickOutside): Window(parent->getFullScreenWindow(), {0, 0, LCD_W, LCD_H}), closeWhenClickOutside(closeWhenClickOutside) { + Layer::push(this); lv_obj_set_style_bg_color(lvobj, lv_color_black(), LV_PART_MAIN); lv_obj_set_style_bg_opa(lvobj, LV_OPA_50, LV_PART_MAIN); - Layer::push(this); } void ModalWindow::deleteLater(bool detach, bool trash) { - if (_deleted) - return; - - Window::deleteLater(detach, trash); + if (_deleted) return; Layer::pop(this); + Window::deleteLater(detach, trash); } -#if defined(HARDWARE_TOUCH) -bool ModalWindow::onTouchEnd(coord_t x, coord_t y) +void ModalWindow::onClicked() { if (closeWhenClickOutside) { onKeyPress(); deleteLater(); } - return true; } -#endif ModalWindowContent::ModalWindowContent(ModalWindow* parent, const rect_t& rect) : @@ -57,6 +53,11 @@ ModalWindowContent::ModalWindowContent(ModalWindow* parent, { } +void ModalWindowContent::onClicked() +{ + Keyboard::hide(); +} + void ModalWindowContent::setTitle(const std::string& text) { if (!title) { diff --git a/radio/src/thirdparty/libopenui/src/modal_window.h b/radio/src/thirdparty/libopenui/src/modal_window.h index 381c96ea7..09864cf87 100644 --- a/radio/src/thirdparty/libopenui/src/modal_window.h +++ b/radio/src/thirdparty/libopenui/src/modal_window.h @@ -21,49 +21,41 @@ #include "window.h" -class ModalWindow: public Window +class ModalWindow : public Window { - public: - explicit ModalWindow(Window * parent, bool closeWhenClickOutside = false); + public: + explicit ModalWindow(Window* parent, bool closeWhenClickOutside = false); #if defined(DEBUG_WINDOWS) - std::string getName() const override - { - return "ModalWindow"; - } + std::string getName() const override { return "ModalWindow"; } #endif - void deleteLater(bool detach = true, bool trash = true) override; // NOLINT(google-default-arguments) + void setCloseWhenClickOutside(bool value = true) + { + closeWhenClickOutside = value; + } -#if defined(HARDWARE_TOUCH) - bool onTouchEnd(coord_t x, coord_t y) override; -#endif + void onClicked() override; + void deleteLater(bool detach = true, bool trash = true) override; - void setCloseWhenClickOutside(bool value = true) - { - closeWhenClickOutside = value; - } - - protected: - bool closeWhenClickOutside; + protected: + bool closeWhenClickOutside; }; -class ModalWindowContent: public Window +class ModalWindowContent : public Window { - public: - explicit ModalWindowContent(ModalWindow * parent, const rect_t & rect); + public: + explicit ModalWindowContent(ModalWindow* parent, const rect_t& rect); #if defined(DEBUG_WINDOWS) - std::string getName() const override - { - return "ModalWindowContent"; - } + std::string getName() const override { return "ModalWindowContent"; } #endif - void setTitle(const std::string& text); - std::string getTitle() const; + void setTitle(const std::string& text); + std::string getTitle() const; - protected: - lv_obj_t* title = nullptr; + void onClicked() override; + + protected: + lv_obj_t* title = nullptr; }; - diff --git a/radio/src/thirdparty/libopenui/src/numberedit.cpp b/radio/src/thirdparty/libopenui/src/numberedit.cpp index 7d7e03ee2..10f2af558 100644 --- a/radio/src/thirdparty/libopenui/src/numberedit.cpp +++ b/radio/src/thirdparty/libopenui/src/numberedit.cpp @@ -26,32 +26,18 @@ static void numberedit_cb(lv_event_t* e) { - lv_event_code_t code = lv_event_get_code(e); - if (code == LV_EVENT_DELETE) return; - NumberEdit* numEdit = (NumberEdit*)lv_event_get_user_data(e); if (!numEdit || numEdit->deleted()) return; uint32_t key = lv_event_get_key(e); - lv_obj_t* obj = numEdit->getLvObj(); - - if (obj != nullptr && lv_obj_is_editable(obj)) { - lv_group_t* grp = (lv_group_t*)lv_obj_get_group(obj); - if (grp && lv_group_get_focused(grp) == obj) - numEdit->setEditMode(lv_group_get_editing(grp)); - - switch (key) { - case LV_KEY_LEFT: - // numEdit->onEvent(EVT_ROTARY_LEFT); - break; - case LV_KEY_RIGHT: - // numEdit->onEvent(EVT_ROTARY_RIGHT); - break; - } + switch (key) { + case LV_KEY_LEFT: + numEdit->onEvent(EVT_ROTARY_LEFT); + break; + case LV_KEY_RIGHT: + numEdit->onEvent(EVT_ROTARY_RIGHT); + break; } - - // TODO: this looks highly forbidden!!! - e->code = LV_EVENT_REFRESH; } // create a new class for number edit so we can set the sytles differently if needed. @@ -133,14 +119,6 @@ void NumberEdit::onEvent(event_t event) } #endif - case EVT_KEY_FIRST(KEY_EXIT): -#if defined(SOFTWARE_KEYBOARD) - Keyboard::hide(); - return; -#endif - break; - - #if defined(HARDWARE_TOUCH) case EVT_VIRTUAL_KEY_PLUS: setValue(getValue() + getStep()); @@ -180,35 +158,12 @@ void NumberEdit::onEvent(event_t event) FormField::onEvent(event); } -void NumberEdit::onFocusLost() +void NumberEdit::onClicked() { -#if defined(SOFTWARE_KEYBOARD) - Keyboard::hide(); -#endif - - FormField::onFocusLost(); + lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); + if(indev_type == LV_INDEV_TYPE_POINTER) { + NumberKeyboard::show(this); + } else { + FormField::onClicked(); + } } - - -#if defined(HARDWARE_TOUCH) -bool NumberEdit::onTouchEnd(coord_t, coord_t) -{ - if (!enabled) { - return true; - } - - if (hasFocus()) { - setEditMode(true); - } - else { - setFocus(SET_FOCUS_DEFAULT); - } - -#if defined(SOFTWARE_KEYBOARD) - NumberKeyboard::show(this); -#endif - - return true; -} -#endif - diff --git a/radio/src/thirdparty/libopenui/src/numberedit.h b/radio/src/thirdparty/libopenui/src/numberedit.h index 0a5de69d0..2aa04ab5f 100644 --- a/radio/src/thirdparty/libopenui/src/numberedit.h +++ b/radio/src/thirdparty/libopenui/src/numberedit.h @@ -24,30 +24,29 @@ class NumberEdit : public BaseNumberEdit { - public: - NumberEdit(Window * parent, const rect_t & rect, int vmin, int vmax, std::function getValue, std::function setValue = nullptr, WindowFlags windowFlags = 0, LcdFlags textFlags = 0); + public: + NumberEdit(Window* parent, const rect_t& rect, int vmin, int vmax, + std::function getValue, + std::function setValue = nullptr, + WindowFlags windowFlags = 0, LcdFlags textFlags = 0); #if defined(DEBUG_WINDOWS) - std::string getName() const override - { - return "NumberEdit(" + std::to_string(getValue()) + ")"; - } + std::string getName() const override + { + return "NumberEdit(" + std::to_string(getValue()) + ")"; + } #endif - void setAvailableHandler(std::function handler) - { - isValueAvailable = std::move(handler); - } + void setAvailableHandler(std::function handler) + { + isValueAvailable = std::move(handler); + } - void onEvent(event_t event) override; - void onFocusLost() override; + void onEvent(event_t event) override; + void onClicked() override; -#if defined(HARDWARE_TOUCH) - bool onTouchEnd(coord_t x, coord_t y) override; -#endif - - protected: - std::function isValueAvailable; + protected: + std::function isValueAvailable; }; extern const lv_obj_class_t lv_numberedit_class; diff --git a/radio/src/thirdparty/libopenui/src/table.cpp b/radio/src/thirdparty/libopenui/src/table.cpp index d1b3a2188..2038b40ee 100644 --- a/radio/src/thirdparty/libopenui/src/table.cpp +++ b/radio/src/thirdparty/libopenui/src/table.cpp @@ -24,14 +24,21 @@ void TableField::clicked(lv_event_t *e) lv_obj_t* target = lv_event_get_target(e); if (!target) return; - uint16_t row; - uint16_t col; - lv_table_get_selected_cell(target, &row, &col); - TableField* tf = (TableField*)lv_obj_get_user_data(target); if (!tf) return; - tf->onPress(row, col); + lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); + if(indev_type == LV_INDEV_TYPE_ENCODER) { + // Encoder send VALUE_CHANGED when selection changes + tf->adjustScroll(); + } else { + // Otherwise it's a click + uint16_t row; + uint16_t col; + lv_table_get_selected_cell(target, &row, &col); + + tf->onPress(row, col); + } } void TableField::draw_begin(lv_event_t* e) @@ -73,7 +80,7 @@ void TableField::draw_end(lv_event_t* e) } TableField::TableField(Window* parent, const rect_t& rect, WindowFlags windowFlags) : - FormField(parent, rect, windowFlags, 0, lv_table_create) + Window(parent, rect, windowFlags, 0, lv_table_create) { lv_obj_add_event_cb(lvobj, TableField::clicked, LV_EVENT_VALUE_CHANGED, nullptr); lv_obj_add_event_cb(lvobj, TableField::draw_begin, LV_EVENT_DRAW_PART_BEGIN, nullptr); @@ -205,15 +212,15 @@ void TableField::onEvent(event_t event) onKeyPress(); selectNext(-1); } - else if (event == EVT_KEY_BREAK(KEY_ENTER)) { - onKeyPress(); + // else if (event == EVT_KEY_BREAK(KEY_ENTER)) { + // onKeyPress(); - uint16_t row; - uint16_t col; - lv_table_get_selected_cell(lvobj, &row, &col); + // uint16_t row; + // uint16_t col; + // lv_table_get_selected_cell(lvobj, &row, &col); - onPress(row, col); - } + // onPress(row, col); + // } else { Window::onEvent(event); } diff --git a/radio/src/thirdparty/libopenui/src/table.h b/radio/src/thirdparty/libopenui/src/table.h index 2d0b4e192..0feb7ac30 100644 --- a/radio/src/thirdparty/libopenui/src/table.h +++ b/radio/src/thirdparty/libopenui/src/table.h @@ -21,7 +21,7 @@ #include "form.h" -class TableField : public FormField +class TableField : public Window { public: TableField(Window* parent, const rect_t& rect, diff --git a/radio/src/thirdparty/libopenui/src/textedit.cpp b/radio/src/thirdparty/libopenui/src/textedit.cpp index 8458fbbb7..6bd890942 100644 --- a/radio/src/thirdparty/libopenui/src/textedit.cpp +++ b/radio/src/thirdparty/libopenui/src/textedit.cpp @@ -55,7 +55,11 @@ TextEdit::TextEdit(Window *parent, const rect_t &rect, char *value, lv_obj_set_scrollbar_mode(lvobj, LV_SCROLLBAR_MODE_OFF); lv_textarea_set_password_mode(lvobj, false); lv_textarea_set_one_line(lvobj, true); - lv_textarea_set_text(lvobj, value); + + // value may not be null-terminated + std::string txt(value, length); + lv_textarea_set_text(lvobj, txt.c_str()); + lv_textarea_set_placeholder_text(lvobj, "---"); lv_textarea_set_max_length(lvobj, length); @@ -145,16 +149,6 @@ void TextEdit::onEvent(event_t event) } break; - case EVT_KEY_BREAK(KEY_EXIT): - changeEnd(); - FormField::onEvent(event); - -#if defined(SOFTWARE_KEYBOARD) - Keyboard::hide(); -#endif - setFocus(SET_FOCUS_DEFAULT, this); - break; - case EVT_KEY_LONG(KEY_ENTER): { killEvents(event); @@ -219,33 +213,14 @@ void TextEdit::onEvent(event_t event) #endif } -#if defined(HARDWARE_TOUCH) -bool TextEdit::onTouchEnd(coord_t x, coord_t y) +void TextEdit::onClicked() { - if (!isEnabled()) { - return true; - } - - if (!hasFocus()) { - setFocus(SET_FOCUS_DEFAULT); - } - cursorPos = lv_textarea_get_cursor_pos(lvobj); - -#if defined(SOFTWARE_KEYBOARD) TextKeyboard::show(this); -#endif - - return true; } -#endif void TextEdit::onFocusLost() { -#if defined(SOFTWARE_KEYBOARD) - TextKeyboard::hide(); -#endif - changeEnd(); FormField::onFocusLost(); } diff --git a/radio/src/thirdparty/libopenui/src/textedit.h b/radio/src/thirdparty/libopenui/src/textedit.h index 9f9d74307..40f7ae963 100644 --- a/radio/src/thirdparty/libopenui/src/textedit.h +++ b/radio/src/thirdparty/libopenui/src/textedit.h @@ -47,10 +47,11 @@ class TextEdit : public FormField { } void onEvent(event_t event) override; + void onClicked() override; -#if defined(HARDWARE_TOUCH) - bool onTouchEnd(coord_t x, coord_t y) override; -#endif +// #if defined(HARDWARE_TOUCH) +// bool onTouchEnd(coord_t x, coord_t y) override; +// #endif void onFocusLost() override; diff --git a/radio/src/thirdparty/libopenui/src/widgets/simple_btn.c b/radio/src/thirdparty/libopenui/src/widgets/simple_btn.c new file mode 100644 index 000000000..751864404 --- /dev/null +++ b/radio/src/thirdparty/libopenui/src/widgets/simple_btn.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) OpenTX + * + * Source: + * https://github.com/opentx/libopenui + * + * This file is a part of libopenui library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +#include "simple_btn.h" + +#define MY_CLASS &simple_btn_class + +const lv_obj_class_t simple_btn_class = { + .width_def = LV_DPI_DEF, + .height_def = LV_DPI_DEF, + .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, + .instance_size = sizeof(lv_btn_t), + .base_class = &lv_btn_class, +}; + +lv_obj_t* simple_btn_create(lv_obj_t* parent) +{ + LV_LOG_INFO("begin"); + lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent); + lv_obj_class_init_obj(obj); + return obj; +} diff --git a/radio/src/thirdparty/libopenui/src/widgets/simple_btn.h b/radio/src/thirdparty/libopenui/src/widgets/simple_btn.h new file mode 100644 index 000000000..fe0e31ff7 --- /dev/null +++ b/radio/src/thirdparty/libopenui/src/widgets/simple_btn.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) OpenTX + * + * Source: + * https://github.com/opentx/libopenui + * + * This file is a part of libopenui library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +#ifndef SIMPLE_BTN_H +#define SIMPLE_BTN_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern const lv_obj_class_t simple_btn_class; +lv_obj_t* simple_btn_create(lv_obj_t* parent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/radio/src/thirdparty/libopenui/src/widgets/window_base.c b/radio/src/thirdparty/libopenui/src/widgets/window_base.c new file mode 100644 index 000000000..008f50204 --- /dev/null +++ b/radio/src/thirdparty/libopenui/src/widgets/window_base.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) OpenTX + * + * Source: + * https://github.com/opentx/libopenui + * + * This file is a part of libopenui library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +#include "window_base.h" + +void window_event_cb(lv_event_t* e); + +#define MY_CLASS &window_base_class + +static void window_base_event(const lv_obj_class_t* class_p, lv_event_t* e); + +const lv_obj_class_t window_base_class = { + .base_class = &lv_obj_class, + .event_cb = window_base_event, + .width_def = LV_DPI_DEF, + .height_def = LV_DPI_DEF, + .editable = LV_OBJ_CLASS_EDITABLE_FALSE, + .group_def = LV_OBJ_CLASS_GROUP_DEF_FALSE, + .instance_size = sizeof(lv_obj_t) +}; + +static void window_base_event(const lv_obj_class_t* class_p, lv_event_t* e) +{ + /* Call the ancestor's event handler */ + lv_res_t res = lv_obj_event_base(MY_CLASS, e); + if (res != LV_RES_OK) return; + + window_event_cb(e); +} + +lv_obj_t* window_create(lv_obj_t* parent) +{ + lv_obj_t* obj = lv_obj_class_create_obj(MY_CLASS, parent); + lv_obj_class_init_obj(obj); + return obj; +} diff --git a/radio/src/thirdparty/libopenui/src/widgets/window_base.h b/radio/src/thirdparty/libopenui/src/widgets/window_base.h new file mode 100644 index 000000000..fdbdfa9cf --- /dev/null +++ b/radio/src/thirdparty/libopenui/src/widgets/window_base.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) OpenTX + * + * Source: + * https://github.com/opentx/libopenui + * + * This file is a part of libopenui library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +#ifndef WINDOW_BASE_H +#define WINDOW_BASE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern const lv_obj_class_t window_base_class; +lv_obj_t* window_create(lv_obj_t* parent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/radio/src/thirdparty/libopenui/src/window.cpp b/radio/src/thirdparty/libopenui/src/window.cpp index fdbd2f4eb..0666ebd54 100644 --- a/radio/src/thirdparty/libopenui/src/window.cpp +++ b/radio/src/thirdparty/libopenui/src/window.cpp @@ -21,15 +21,17 @@ #include "touch.h" #include "mainwindow.h" -Window * Window::focusWindow = nullptr; +#include "widgets/window_base.h" + +// Window * Window::focusWindow = nullptr; std::list Window::trash; extern lv_obj_t *virtual_kb; static bool is_scrolling = false; -static bool inhibit_focus = false; +// static bool inhibit_focus = false; -static void window_event_cb(lv_event_t * e) +extern "C" void window_event_cb(lv_event_t * e) { lv_obj_t *target = lv_event_get_target(e); lv_event_code_t code = lv_event_get_code(e); @@ -87,11 +89,11 @@ static void window_event_cb(lv_event_t * e) return; } - // Exclude keyboard ? // if(lv_indev_get_type(click_source) == LV_INDEV_TYPE_KEYPAD || // lv_indev_get_type(click_source) == LV_INDEV_TYPE_ENCODER) { // return; // } + lv_area_t obj_coords; lv_obj_get_coords(target, &obj_coords); @@ -122,7 +124,6 @@ static void window_event_cb(lv_event_t * e) } #endif else if (code == LV_EVENT_SCROLL) { - #if defined(DEBUG_WINDOWS) lv_coord_t scroll_y = lv_obj_get_scroll_y(target); lv_coord_t scroll_x = lv_obj_get_scroll_x(target); @@ -130,53 +131,15 @@ static void window_event_cb(lv_event_t * e) TRACE_WINDOWS("SCROLL[x=%d;y=%d] %s", scroll_x, scroll_y, window->getWindowDebugString().c_str()); #endif - - - } else if (code == LV_EVENT_FOCUSED) { - if (inhibit_focus) return; - - bool focused = ((Window *)target->user_data)->hasFocus(); - TRACE_WINDOWS("FOCUSED[%d] %s", focused, - window->getWindowDebugString().c_str()); - - if (!focused) { - SetFocusFlag flag = SET_FOCUS_DEFAULT; - lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); - if(indev_type == LV_INDEV_TYPE_POINTER) { - flag = SET_FOCUS_NO_SCROLL; - } - window->setFocus(flag); - } } -} - -static void window_base_event(const lv_obj_class_t* class_p, lv_event_t* e) -{ - /*Call the ancestor's event handler*/ - lv_res_t res = lv_obj_event_base(&window_base_class, e); - if(res != LV_RES_OK) return; - - window_event_cb(e); -} - -const lv_obj_class_t window_base_class = { - .base_class = &lv_obj_class, - .constructor_cb = nullptr, - .destructor_cb = nullptr, - .user_data = nullptr, - .event_cb = window_base_event, - .width_def = LV_DPI_DEF, - .height_def = LV_DPI_DEF, - .editable = LV_OBJ_CLASS_EDITABLE_FALSE, - .group_def = LV_OBJ_CLASS_GROUP_DEF_FALSE, - .instance_size = sizeof(lv_obj_t) -}; - -lv_obj_t* window_create(lv_obj_t* parent) -{ - lv_obj_t * obj = lv_obj_class_create_obj(&window_base_class, parent); - lv_obj_class_init_obj(obj); - return obj; + else if (code == LV_EVENT_CLICKED) { + TRACE("CLICKED[%p]", window); + window->onClicked(); + } + else if (code == LV_EVENT_CANCEL) { + TRACE("CANCEL[%p]", window); + window->onCancel(); + } } Window::Window(Window *parent, const rect_t &rect, WindowFlags windowFlags, @@ -189,7 +152,7 @@ Window::Window(Window *parent, const rect_t &rect, WindowFlags windowFlags, lv_obj_t* lv_parent = nullptr; if (parent) lv_parent = parent->lvobj; - if (objConstruct != nullptr) { + if (objConstruct != nullptr && objConstruct != window_create) { lvobj = objConstruct(lv_parent); lv_obj_add_event_cb(lvobj, window_event_cb, LV_EVENT_ALL, nullptr); } else { @@ -254,9 +217,6 @@ Window::Window(Window *parent, lv_obj_t* lvobj) Window::~Window() { TRACE_WINDOWS("Destroy %p %s", this, getWindowDebugString().c_str()); - if (focusWindow == this) { - focusWindow = nullptr; - } if (children.size() > 0) deleteChildren(); @@ -352,10 +312,6 @@ void Window::deleteLater(bool detach, bool trash) _deleted = true; - if (static_cast(focusWindow) == static_cast(this)) { - focusWindow = nullptr; - } - if (detach) this->detach(); else @@ -389,62 +345,17 @@ void Window::clear() void Window::deleteChildren() { // prevent LVGL refocus while mass-deleting - inhibit_focus = true; + // inhibit_focus = true; for (auto window: children) { window->deleteLater(false); } - inhibit_focus = false; + // inhibit_focus = false; children.clear(); } -void Window::clearFocus() -{ - if (focusWindow) { - focusWindow->onFocusLost(); - focusWindow = nullptr; - } -} - -void Window::setFocus(uint8_t flag, Window * from) -{ - if (deleted()) - return; - - TRACE_WINDOWS("%s setFocus()", getWindowDebugString().c_str()); - - if (focusWindow != this) { - // synchronize lvgl focused state with libopenui - if (lvobj != nullptr && - !lv_obj_has_state(lvobj, LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY)) { - lv_obj_add_state(lvobj, LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY); - if (focusWindow != nullptr) { - lv_obj_clear_state(focusWindow->lvobj, LV_STATE_FOCUSED | - LV_STATE_FOCUS_KEY | - LV_STATE_EDITED); - } - } - - // scroll before calling focusHandler so that the window can adjust the - // scroll position if needed - if (flag != SET_FOCUS_NO_SCROLL) { - lv_obj_scroll_to_view_recursive(lvobj, LV_ANIM_OFF); - } - invalidate(); - - clearFocus(); - focusWindow = this; - if (focusHandler) { - focusHandler(true); - } - } -} - -void Window::scrollTo(Window * child) -{ -} - -void Window::scrollTo(const rect_t & rect) +bool Window::hasFocus() const { + return lvobj && lv_obj_has_state(lvobj, LV_STATE_FOCUS_KEY); } bool Window::hasOpaqueRect(const rect_t & testRect) const @@ -579,14 +490,6 @@ void Window::checkEvents() } } - if (this == Window::focusWindow) { - event_t event = getWindowEvent(); -// lvglPushEncoderEvent(event); - if (event) { - this->onEvent(event); - } - } - if (windowFlags & REFRESH_ALWAYS) { invalidate(); } @@ -595,46 +498,52 @@ void Window::checkEvents() void Window::onEvent(event_t event) { TRACE_WINDOWS("%s received event 0x%X", Window::getWindowDebugString("Window").c_str(), event); - if (parent) { - parent->onEvent(event); - } + if (parent) { parent->onEvent(event); } } +void Window::onClicked() +{ + if (parent && !(windowFlags & OPAQUE)) { parent->onClicked(); } +} + +void Window::onCancel() +{ + if (parent) { parent->onCancel(); } +} + + #if defined(HARDWARE_TOUCH) bool Window::onTouchStart(coord_t x, coord_t y) { - if (parent) - return parent->onTouchStart(x, y); + if (parent && !(windowFlags & OPAQUE)) return parent->onTouchStart(x, y); return true; } bool Window::onTouchEnd(coord_t x, coord_t y) { - if (parent && !(windowFlags & OPAQUE)) - return parent->onTouchEnd(x, y); + if (parent && !(windowFlags & OPAQUE)) return parent->onTouchEnd(x, y); return true; } bool Window::onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, coord_t slideX, coord_t slideY) { + // TODO: this is not used anymore: REMOVE + + // for (auto it = children.rbegin(); it != children.rend(); ++it) { + // auto child = *it; + // if (child->rect.contains(startX, startY)) { + // if (child->onTouchSlide(x - child->rect.x, y - child->rect.y, startX - child->rect.x, startY - child->rect.y, slideX, slideY)) { + // return true; + // } + // } + // } - for (auto it = children.rbegin(); it != children.rend(); ++it) { - auto child = *it; - if (child->rect.contains(startX, startY)) { - if (child->onTouchSlide(x - child->rect.x, y - child->rect.y, startX - child->rect.x, startY - child->rect.y, slideX, slideY)) { - return true; - } - } - } + // return false; - return false; + return true; } #endif -void Window::adjustInnerHeight() -{ -} - coord_t Window::adjustHeight() { coord_t old = rect.h; diff --git a/radio/src/thirdparty/libopenui/src/window.h b/radio/src/thirdparty/libopenui/src/window.h index deee76402..8cf5dec9f 100644 --- a/radio/src/thirdparty/libopenui/src/window.h +++ b/radio/src/thirdparty/libopenui/src/window.h @@ -26,10 +26,14 @@ #include #include #include + #include "bitmapbuffer.h" #include "libopenui_defines.h" #include "libopenui_helpers.h" #include "libopenui_config.h" + +#include "widgets/window_base.h" + #include "LvglWrapper.h" typedef uint32_t WindowFlags; @@ -51,19 +55,16 @@ constexpr WindowFlags PAINT_CHILDREN_FIRST = 1u << 6u; constexpr WindowFlags PUSH_FRONT = 1u << 7u; constexpr WindowFlags WINDOW_FLAGS_LAST = PUSH_FRONT; -enum SetFocusFlag -{ - SET_FOCUS_DEFAULT = 0, - SET_FOCUS_FORWARD = 1, - SET_FOCUS_BACKWARD = 2, - SET_FOCUS_FIRST = 3, - SET_FOCUS_NO_SCROLL= 4 -}; +// enum SetFocusFlag +// { +// SET_FOCUS_DEFAULT = 0, +// SET_FOCUS_FORWARD = 1, +// SET_FOCUS_BACKWARD = 2, +// SET_FOCUS_FIRST = 3, +// SET_FOCUS_NO_SCROLL= 4 +// }; typedef lv_obj_t *(*LvglCreate)(lv_obj_t *); -extern const lv_obj_class_t window_base_class; - -lv_obj_t* window_create(lv_obj_t* parent); class Window { @@ -110,23 +111,7 @@ class Window void clear(); virtual void deleteLater(bool detach = true, bool trash = true); - bool hasFocus() const - { - return focusWindow == this; - } - - static Window * getFocus() - { - return focusWindow; - } - - void scrollTo(const rect_t & rect); - - void scrollTo(Window * child); - - static void clearFocus(); - - virtual void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr); + bool hasFocus() const; void setRect(rect_t value) { @@ -216,8 +201,8 @@ class Window } virtual void onEvent(event_t event); - - void adjustInnerHeight(); + virtual void onClicked(); + virtual void onCancel(); coord_t adjustHeight(); @@ -243,10 +228,8 @@ class Window return _deleted; } - virtual void paint(BitmapBuffer *) - { - } - + virtual void paint(BitmapBuffer *) {} + #if defined(HARDWARE_TOUCH) virtual bool onTouchStart(coord_t x, coord_t y); virtual bool onTouchEnd(coord_t x, coord_t y); @@ -255,7 +238,6 @@ class Window inline lv_obj_t *getLvObj() { return lvobj; } protected: - static Window* focusWindow; static std::list trash; rect_t rect; diff --git a/radio/src/thirdparty/libopenui/thirdparty/lvgl b/radio/src/thirdparty/libopenui/thirdparty/lvgl index 2d557d712..a7ec08238 160000 --- a/radio/src/thirdparty/libopenui/thirdparty/lvgl +++ b/radio/src/thirdparty/libopenui/thirdparty/lvgl @@ -1 +1 @@ -Subproject commit 2d557d712848696cf2d52a802ba041554edb2803 +Subproject commit a7ec08238759d446cf22197ae346ed1b995ae422