From ff180ed730d16dd72f499b6e04716326fa137831 Mon Sep 17 00:00:00 2001 From: Tomasz Langowski Date: Fri, 8 Jan 2021 10:30:36 +0100 Subject: [PATCH] [EGD-5140] Fix default borderCallback navigation in GridLayout Fix default borderCallback navigation in GridLayout --- changelog.md | 1 + module-gui/gui/widgets/BoxLayout.cpp | 2 +- module-gui/gui/widgets/GridLayout.cpp | 46 +++++++++++++++++++++------ module-gui/gui/widgets/GridLayout.hpp | 7 ++++ module-gui/gui/widgets/Item.cpp | 5 +++ module-gui/gui/widgets/Item.hpp | 2 +- 6 files changed, 52 insertions(+), 11 deletions(-) diff --git a/changelog.md b/changelog.md index a9fe282c2307c1fd9f0f78d7334ae292d72658e5..09f41905c9356733f62104f900b86ac48ec9466f 100644 --- a/changelog.md +++ b/changelog.md @@ -14,6 +14,7 @@ * Fix absent notifications * Fix newly added contact recognized as a duplicate of temporary contact. +* Fix default borderCallback navigation in GridLayout. ## [0.52.1 2020-12-23] diff --git a/module-gui/gui/widgets/BoxLayout.cpp b/module-gui/gui/widgets/BoxLayout.cpp index 06a62420cd0e4213fb0203f40a3344fb70fc7afc..9257bc8b787736d35e1715eaca7784ab903b489a 100644 --- a/module-gui/gui/widgets/BoxLayout.cpp +++ b/module-gui/gui/widgets/BoxLayout.cpp @@ -31,7 +31,7 @@ namespace gui if (handleNavigation(inputEvent)) { return true; } - if (borderCallback && borderCallback(inputEvent)) { + if (borderCallback && isInputNavigation(inputEvent) && borderCallback(inputEvent)) { outOfDrawAreaItems.clear(); return true; } diff --git a/module-gui/gui/widgets/GridLayout.cpp b/module-gui/gui/widgets/GridLayout.cpp index 67f0b20dd6f94ddbebb13b30c41cf807f0526e6a..149038a6a53c41c22b3fbdd5243e0256e4969aec 100644 --- a/module-gui/gui/widgets/GridLayout.cpp +++ b/module-gui/gui/widgets/GridLayout.cpp @@ -19,25 +19,28 @@ GridLayout::GridLayout( if (inputEvent.state != InputEvent::State::keyReleasedShort) { return false; } + + auto it = this->getNavigationFocusedItem(); + auto distance = std::distance(children.begin(), it); switch (inputEvent.keyCode) { case KeyCode::KEY_UP: { - auto it = this->getNavigationFocusedItem(); - this->setFocusItem((*std::next(it, (this->rowSize - 1) * this->colSize))); + auto realRowSize = calculateRowSizeForBorderTransition(distance); + this->setFocusItem((*std::next(it, (realRowSize - 1) * this->colSize))); return true; } case KeyCode::KEY_DOWN: { - auto it = this->getNavigationFocusedItem(); - this->setFocusItem((*std::prev(it, (this->rowSize - 1) * this->colSize))); + auto realRowSize = calculateRowSizeForBorderTransition(distance); + this->setFocusItem((*std::prev(it, (realRowSize - 1) * this->colSize))); return true; } case KeyCode::KEY_LEFT: { - auto it = this->getNavigationFocusedItem(); - this->setFocusItem((*std::next(it, this->colSize - 1))); + auto realColSize = calculateColumnSizeForBorderTransition(distance); + this->setFocusItem((*std::next(it, realColSize - 1))); return true; } case KeyCode::KEY_RIGHT: { - auto it = this->getNavigationFocusedItem(); - this->setFocusItem((*std::prev(it, this->colSize - 1))); + auto realColSize = calculateColumnSizeForBorderTransition(distance); + this->setFocusItem((*std::prev(it, realColSize - 1))); return true; } default: { @@ -47,6 +50,25 @@ GridLayout::GridLayout( }; } +uint32_t GridLayout::calculateColumnSizeForBorderTransition(const uint32_t currentPosition) +{ + auto realColSize = colSize; + if (elementsInIncompletedLastRow) { + if (((currentPosition / colSize) + 1) >= rowSize) + realColSize = elementsInIncompletedLastRow; + } + return realColSize; +} +uint32_t GridLayout::calculateRowSizeForBorderTransition(const uint32_t currentPosition) +{ + auto realRowSize = rowSize; + if (elementsInIncompletedLastRow) { + if (((currentPosition % (colSize)) + 1) > elementsInIncompletedLastRow) + realRowSize--; + } + return realRowSize; +} + void GridLayout::resizeItems() { if (grid.x == 0 || grid.y == 0) { @@ -57,7 +79,13 @@ void GridLayout::resizeItems() uint32_t el_in_y = area().h / grid.y; colSize = children.size() < area().w / grid.x ? children.size() : area().w / grid.x; - rowSize = colSize != 0 ? children.size() / colSize : 1; + rowSize = colSize != 0 ? (children.size() / colSize) : 1; + if (colSize > 1 && (static_cast(children.size()) / colSize) > 1.0) { + elementsInIncompletedLastRow = children.size() % colSize; + } + if (elementsInIncompletedLastRow > 0) { + rowSize++; + } uint32_t strech_x = 0; uint32_t strech_y = 0; diff --git a/module-gui/gui/widgets/GridLayout.hpp b/module-gui/gui/widgets/GridLayout.hpp index dec9bd4bca52733471b9968e6fe3c8cdb0931eaa..f8976f4b3324068825f98164dcbe5c2e130395be 100644 --- a/module-gui/gui/widgets/GridLayout.hpp +++ b/module-gui/gui/widgets/GridLayout.hpp @@ -34,6 +34,13 @@ namespace gui uint32_t rowSize = 0; uint32_t colSize = 0; + ///> elementsInIncompletedLastRow describes how many items has been put to last row, + /// in case when items for last row is not equal to colSize + uint32_t elementsInIncompletedLastRow = 0; + + private: + uint32_t calculateColumnSizeForBorderTransition(const uint32_t currentPosition); + uint32_t calculateRowSizeForBorderTransition(const uint32_t currentPosition); }; }; // namespace gui diff --git a/module-gui/gui/widgets/Item.cpp b/module-gui/gui/widgets/Item.cpp index 7ed7f74e24ac4f87f5d4511f4523f2d455ec1ee4..c1dc8baaee603bfc11f4535f8adf48a177bea725 100644 --- a/module-gui/gui/widgets/Item.cpp +++ b/module-gui/gui/widgets/Item.cpp @@ -30,6 +30,11 @@ namespace gui } } + bool isInputNavigation(const InputEvent &evt) + { + return inputToNavigation(evt) != NavigationDirection::NONE; + } + Item::Item() : focus{false}, type{ItemType::ITEM}, parent{nullptr}, radius{0}, visible{true}, verticalPolicy{LayoutVerticalPolicy::LAYOUT_POLICY_VERTICAL_EXPAND}, diff --git a/module-gui/gui/widgets/Item.hpp b/module-gui/gui/widgets/Item.hpp index 50ae95b29018be16286e54f3e6a0a528892b9cd2..989198ebfb8ee4c897213677cdcced88919bbf59 100644 --- a/module-gui/gui/widgets/Item.hpp +++ b/module-gui/gui/widgets/Item.hpp @@ -363,5 +363,5 @@ namespace gui }; NavigationDirection inputToNavigation(const InputEvent &evt); - + bool isInputNavigation(const InputEvent &evt); } /* namespace gui */