keyboard: simplify showing/scrolling

This commit is contained in:
Raphael Coeffic
2022-06-11 15:13:11 +02:00
committed by Raphael Coeffic
parent 07e4f494b1
commit 0d69b7a391
3 changed files with 26 additions and 98 deletions
+2 -1
View File
@@ -153,7 +153,8 @@ FormGroup::Line::Line(Window* parent, lv_obj_t* obj, FlexGridLayout* layout,
void FormGroup::Line::construct()
{
// forward scroll and focus
windowFlags |= FORWARD_SCROLL | FORM_FORWARD_FOCUS;
windowFlags |= FORWARD_SCROLL | NO_FOCUS | FORM_FORWARD_FOCUS;
lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_CLICK_FOCUSABLE);
if (layout) {
layout->apply(lvobj);
+23 -93
View File
@@ -31,7 +31,6 @@ static void keyboard_event_cb(lv_event_t * e)
}
}
Keyboard::Keyboard(coord_t height) :
FormWindow(MainWindow::instance(), {0, LCD_H - height, LCD_W, height}, OPAQUE)
{
@@ -55,14 +54,13 @@ void Keyboard::clearField()
}
detach();
if (fields) {
fields->setHeight(oldHeight);
fields = nullptr;
}
if (lvobj != nullptr) lv_obj_set_parent(lvobj, nullptr);
if (fieldContainer) {
fieldContainer->setHeight(LCD_H - 0 - fieldContainer->top());
lv_obj_scroll_to_y(fieldContainer->getLvObj(), scroll_pos, LV_ANIM_OFF);
fieldContainer = nullptr;
}
if (field) {
field->setEditMode(false);
field->changeEnd();
@@ -79,24 +77,6 @@ void Keyboard::hide()
}
}
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 / 7;
}
bool Keyboard::attachKeyboard()
{
if (activeKeyboard) {
@@ -108,84 +88,34 @@ bool Keyboard::attachKeyboard()
return true;
}
// 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(Window *parent)
{
if (parent) {
auto children = parent->getChildren();
auto childIterator = children.begin();
while (childIterator != children.end())
{
#if defined(DEBUG_WINDOWS)
std::string windowName;
Window *window = dynamic_cast<Window *>(*childIterator);
if (window)
windowName = window->getName();
#endif
FormWindow *formWindow = dynamic_cast<FormWindow*>(*childIterator);
if (formWindow)
return formWindow;
childIterator++;
}
}
return nullptr;
}
void Keyboard::setField(FormField* newField)
{
TRACE("SET FIELD");
if (!attachKeyboard())
return;
fieldContainer = getFieldContainer(newField);
if (fieldContainer) {
#if defined(DEBUG_WINDOWS)
auto windowName = fieldContainer->getName();
#endif
coord_t newHeight = LCD_H - height();
fieldContainer->setHeight(newHeight);
lv_obj_t* obj = newField->getLvObj();
if (obj) {
fields = findFormWindow(fieldContainer);
fieldContainer = newField->getFullScreenWindow();
if (fieldContainer) {
if (fields) {
#if defined(DEBUG_WINDOWS)
windowName = fields->getName();
#endif
// scroll the header of the window out of view to get more space to
// see the field being edited
// TODO: this no longer works. we need to figure out something else
//lv_obj_scroll_to_y(fieldContainer->getLvObj(), fields->top(), LV_ANIM_OFF);
attach(fieldContainer);
oldHeight = fields->height();
fields->setHeight(newHeight);
lv_area_t coords;
lv_obj_get_coords(obj, &coords);
coord_t offsetY = calcScrollOffsetForField(newField, fields);
lv_obj_scroll_to_y(fields->getLvObj(), offsetY, LV_ANIM_OFF);
} else {
// TODO: what happens if field container is null.
// we will need to interrogate the fieldContainer for its
// FormGroup. That is really how it should work anyway.
// place keyboard bellow the field with some margin
setTop(max(coords.y2 + 21, LCD_H - height()));
// save scroll position
scroll_pos = lv_obj_get_scroll_y(fieldContainer->getLvObj());
lv_obj_scroll_to_view(lvobj, LV_ANIM_OFF);
invalidate();
newField->setEditMode(true);
lv_keyboard_set_textarea(keyboard, newField->getLvObj());
field = newField;
}
invalidate();
newField->setEditMode(true);
lv_keyboard_set_textarea(keyboard, newField->getLvObj());
field = newField;
} else {
clearField();
}
}
Window* Keyboard::getFieldContainer(FormField* field)
{
return field->getFullScreenWindow();
}
+1 -4
View File
@@ -34,12 +34,9 @@ class Keyboard: public FormWindow
FormField *field = nullptr;
Window *fieldContainer = nullptr;
FormWindow *fields = nullptr;
coord_t oldHeight = 0;
lv_coord_t scroll_pos = 0;
void setField(FormField *newField);
Window *getFieldContainer(FormField * field);
bool attachKeyboard();
FormWindow *findFormWindow(Window *parent);
};