M module-apps/apps-common/CMakeLists.txt => module-apps/apps-common/CMakeLists.txt +1 -0
@@ 59,6 59,7 @@ target_sources(apps-common
widgets/TimeSetFmtSpinner.cpp
widgets/TimeWidget.cpp
widgets/TimeFixedWidget.cpp
+ widgets/TimeMinuteSecondWidget.cpp
widgets/DigitsContainer.cpp
widgets/WidgetsUtils.cpp
widgets/ProgressTimer.cpp
A module-apps/apps-common/widgets/AbstractProgressTime.hpp => module-apps/apps-common/widgets/AbstractProgressTime.hpp +18 -0
@@ 0,0 1,18 @@
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <time/time_constants.hpp>
+#include <cstdint>
+
+namespace gui
+{
+
+ class AbstractProgressTime
+ {
+ public:
+ virtual ~AbstractProgressTime() = default;
+ virtual void updateTime(std::uint32_t seconds) = 0;
+ };
+} // namespace gui
M module-apps/apps-common/widgets/ProgressTimerWithBarGraphAndCounter.cpp => module-apps/apps-common/widgets/ProgressTimerWithBarGraphAndCounter.cpp +3 -4
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ProgressTimerWithBarGraphAndCounter.hpp"
@@ 46,8 46,7 @@ namespace app
return;
}
const auto secondsRemaining = std::chrono::duration_cast<std::chrono::seconds>(duration - elapsed);
- timeWidget->setMinutesBox(secondsRemaining.count() / 60);
- timeWidget->setSecondsBox(secondsRemaining.count() % 60);
+ timeWidget->updateTime(secondsRemaining.count());
}
void ProgressTimerWithBarGraphAndCounter::updateProgress()
@@ 73,7 72,7 @@ namespace app
text = _text;
}
- void ProgressTimerWithBarGraphAndCounter::attach(gui::TimeFixedWidget *_timeWidget)
+ void ProgressTimerWithBarGraphAndCounter::attach(gui::AbstractProgressTime *_timeWidget)
{
Expects(_timeWidget != nullptr);
timeWidget = _timeWidget;
M module-apps/apps-common/widgets/ProgressTimerWithBarGraphAndCounter.hpp => module-apps/apps-common/widgets/ProgressTimerWithBarGraphAndCounter.hpp +6 -6
@@ 1,9 1,9 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
#include "ProgressTimer.hpp"
-#include "TimeFixedWidget.hpp"
+#include "AbstractProgressTime.hpp"
#include <Timers/TimerHandle.hpp>
#include <time/time_conversion.hpp>
#include <atomic>
@@ 20,9 20,9 @@ namespace app
{
class ProgressTimerWithBarGraphAndCounter : public ProgressTimer
{
- gui::Text *text = nullptr;
- gui::Progress *progress = nullptr;
- gui::TimeFixedWidget *timeWidget = nullptr;
+ gui::Text *text{nullptr};
+ gui::Progress *progress{nullptr};
+ gui::AbstractProgressTime *timeWidget{nullptr};
void update() override;
void updateText();
@@ 34,6 34,6 @@ namespace app
void attach(gui::Progress *_progress);
void attach(gui::Text *_text);
- void attach(gui::TimeFixedWidget *_timeWidget);
+ void attach(gui::AbstractProgressTime *_timeWidget);
};
} // namespace app
M module-apps/apps-common/widgets/TimeFixedWidget.cpp => module-apps/apps-common/widgets/TimeFixedWidget.cpp +7 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "TimeFixedWidget.hpp"
@@ 114,6 114,12 @@ namespace gui
colon->activeItem = false;
}
+ void TimeFixedWidget::updateTime(std::uint32_t sec)
+ {
+ setMinutesBox(sec / utils::time::secondsInMinute);
+ setSecondsBox(sec % utils::time::secondsInMinute);
+ }
+
void TimeFixedWidget::setMinutesBox(std::uint32_t minutes)
{
leftBox.container.setMinutesBox(minutes, getInitialDimensions());
M module-apps/apps-common/widgets/TimeFixedWidget.hpp => module-apps/apps-common/widgets/TimeFixedWidget.hpp +4 -2
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 7,11 7,12 @@
#include <Text.hpp>
#include <BoxLayout.hpp>
#include "widgets/DateWidget.hpp"
+#include "AbstractProgressTime.hpp"
#include <time/FromTillDate.hpp>
namespace gui
{
- class TimeFixedWidget : public Rect
+ class TimeFixedWidget : public Rect, public AbstractProgressTime
{
public:
struct LeftBox
@@ 49,6 50,7 @@ namespace gui
std::uint32_t leftBoxSize,
std::uint32_t rightBoxSize);
+ void updateTime(std::uint32_t sec) override;
void init(std::uint32_t w, std::uint32_t h);
void setMinutesBox(std::uint32_t first);
A module-apps/apps-common/widgets/TimeMinuteSecondWidget.cpp => module-apps/apps-common/widgets/TimeMinuteSecondWidget.cpp +130 -0
@@ 0,0 1,130 @@
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "TimeMinuteSecondWidget.hpp"
+#include <common/LanguageUtils.hpp>
+
+namespace
+{
+ std::vector<std::uint32_t> valueToDigits(std::uint32_t value)
+ {
+ std::vector<std::uint32_t> digits;
+ while (value) {
+ digits.push_back(value % 10);
+ value /= 10;
+ }
+ std::reverse(digits.begin(), digits.end());
+ return digits;
+ }
+
+ namespace digit
+ {
+ constexpr auto width = 340U;
+ constexpr auto height = 95U;
+ constexpr auto topMargin = 30U;
+ constexpr auto digitWidth = 48U;
+ constexpr auto font = style::window::font::supersizeme;
+ } // namespace digit
+
+ namespace description
+ {
+ constexpr auto width = 226U;
+ constexpr auto height = 33U;
+ constexpr auto topMargin = -2;
+ constexpr auto font = style::window::font::big;
+ } // namespace description
+} // namespace
+
+namespace gui
+{
+ TimeMinuteSecondWidget::TimeMinuteSecondWidget(Item *parent,
+ const std::uint32_t &x,
+ const std::uint32_t &y,
+ const std::uint32_t &w,
+ const std::uint32_t &h,
+ DisplayType type)
+ : Rect(parent, x, y, w, h), displayType{type}
+ {
+ buildInterface(w, h);
+ }
+
+ void TimeMinuteSecondWidget::buildInterface(const std::uint32_t w, const std::uint32_t h)
+ {
+ setEdges(gui::RectangleEdge::None);
+ mainBox = new gui::VBox(this, 0, 0, w, h);
+ mainBox->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));
+ mainBox->setEdges(gui::RectangleEdge::None);
+ mainBox->activeItem = false;
+
+ digitsContainer = new gui::HBox(mainBox, 0, 0, digit::width, digit::height);
+ digitsContainer->setAlignment(
+ gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
+ digitsContainer->setEdges(gui::RectangleEdge::None);
+ digitsContainer->setMargins(gui::Margins(0, digit::topMargin, 0, 0));
+
+ for (auto i = 0U; i < maxDigits; i++) {
+ digitBox[i] = new gui::VBox(digitsContainer, 0, 0, digit::digitWidth, digit::height);
+ digitBox[i]->setAlignment(
+ gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
+ digitBox[i]->setEdges(gui::RectangleEdge::None);
+ digitBox[i]->setMargins(gui::Margins(0, 0, 0, 0));
+
+ digitsText[i] = new gui::Label(digitBox[i], 0, 0, 0, 0);
+ digitsText[i]->setEdges(gui::RectangleEdge::None);
+ digitsText[i]->setMaximumSize(digit::width, digit::height);
+ digitsText[i]->setMargins(gui::Margins(0, 0, 0, 0));
+ digitsText[i]->setAlignment(
+ gui::Alignment{gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center});
+ digitsText[i]->setFont(digit::font);
+
+ digitBox[i]->resizeItems();
+ }
+ digitsContainer->resizeItems();
+
+ descriptionBox = new gui::HBox(mainBox, 0, 0, description::width, description::height);
+ descriptionBox->setAlignment(
+ gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
+ descriptionBox->setEdges(gui::RectangleEdge::None);
+ descriptionBox->setMargins(gui::Margins(0, description::topMargin, 0, 0));
+
+ description = new gui::Label(descriptionBox, 0, 0, 0, 0);
+ description->setEdges(gui::RectangleEdge::None);
+ description->setMaximumSize(description::width, description::height);
+ description->setMargins(gui::Margins(0, 0, 0, 0));
+ description->setAlignment(gui::Alignment{gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center});
+ description->setFont(description::font);
+
+ descriptionBox->resizeItems();
+ mainBox->resizeItems();
+ }
+
+ void TimeMinuteSecondWidget::updateTime(std::uint32_t seconds)
+ {
+ if (seconds >= utils::time::secondsInMinute || displayType == DisplayType::OnlyMinutes) {
+ const auto minutes = (seconds + utils::time::secondsInMinute - 1) / utils::time::secondsInMinute;
+ setText(minutes);
+ description->setText(utils::language::getCorrectMinutesNumeralForm(minutes));
+ }
+ else {
+ setText(seconds);
+ description->setText(utils::language::getCorrectSecondsNumeralForm(seconds));
+ }
+ }
+
+ void TimeMinuteSecondWidget::setText(std::uint32_t value)
+ {
+ const auto digits = valueToDigits(value);
+ const auto totalDigits = digits.size();
+
+ for (auto i = 0U; i < maxDigits; i++) {
+ if (i < totalDigits) {
+ digitsText[i]->setText(std::to_string(digits[i]));
+ digitBox[i]->setVisible(true);
+ }
+ else {
+ digitBox[i]->setVisible(false);
+ }
+ }
+ digitsContainer->resizeItems();
+ }
+} /* namespace gui */
A module-apps/apps-common/widgets/TimeMinuteSecondWidget.hpp => module-apps/apps-common/widgets/TimeMinuteSecondWidget.hpp +43 -0
@@ 0,0 1,43 @@
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <Label.hpp>
+#include <BoxLayout.hpp>
+#include "AbstractProgressTime.hpp"
+
+namespace gui
+{
+ class TimeMinuteSecondWidget : public Rect, public AbstractProgressTime
+ {
+ public:
+ enum class DisplayType
+ {
+ MinutesThenSeconds,
+ OnlyMinutes
+ };
+
+ TimeMinuteSecondWidget(Item *parent,
+ const std::uint32_t &x,
+ const std::uint32_t &y,
+ const std::uint32_t &w,
+ const std::uint32_t &h,
+ DisplayType type = DisplayType::OnlyMinutes);
+
+ void updateTime(std::uint32_t sec) override;
+ void buildInterface(std::uint32_t w, std::uint32_t h);
+ void setText(std::uint32_t value);
+
+ private:
+ DisplayType displayType;
+
+ static constexpr auto maxDigits{3U};
+ VBox *mainBox{nullptr};
+ HBox *descriptionBox{nullptr};
+ HBox *digitsContainer{nullptr};
+ VBox *digitBox[maxDigits]{nullptr};
+ Label *digitsText[maxDigits]{nullptr};
+ Label *description{nullptr};
+ };
+} // namespace gui
M products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.cpp => products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.cpp +6 -2
@@ 77,8 77,12 @@ namespace app::focus
clock->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
clock->setMargins(gui::Margins(0, runningStyle::clock::marginTop, 0, 0));
- timer = new gui::TimeFixedWidget(mainVBox, 0, 0, runningStyle::timer::maxSizeX, runningStyle::timer::maxSizeY);
- timer->setFontAndDimensions(runningStyle::timer::font);
+ timer = new gui::TimeMinuteSecondWidget(mainVBox,
+ 0,
+ 0,
+ runningStyle::timer::maxSizeX,
+ runningStyle::timer::maxSizeY,
+ gui::TimeMinuteSecondWidget::DisplayType::MinutesThenSeconds);
timer->setMinimumSize(runningStyle::timer::maxSizeX, runningStyle::timer::maxSizeY);
timer->setMargins(gui::Margins(0, runningStyle::timer::marginTop, 0, 0));
timer->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
M products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.hpp => products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.hpp +8 -8
@@ 8,7 8,7 @@
#include <Text.hpp>
#include <apps-common/widgets/BarGraph.hpp>
-#include <apps-common/widgets/TimeFixedWidget.hpp>
+#include <apps-common/widgets/TimeMinuteSecondWidget.hpp>
#include <common/widgets/BellStatusClock.hpp>
#include <gui/widgets/Icon.hpp>
#include <apps-common/windows/AppWindow.hpp>
@@ 35,13 35,13 @@ namespace app::focus
private:
std::unique_ptr<FocusTimerContract::Presenter> presenter;
- gui::VBox *mainVBox = nullptr;
- gui::ArcProgressBar *progress = nullptr;
- gui::TimeFixedWidget *timer = nullptr;
- gui::TextFixedSize *bottomDescription = nullptr;
- gui::Icon *iconPause = nullptr;
- gui::Icon *iconRing = nullptr;
- gui::BellStatusClock *clock = nullptr;
+ gui::VBox *mainVBox{nullptr};
+ gui::ArcProgressBar *progress{nullptr};
+ gui::TimeMinuteSecondWidget *timer{nullptr};
+ gui::TextFixedSize *bottomDescription{nullptr};
+ gui::Icon *iconPause{nullptr};
+ gui::Icon *iconRing{nullptr};
+ gui::BellStatusClock *clock{nullptr};
void setTime(std::time_t newTime) override;
void setTimeFormat(utils::time::Locale::TimeFormat fmt) override;