fix scroll position

This commit is contained in:
kevinkoenig
2021-08-27 13:11:11 -04:00
parent 8a1089538f
commit 95f696bfef
3 changed files with 66 additions and 41 deletions
+57 -34
View File
@@ -1,8 +1,8 @@
/*
* Copyright (C) OpenTX
* Copyright (C) EdgeTX
*
* Source:
* https://github.com/opentx/libopenui
* https://github.com/edgetx/libopenui
*
* This file is a part of libopenui library.
*
@@ -43,7 +43,24 @@ void Keyboard::clearField()
}
}
void Keyboard::setField(FormField* newField)
coord_t calcScrollOffsetForField(FormField *newField, Window *topWindow)
{
// now we need to calculate the offset of the field in the fields scroll container
// start with the current fields top and walk the hierarchy to calculate positon
coord_t offsetY = newField->top();
Window* parentWindow = newField->getParent();
while (parentWindow && parentWindow != topWindow) {
offsetY += parentWindow->top();
parentWindow = parentWindow->getParent();
}
// try and place it in the middle of the screen. The containing window MUST have
// already been resized
return offsetY - topWindow->height() / 2;
}
void Keyboard::attachKeyboard()
{
if (activeKeyboard) {
if (activeKeyboard == this) return;
@@ -51,44 +68,50 @@ void Keyboard::setField(FormField* newField)
}
activeKeyboard = this;
attach(MainWindow::instance());
}
// this routine finds the window that is a FormWindow. This is the window
// that contains all of the editable fields. This is the window that needs
// to be scrolled into view.
FormWindow *Keyboard::findFormWindow()
{
if (fieldContainer) {
auto children = fieldContainer->getChildren();
auto k = children.begin();
while (k != children.end())
{
FormWindow *a = dynamic_cast<FormWindow*>(*k);
if (a)
return a;
k++;
}
}
return nullptr;
}
void Keyboard::setField(FormField* newField)
{
attachKeyboard();
fieldContainer = getFieldContainer(newField);
if (fieldContainer) {
coord_t newWindowHeight = LCD_H - height();
coord_t newHeight = LCD_H - height();
fieldContainer->setHeight(newHeight);
fieldContainer->setHeight(newWindowHeight);
fields = findFormWindow();
if (fields) {
// scroll the header of the window out of view to get more space to
// see the field being edited
fieldContainer->setScrollPositionY(fields->top());
oldHeight = fields->height();
fields->setHeight(newHeight);
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();
coord_t offsetY = calcScrollOffsetForField(newField, fields);
fields->setScrollPositionY(offsetY);
}
scrollRect = {
offsetX,
offsetY + 69,
fieldContainer->width(),
fieldContainer->height()
};
fields->scrollTo(scrollRect);
invalidate();
newField->setEditMode(true);
field = newField;
+7 -5
View File
@@ -1,8 +1,8 @@
/*
* Copyright (C) OpenTX
* Copyright (C) EdgeTX
*
* Source:
* https://github.com/opentx/libopenui
* https://github.com/edgetx/libopenui
*
* This file is a part of libopenui library.
*
@@ -34,12 +34,14 @@ class Keyboard: public FormWindow
protected:
static Keyboard * activeKeyboard;
FormField *field = nullptr;
Window *fieldContainer = nullptr;
Window *fields = nullptr;
coord_t oldHeight = 0;
Window *fieldContainer = nullptr;
FormWindow *fields = nullptr;
coord_t oldHeight = 0;
void setField(FormField *newField);
void clearField();
Window *getFieldContainer(FormField * field);
void attachKeyboard();
FormWindow *findFormWindow();
};
+2 -2
View File
@@ -174,7 +174,7 @@ void TextKeyboard::paint(BitmapBuffer * dc)
bool TextKeyboard::onTouchStart(coord_t x, coord_t y)
{
// remove the centering. If x < 0 then this is an invalid touch event
// remove the centering. If x < 0 then this is an invalid touch event
x -= (this->width() - calculateMaxWidth()) / 2;
if (x < 0) {
if (touched) {
@@ -274,7 +274,7 @@ bool TextKeyboard::onTouchEnd(coord_t x, coord_t y)
}
}
else {
if (x <= KEYBOARD_CHAR_WIDTH && *key != ' ') {
if (*key != ' ' && (x >= -(KEYBOARD_CHAR_WIDTH / 2) && x <= KEYBOARD_CHAR_WIDTH / 2)) {
pushEvent(EVT_VIRTUAL_KEY(*key));
return true;
}