From 89978ff17c548a0145d4d8496d44b0751dc6de05 Mon Sep 17 00:00:00 2001 From: Kevin Koenig Date: Sun, 12 Sep 2021 22:20:24 -0400 Subject: [PATCH] Move ChoiceEx to libopenui + fix keyboard crash (#19) * moved choiceex.* to libopenui where it belongs * added choiceex to build * enhanced system * removed construtor parameter for getTicks. Turns out you can just access the timer directly in libopenui * fixed keyboard crash for widget settings * code cleanup Co-authored-by: kkoenig1@optonline.com --- .../thirdparty/libopenui/src/CMakeLists.txt | 1 + .../thirdparty/libopenui/src/bitmapbuffer.cpp | 0 .../thirdparty/libopenui/src/bitmapbuffer.h | 0 radio/src/thirdparty/libopenui/src/choice.cpp | 5 + radio/src/thirdparty/libopenui/src/choice.h | 8 ++ .../src/thirdparty/libopenui/src/choiceex.cpp | 111 ++++++++++++++++++ radio/src/thirdparty/libopenui/src/choiceex.h | 60 ++++++++++ .../libopenui/src/keyboard_base.cpp | 12 +- .../thirdparty/libopenui/src/keyboard_base.h | 3 +- radio/src/thirdparty/libopenui/src/static.cpp | 0 10 files changed, 196 insertions(+), 4 deletions(-) mode change 100755 => 100644 radio/src/thirdparty/libopenui/src/bitmapbuffer.cpp mode change 100755 => 100644 radio/src/thirdparty/libopenui/src/bitmapbuffer.h create mode 100644 radio/src/thirdparty/libopenui/src/choiceex.cpp create mode 100644 radio/src/thirdparty/libopenui/src/choiceex.h mode change 100755 => 100644 radio/src/thirdparty/libopenui/src/static.cpp diff --git a/radio/src/thirdparty/libopenui/src/CMakeLists.txt b/radio/src/thirdparty/libopenui/src/CMakeLists.txt index c1a9671d3..661dee69e 100644 --- a/radio/src/thirdparty/libopenui/src/CMakeLists.txt +++ b/radio/src/thirdparty/libopenui/src/CMakeLists.txt @@ -26,6 +26,7 @@ set(LIBOPENUI_SRC menu.cpp menutoolbar.cpp choice.cpp + choiceex.cpp filechoice.cpp numberedit.cpp textedit.cpp diff --git a/radio/src/thirdparty/libopenui/src/bitmapbuffer.cpp b/radio/src/thirdparty/libopenui/src/bitmapbuffer.cpp old mode 100755 new mode 100644 diff --git a/radio/src/thirdparty/libopenui/src/bitmapbuffer.h b/radio/src/thirdparty/libopenui/src/bitmapbuffer.h old mode 100755 new mode 100644 diff --git a/radio/src/thirdparty/libopenui/src/choice.cpp b/radio/src/thirdparty/libopenui/src/choice.cpp index 9be769153..0d935b245 100644 --- a/radio/src/thirdparty/libopenui/src/choice.cpp +++ b/radio/src/thirdparty/libopenui/src/choice.cpp @@ -162,6 +162,11 @@ void Choice::openMenu() menu->select(current); } + if (beforeDisplayMenuHandler) { + beforeDisplayMenuHandler(menu); + } + + menu->setCloseHandler([=]() { setEditMode(false); }); diff --git a/radio/src/thirdparty/libopenui/src/choice.h b/radio/src/thirdparty/libopenui/src/choice.h index a92767ddd..bea30052a 100644 --- a/radio/src/thirdparty/libopenui/src/choice.h +++ b/radio/src/thirdparty/libopenui/src/choice.h @@ -22,6 +22,8 @@ #include #include "form.h" +class Menu; + enum ChoiceType { CHOICE_TYPE_DROPOWN, CHOICE_TYPE_FOLDER, @@ -77,6 +79,11 @@ class Choice: public ChoiceBase { bool onTouchEnd(coord_t x, coord_t y) override; #endif + void setBeforeDisplayMenuHandler(std::function handler) + { + beforeDisplayMenuHandler = std::move(handler); + } + void setSetValueHandler(std::function handler) { setValue = std::move(handler); @@ -155,6 +162,7 @@ class Choice: public ChoiceBase { std::function setValue; std::function isValueAvailable; std::function textHandler; + std::function beforeDisplayMenuHandler; virtual void openMenu(); }; diff --git a/radio/src/thirdparty/libopenui/src/choiceex.cpp b/radio/src/thirdparty/libopenui/src/choiceex.cpp new file mode 100644 index 000000000..d8a87698d --- /dev/null +++ b/radio/src/thirdparty/libopenui/src/choiceex.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + */ +#include "choiceex.h" + +constexpr int LONG_PRESS_10MS = 40; + +extern inline tmr10ms_t getTicks() +{ + return g_tmr10ms; +} + + + +void ChoiceEx::setLongPressHandler(std::function handler) +{ + longPressHandler = handler; +} + +ChoiceEx::ChoiceEx(FormGroup * parent, const rect_t & rect, int16_t vmin, int16_t vmax, std::function getValue, + std::function setValue, WindowFlags windowFlags) : + Choice(parent, rect, vmin, vmax, getValue, setValue, windowFlags) +{ +#if defined(HARDWARE_TOUCH) + duration10ms = 0; +#endif +} + +#if defined(HARDWARE_KEYS) +void ChoiceEx::onEvent(event_t event) +{ + if (event == EVT_KEY_LONG(KEY_ENTER)) { + if (longPressHandler) { + killEvents(event); + longPressHandler(event); + return; + } + } + + Choice::onEvent(event); +} +#endif + +#if defined(HARDWARE_TOUCH) +bool ChoiceEx::isLongPress() +{ + unsigned int curTimer = getTicks(); + return (!longPressed && duration10ms != 0 && curTimer - duration10ms > LONG_PRESS_10MS); +} + +void ChoiceEx::checkEvents(void) +{ + event_t event = getEvent(); + + if (isLongPress()) { + if (!longPressed && longPressHandler) { + longPressHandler(event); + killEvents(event); + duration10ms = 0; + longPressed = true; + return; + } + } + + if (hasFocus()) + onEvent(event); + else + pushEvent(event); +} + +bool ChoiceEx::onTouchStart(coord_t x, coord_t y) +{ + if (!longPressed && duration10ms == 0) { + duration10ms = getTicks(); + } + + return Choice::onTouchStart(x, y); +} + + +bool ChoiceEx::onTouchEnd(coord_t x, coord_t y) +{ + if (longPressed) { + longPressed = false; + return false; + } + + duration10ms = 0; + return Choice::onTouchEnd(x,y); +} +#endif + + + diff --git a/radio/src/thirdparty/libopenui/src/choiceex.h b/radio/src/thirdparty/libopenui/src/choiceex.h new file mode 100644 index 000000000..4a63d13cb --- /dev/null +++ b/radio/src/thirdparty/libopenui/src/choiceex.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + */ +#ifndef _CHOICEEX_H_ +#define _CHOICEEX_H_ +#include "choice.h" + +class ChoiceEx : public Choice +{ + public: + ChoiceEx(FormGroup * parent, const rect_t &rect, int16_t vmin, int16_t vmax, std::function getValue, + std::function setValue = nullptr, WindowFlags windowFlags = 0); + + void setLongPressHandler(std::function handler); + +#if defined(HARDWARE_KEYS) + void onEvent(event_t event) override; +#endif + +#if defined(HARDWARE_TOUCH) + bool onTouchEnd(coord_t x, coord_t y) override; + bool onTouchStart(coord_t x, coord_t y) override; + void checkEvents(void) override; + bool isLongPress(); +#endif + +#if defined(DEBUG_WINDOWS) + std::string getName() const override + { + return "ChoceEx"; + } +#endif + +protected: + std::function longPressHandler = nullptr; + +#if defined(HARDWARE_TOUCH) + uint32_t duration10ms; + bool longPressed = false; +#endif +}; + +#endif \ No newline at end of file diff --git a/radio/src/thirdparty/libopenui/src/keyboard_base.cpp b/radio/src/thirdparty/libopenui/src/keyboard_base.cpp index 10c80d526..414c0bd42 100644 --- a/radio/src/thirdparty/libopenui/src/keyboard_base.cpp +++ b/radio/src/thirdparty/libopenui/src/keyboard_base.cpp @@ -35,14 +35,17 @@ coord_t calcScrollOffsetForField(FormField *newField, Window *topWindow) return offsetY - topWindow->height() / 2; } -void Keyboard::attachKeyboard() +bool Keyboard::attachKeyboard() { + TRACE("ATTACH KEYBOARD"); if (activeKeyboard) { - if (activeKeyboard == this) return; + if (activeKeyboard == this) return false; activeKeyboard->clearField(); } + activeKeyboard = this; attach(MainWindow::instance()); + return true; } @@ -76,7 +79,10 @@ FormWindow *Keyboard::findFormWindow(Window *parent) void Keyboard::setField(FormField* newField) { - attachKeyboard(); + TRACE("SET FIELD"); + + if (!attachKeyboard()) + return; fieldContainer = getFieldContainer(newField); if (fieldContainer) { diff --git a/radio/src/thirdparty/libopenui/src/keyboard_base.h b/radio/src/thirdparty/libopenui/src/keyboard_base.h index b30c76a05..5374b9d5c 100644 --- a/radio/src/thirdparty/libopenui/src/keyboard_base.h +++ b/radio/src/thirdparty/libopenui/src/keyboard_base.h @@ -31,6 +31,7 @@ class Keyboard: public FormWindow void clearField() { + TRACE("CLEAR FIELD"); detach(); if (fields) { fields->setHeight(oldHeight); @@ -64,7 +65,7 @@ class Keyboard: public FormWindow void setField(FormField *newField); Window *getFieldContainer(FormField * field); - void attachKeyboard(); + bool attachKeyboard(); FormWindow *findFormWindow(Window *parent); }; diff --git a/radio/src/thirdparty/libopenui/src/static.cpp b/radio/src/thirdparty/libopenui/src/static.cpp old mode 100755 new mode 100644