diff --git a/radio/src/thirdparty/libopenui/src/CMakeLists.txt b/radio/src/thirdparty/libopenui/src/CMakeLists.txt index 98bcf5f78..c1a9671d3 100644 --- a/radio/src/thirdparty/libopenui/src/CMakeLists.txt +++ b/radio/src/thirdparty/libopenui/src/CMakeLists.txt @@ -42,5 +42,6 @@ if(SOFTWARE_KEYBOARD) ${LIBOPENUI_SRC} keyboard_text.cpp keyboard_number.cpp + keyboard_base.cpp ) endif() diff --git a/radio/src/thirdparty/libopenui/src/keyboard_base.cpp b/radio/src/thirdparty/libopenui/src/keyboard_base.cpp new file mode 100644 index 000000000..a74e6516b --- /dev/null +++ b/radio/src/thirdparty/libopenui/src/keyboard_base.cpp @@ -0,0 +1,103 @@ +/* + * 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 "keyboard_base.h" + +void Keyboard::hide() +{ + if (activeKeyboard) { + activeKeyboard->clearField(); + activeKeyboard = nullptr; + } +} + +void Keyboard::clearField() +{ + detach(); + if (fields) { + fields->setHeight(oldHeight); + fields = nullptr; + } + if (fieldContainer) { + fieldContainer->setHeight(LCD_H - 0 - fieldContainer->top()); + fieldContainer = nullptr; + } + if (field) { + field->setEditMode(false); + field = nullptr; + } +} + +void Keyboard::setField(FormField* newField) +{ + if (activeKeyboard) { + if (activeKeyboard == this) return; + activeKeyboard->clearField(); + } + activeKeyboard = this; + attach(MainWindow::instance()); + + fieldContainer = getFieldContainer(newField); + if (fieldContainer) { + coord_t newWindowHeight = LCD_H - height(); + + fieldContainer->setHeight(newWindowHeight); + + std::list children = fieldContainer->getChildren(); + fields = *std::next(children.begin()); + + rect_t scrollRect = { + fieldContainer->left(), + fields->top(), // this will remove the title from the screen to provide extra visible space. + fieldContainer->width(), + fieldContainer->height() + }; + // both should be the same height as we are scrolled to the right position + fieldContainer->scrollTo(scrollRect); + oldHeight = fields->height(); + fields->setHeight(newWindowHeight); + + // now we need to calculate the offset of the field in the fields scroll container + coord_t offsetX = 0, offsetY = 0; + Window* parentWindow = newField->getParent(); + while (parentWindow && parentWindow != fieldContainer) { + offsetX += parentWindow->left(); + offsetY += parentWindow->top(); + parentWindow = parentWindow->getParent(); + } + + scrollRect = { + offsetX, + offsetY + 69, + fieldContainer->width(), + fieldContainer->height() + }; + fields->scrollTo(scrollRect); + + invalidate(); + newField->setEditMode(true); + field = newField; + } else { + clearField(); + } +} + +Window* Keyboard::getFieldContainer(FormField* field) +{ + return field->getFullScreenWindow(); +} diff --git a/radio/src/thirdparty/libopenui/src/keyboard_base.h b/radio/src/thirdparty/libopenui/src/keyboard_base.h index fb6859eb8..2240d183c 100644 --- a/radio/src/thirdparty/libopenui/src/keyboard_base.h +++ b/radio/src/thirdparty/libopenui/src/keyboard_base.h @@ -25,61 +25,21 @@ class Keyboard: public FormWindow { public: - explicit Keyboard(coord_t height): - FormWindow(nullptr, {0, LCD_H - height, LCD_W, height}, OPAQUE) + explicit Keyboard(coord_t height) : FormWindow(nullptr, {0, LCD_H - height, LCD_W, height}, OPAQUE) { } - static void hide() - { - if (activeKeyboard) { - activeKeyboard->clearField(); - activeKeyboard = nullptr; - } - } + static void hide(); protected: static Keyboard * activeKeyboard; - FormField * field = nullptr; - Window * fieldContainer = nullptr; + FormField *field = nullptr; + Window *fieldContainer = nullptr; + Window *fields = nullptr; + coord_t oldHeight = 0; - void setField(FormField * newField) - { - if (activeKeyboard) { - if (activeKeyboard == this) - return; - activeKeyboard->clearField(); - } - activeKeyboard = this; - attach(MainWindow::instance()); - fieldContainer = getFieldContainer(newField); - if (fieldContainer) { - fieldContainer->setHeight(LCD_H - height() - fieldContainer->top()); - fieldContainer->scrollTo(newField); - invalidate(); - newField->setEditMode(true); - field = newField; - } else { - clearField(); - } - } - - void clearField() - { - detach(); - if (fieldContainer) { - fieldContainer->setHeight(LCD_H - 0 - fieldContainer->top()); - fieldContainer = nullptr; - } - if (field) { - field->setEditMode(false); - field = nullptr; - } - } - - Window * getFieldContainer(FormField * field) - { - return field->getFullScreenWindow(); - } + void setField(FormField *newField); + void clearField(); + Window *getFieldContainer(FormField * field); }; diff --git a/radio/src/thirdparty/libopenui/src/numberedit.cpp b/radio/src/thirdparty/libopenui/src/numberedit.cpp index eacc2b86e..f9d56fbbd 100644 --- a/radio/src/thirdparty/libopenui/src/numberedit.cpp +++ b/radio/src/thirdparty/libopenui/src/numberedit.cpp @@ -106,6 +106,7 @@ void NumberEdit::onEvent(event_t event) case EVT_KEY_FIRST(KEY_EXIT): #if defined(SOFTWARE_KEYBOARD) Keyboard::hide(); + return; #endif break; diff --git a/radio/src/thirdparty/libopenui/src/textedit.cpp b/radio/src/thirdparty/libopenui/src/textedit.cpp index 0e023d354..b2aa9ef94 100644 --- a/radio/src/thirdparty/libopenui/src/textedit.cpp +++ b/radio/src/thirdparty/libopenui/src/textedit.cpp @@ -170,10 +170,12 @@ void TextEdit::onEvent(event_t event) case EVT_KEY_BREAK(KEY_EXIT): changeEnd(); + FormField::onEvent(event); + #if defined(SOFTWARE_KEYBOARD) Keyboard::hide(); #endif - FormField::onEvent(event); + setFocus(SET_FOCUS_DEFAULT, this); break; case EVT_KEY_LONG(KEY_ENTER): diff --git a/radio/src/thirdparty/libopenui/src/window.h b/radio/src/thirdparty/libopenui/src/window.h index a3cbbb964..6902eb4e4 100644 --- a/radio/src/thirdparty/libopenui/src/window.h +++ b/radio/src/thirdparty/libopenui/src/window.h @@ -144,6 +144,11 @@ class Window focusHandler = std::move(handler); } + const std::list getChildren() + { + return children; + } + virtual void deleteLater(bool detach = true, bool trash = true); void clear();