fix scroll position
This commit is contained in:
+57
-34
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user