trying to fix scrolling to correct positon when keyboard pops up
This commit is contained in:
@@ -42,5 +42,6 @@ if(SOFTWARE_KEYBOARD)
|
||||
${LIBOPENUI_SRC}
|
||||
keyboard_text.cpp
|
||||
keyboard_number.cpp
|
||||
keyboard_base.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -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<Window*> 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();
|
||||
}
|
||||
+9
-49
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+3
-1
@@ -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):
|
||||
|
||||
+5
@@ -144,6 +144,11 @@ class Window
|
||||
focusHandler = std::move(handler);
|
||||
}
|
||||
|
||||
const std::list<Window *> getChildren()
|
||||
{
|
||||
return children;
|
||||
}
|
||||
|
||||
virtual void deleteLater(bool detach = true, bool trash = true);
|
||||
|
||||
void clear();
|
||||
|
||||
Reference in New Issue
Block a user