From 659570ca134048c5ca961fb3fc0f916398aa3bb8 Mon Sep 17 00:00:00 2001 From: mkamonMdt Date: Fri, 10 Sep 2021 07:53:00 +0200 Subject: [PATCH] [BH-863] Fix powernap spinner arrows There were an issue in the PowerNap's main window, that the spinner's arrows would not disappear on reaching extremums. To solve this the commit adds a setArrowVisible functionality to the gui::BellBaseLayout, a onValueChange callback to gui::Spinner and employs both to the gui::PowerNapListItem to solve the issue. --- .../apps-common/widgets/BellBaseLayout.cpp | 8 +++++++ .../apps-common/widgets/BellBaseLayout.hpp | 8 +++++++ module-gui/gui/widgets/Spinner.cpp | 8 +++++-- module-gui/gui/widgets/Spinner.hpp | 5 ++++- .../data/PowerNapListItem.cpp | 22 ++++++++++++++++++- .../data/PowerNapListItem.hpp | 6 ++++- .../models/PowerNapModel.cpp | 1 + 7 files changed, 53 insertions(+), 5 deletions(-) diff --git a/module-apps/apps-common/widgets/BellBaseLayout.cpp b/module-apps/apps-common/widgets/BellBaseLayout.cpp index abf8b9f1a6401d572d00fe735a6cca615e9b195b..a9c3a6daf148516644c2e036377d31628edb1bd0 100644 --- a/module-apps/apps-common/widgets/BellBaseLayout.cpp +++ b/module-apps/apps-common/widgets/BellBaseLayout.cpp @@ -85,4 +85,12 @@ namespace gui rightArrow->setVisible(true); rightArrow->setEdges(RectangleEdge::None); } + + void BellBaseLayout::setArrowVisible(Arrow arrow, bool isVisible) + { + auto item = arrow == Arrow::Left ? leftArrow : rightArrow; + if (item != nullptr) { + item->setVisible(isVisible); + } + } } // namespace gui diff --git a/module-apps/apps-common/widgets/BellBaseLayout.hpp b/module-apps/apps-common/widgets/BellBaseLayout.hpp index 8e48dce70e51dae33454f57f24d5ff3bb40a4a1e..16a216e600ab51a1d66ce8a6bc2e393a7f1eb5d0 100644 --- a/module-apps/apps-common/widgets/BellBaseLayout.hpp +++ b/module-apps/apps-common/widgets/BellBaseLayout.hpp @@ -30,11 +30,19 @@ namespace gui class BellBaseLayout : public VThreeBox { public: + enum class Arrow + { + Left, + Right + }; + explicit BellBaseLayout( Item *parent, Position x = 0, Position y = 0, Length w = 0, Length h = 0, bool withSideArrows = true); [[nodiscard]] Item *getCenterBox() const noexcept; + void setArrowVisible(Arrow arrow, bool isVisible); + private: HThreeBox *centerThreeBox{nullptr}; ImageBox *leftArrow{nullptr}; diff --git a/module-gui/gui/widgets/Spinner.cpp b/module-gui/gui/widgets/Spinner.cpp index f2b65cdb88a16f308c9b6e7e3c7a152545835fba..2aea79d6372b738c9b2036a9938321754f94a442 100644 --- a/module-gui/gui/widgets/Spinner.cpp +++ b/module-gui/gui/widgets/Spinner.cpp @@ -11,8 +11,9 @@ namespace gui { - Spinner::Spinner(int minValue, int maxValue, int step, Boundaries boundaries) - : minValue(minValue), maxValue(maxValue), step(step), currentValue(minValue), boundaries(boundaries) + Spinner::Spinner(int minValue, int maxValue, int step, Boundaries boundaries, OnUpdateCallback cb) + : minValue(minValue), maxValue(maxValue), step(step), currentValue(minValue), + boundaries(boundaries), onUpdate{std::move(cb)} { setEditMode(EditMode::Browse); drawUnderline(false); @@ -106,6 +107,9 @@ namespace gui } outStream << currentValue; setText(outStream.str()); + if (onUpdate) { + onUpdate(currentValue); + } } void Spinner::setMinValue(int newMinValue) { diff --git a/module-gui/gui/widgets/Spinner.hpp b/module-gui/gui/widgets/Spinner.hpp index cede8e43cae8326c0b3eaec60232e8a6c82eea9b..220935fa3c637751a5c9f988bdff37fcc5183612 100644 --- a/module-gui/gui/widgets/Spinner.hpp +++ b/module-gui/gui/widgets/Spinner.hpp @@ -10,7 +10,8 @@ namespace gui class Spinner : public TextFixedSize { public: - Spinner(int minValue, int maxValue, int step, Boundaries boundaries); + using OnUpdateCallback = std::function; + Spinner(int minValue, int maxValue, int step, Boundaries boundaries, OnUpdateCallback cb = nullptr); void setCurrentValue(int newCurrent); void setFixedFieldWidth(unsigned char newFixedFieldWidth); @@ -40,5 +41,7 @@ namespace gui ///< value of 0 means no fixed width. RectangleEdge focusEdges = RectangleEdge::Bottom; void updateSpinner(); + + OnUpdateCallback onUpdate{nullptr}; }; } // namespace gui diff --git a/products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.cpp b/products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.cpp index 23f84c46877141a6df9c01f0b5fd1f1123566928..f7eb13397a54d38f936e71f27384c46560255aa5 100644 --- a/products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.cpp +++ b/products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.cpp @@ -29,21 +29,41 @@ namespace gui setEdges(RectangleEdge::None); setFocusItem(body); - spinner = new Spinner(spinnerMin, spinnerMax, spinnerStep, Boundaries::Fixed); + createSpinner(); + createBottomDescription(); + registerCallbacks(); + } + + void PowerNapListItem::createSpinner() + { + auto onUpdate = [this](int currentValue) { + const auto isMin = currentValue == spinnerMin; + const auto isMax = currentValue == spinnerMax; + body->setArrowVisible(BellBaseLayout::Arrow::Left, not isMin); + body->setArrowVisible(BellBaseLayout::Arrow::Right, not isMax); + }; + + spinner = new Spinner(spinnerMin, spinnerMax, spinnerStep, Boundaries::Fixed, std::move(onUpdate)); spinner->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::h); spinner->setFont(powerNapStyle::napPeriodFont); spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center)); spinner->setEdges(RectangleEdge::None); spinner->setFocusEdges(RectangleEdge::None); body->getCenterBox()->addWidget(spinner); + } + void PowerNapListItem::createBottomDescription() + { bottomDescription = new Label(body->lastBox); bottomDescription->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::outer_layouts_h); bottomDescription->setFont(powerNapStyle::descriptionFont); bottomDescription->setEdges(RectangleEdge::None); bottomDescription->activeItem = false; bottomDescription->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top)); + } + void PowerNapListItem::registerCallbacks() + { dimensionChangedCallback = [&](Item &, const BoundingBox &newDim) -> bool { body->setArea({0, 0, newDim.w, newDim.h}); return true; diff --git a/products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.hpp b/products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.hpp index cc0286f98ae10c352e4a5ff6a0c1fb40df7d2719..0930bf5223ee58855d8f1ea8c6808c247bf1b26b 100644 --- a/products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.hpp +++ b/products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.hpp @@ -14,8 +14,12 @@ namespace gui Spinner *spinner = nullptr; Label *bottomDescription = nullptr; + void createSpinner(); + void createBottomDescription(); + void registerCallbacks(); + public: - explicit PowerNapListItem(); + PowerNapListItem(); [[nodiscard]] int getSpinnerValue() const noexcept; void setSpinnerValue(int value); diff --git a/products/BellHybrid/apps/application-bell-powernap/models/PowerNapModel.cpp b/products/BellHybrid/apps/application-bell-powernap/models/PowerNapModel.cpp index 508060d8b6ddf0fcc4d7a5cc435127d559e98f86..780da8636318135dc1652a58345e18a3a90d48b4 100644 --- a/products/BellHybrid/apps/application-bell-powernap/models/PowerNapModel.cpp +++ b/products/BellHybrid/apps/application-bell-powernap/models/PowerNapModel.cpp @@ -58,5 +58,6 @@ namespace app::powernap powerNapItem = new gui::PowerNapListItem(); internalData.push_back(powerNapItem); powerNapItem->deleteByList = false; + setValue(spinnerDefaultValue); } } // namespace app::powernap