M module-apps/application-meditation/widgets/MeditationTimer.cpp => module-apps/application-meditation/widgets/MeditationTimer.cpp +3 -2
@@ 7,7 7,7 @@
#include <GuiTimer.hpp>
#include <purefs/filesystem_paths.hpp>
#include <service-audio/AudioServiceAPI.hpp>
-#include <apps-common/widgets/ProgressTimer.hpp>
+#include <apps-common/widgets/ProgressTimerWithBarGraphAndCounter.hpp>
#include <gsl/assert>
@@ 55,7 55,8 @@ namespace gui
text->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
text->setEditMode(EditMode::Browse);
- timer = std::make_unique<app::ProgressTimer>(application, *this, meditationTimerName, timerTick);
+ timer = std::make_unique<app::ProgressTimerWithBarGraphAndCounter>(
+ application, *this, meditationTimerName, timerTick);
timer->attach(progressBar);
timer->attach(text);
auto intervalCallback = [app = application] {
M module-apps/application-meditation/widgets/MeditationTimer.hpp => module-apps/application-meditation/widgets/MeditationTimer.hpp +2 -2
@@ 12,7 12,7 @@
namespace app
{
- class ProgressTimer;
+ class ProgressTimerWithBarGraphAndCounter;
}
namespace gui
@@ 40,6 40,6 @@ namespace gui
app::ApplicationMeditation *application = nullptr;
CircularProgressBar *progressBar = nullptr;
Text *text = nullptr;
- std::unique_ptr<app::ProgressTimer> timer;
+ std::unique_ptr<app::ProgressTimerWithBarGraphAndCounter> timer;
};
} // namespace gui
M module-apps/apps-common/CMakeLists.txt => module-apps/apps-common/CMakeLists.txt +1 -0
@@ 50,6 50,7 @@ target_sources(apps-common
widgets/TimeWidget.cpp
widgets/WidgetsUtils.cpp
widgets/ProgressTimer.cpp
+ widgets/ProgressTimerWithBarGraphAndCounter.cpp
windows/AppWindow.cpp
windows/BrightnessWindow.cpp
windows/Dialog.cpp
M module-apps/apps-common/widgets/ProgressTimer.cpp => module-apps/apps-common/widgets/ProgressTimer.cpp +1 -52
@@ 8,10 8,6 @@
#include <apps-common/GuiTimer.hpp>
#include <gsl/assert>
-namespace
-{
- inline constexpr auto increasingModePrefix = "-";
-}
namespace app
{
@@ 25,45 21,11 @@ namespace app
countdownMode{countdownMode}, displayFormat{displayFormat}
{}
- void ProgressTimer::resetProgress()
- {
- if (progress != nullptr) {
- progress->setValue(0);
- }
- }
-
void ProgressTimer::update()
{
- updateText();
- updateProgress();
app->refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
}
- void ProgressTimer::updateText()
- {
- using utils::time::Duration;
- if (text == nullptr) {
- return;
- }
- const auto secondsRemaining = duration - elapsed;
- const Duration remainingDuration{std::time_t{secondsRemaining.count()}};
- UTF8 timerText;
- if (countdownMode == ProgressCountdownMode::Increasing && secondsRemaining != std::chrono::seconds::zero()) {
- timerText += increasingModePrefix;
- }
- timerText += remainingDuration.str(displayFormat);
- text->setText(std::move(timerText));
- }
-
- void ProgressTimer::updateProgress()
- {
- if (progress != nullptr) {
- const auto percentage = static_cast<float>(elapsed.count()) / duration.count();
- const auto currentStep = percentage * progress->getMaximum();
- progress->setValue(std::ceil(currentStep));
- }
- }
-
void ProgressTimer::reset(std::chrono::seconds _duration, std::chrono::seconds _interval)
{
Expects(_duration != std::chrono::seconds::zero());
@@ 73,8 35,7 @@ namespace app
interval = _interval;
hasInterval = _interval != std::chrono::seconds::zero();
- updateText();
- resetProgress();
+ update();
}
void ProgressTimer::start()
@@ 138,16 99,4 @@ namespace app
{
onIntervalCallback = std::move(cb);
}
-
- void ProgressTimer::attach(gui::Progress *_progress)
- {
- Expects(_progress != nullptr);
- progress = _progress;
- }
-
- void ProgressTimer::attach(gui::Text *_text)
- {
- Expects(_text != nullptr);
- text = _text;
- }
} // namespace app
M module-apps/apps-common/widgets/ProgressTimer.hpp => module-apps/apps-common/widgets/ProgressTimer.hpp +4 -11
@@ 15,8 15,6 @@ namespace
namespace gui
{
class Item;
- class Text;
- class Progress;
} // namespace gui
namespace app
@@ 41,10 39,9 @@ namespace app
{
app::ApplicationCommon *app = nullptr;
gui::Item &parent;
- gui::Text *text = nullptr;
- gui::Progress *progress = nullptr;
const std::string name;
+ protected:
std::atomic_bool isRunning{false};
std::chrono::seconds duration{std::chrono::seconds::zero()};
std::chrono::seconds elapsed{std::chrono::seconds::zero()};
@@ 60,14 57,13 @@ namespace app
utils::time::Duration::DisplayedFormat displayFormat;
void startTimer();
- void update();
- void updateText();
- void updateProgress();
- void resetProgress();
+
[[nodiscard]] auto onTimerTimeout(sys::Timer &timerTask) -> bool;
[[nodiscard]] auto isFinished() const noexcept -> bool;
[[nodiscard]] auto intervalReached() const noexcept -> bool;
+ virtual void update();
+
public:
ProgressTimer(
app::ApplicationCommon *app,
@@ 83,9 79,6 @@ namespace app
void registerOnFinishedCallback(std::function<void()> cb) override;
void registerOnIntervalCallback(std::function<void()> cb) override;
[[nodiscard]] auto isStopped() const noexcept -> bool override;
-
- void attach(gui::Progress *_progress);
- void attach(gui::Text *_text);
};
} // namespace app
A module-apps/apps-common/widgets/ProgressTimerWithBarGraphAndCounter.cpp => module-apps/apps-common/widgets/ProgressTimerWithBarGraphAndCounter.cpp +60 -0
@@ 0,0 1,60 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "ProgressTimerWithBarGraphAndCounter.hpp"
+#include <Text.hpp>
+#include <ProgressBar.hpp>
+#include <ApplicationCommon.hpp>
+#include <apps-common/GuiTimer.hpp>
+#include <gsl/assert>
+
+namespace
+{
+ inline constexpr auto increasingModePrefix = "-";
+}
+namespace app
+{
+ void ProgressTimerWithBarGraphAndCounter::update()
+ {
+ updateText();
+ updateProgress();
+ ProgressTimer::update();
+ }
+
+ void ProgressTimerWithBarGraphAndCounter::updateText()
+ {
+ using utils::time::Duration;
+ if (text == nullptr) {
+ return;
+ }
+ const auto secondsRemaining = duration - elapsed;
+ const Duration remainingDuration{std::time_t{secondsRemaining.count()}};
+ UTF8 timerText;
+ if (countdownMode == ProgressCountdownMode::Increasing && secondsRemaining != std::chrono::seconds::zero()) {
+ timerText += increasingModePrefix;
+ }
+ timerText += remainingDuration.str(displayFormat);
+ text->setText(std::move(timerText));
+ }
+
+ void ProgressTimerWithBarGraphAndCounter::updateProgress()
+ {
+ if (progress != nullptr) {
+ const auto percentage = static_cast<float>(elapsed.count()) / duration.count();
+ const auto currentStep = percentage * progress->getMaximum();
+ progress->setValue(std::ceil(currentStep));
+ }
+ }
+
+ void ProgressTimerWithBarGraphAndCounter::attach(gui::Progress *_progress)
+ {
+ Expects(_progress != nullptr);
+ progress = _progress;
+ }
+
+ void ProgressTimerWithBarGraphAndCounter::attach(gui::Text *_text)
+ {
+ Expects(_text != nullptr);
+ text = _text;
+ }
+} // namespace app
A module-apps/apps-common/widgets/ProgressTimerWithBarGraphAndCounter.hpp => module-apps/apps-common/widgets/ProgressTimerWithBarGraphAndCounter.hpp +36 -0
@@ 0,0 1,36 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+#pragma once
+
+#include "ProgressTimer.hpp"
+#include <Timers/TimerHandle.hpp>
+#include <time/time_conversion.hpp>
+#include <atomic>
+#include <chrono>
+#include <string>
+
+namespace gui
+{
+ class Text;
+ class Progress;
+} // namespace gui
+
+namespace app
+{
+ class ProgressTimerWithBarGraphAndCounter : public ProgressTimer
+ {
+ gui::Text *text = nullptr;
+ gui::Progress *progress = nullptr;
+
+ void update() override;
+ void updateText();
+ void updateProgress();
+
+ public:
+ using ProgressTimer::ProgressTimer;
+
+ void attach(gui::Progress *_progress);
+ void attach(gui::Text *_text);
+ };
+
+} // namespace app
M module-utils/time/time/time_conversion.hpp => module-utils/time/time/time_conversion.hpp +5 -0
@@ 212,6 212,11 @@ namespace utils
return duration;
}
+ time_t getSeconds() const
+ {
+ return seconds;
+ }
+
time_t getMinutes() const
{
return minutes;
M products/BellHybrid/apps/application-bell-background-sounds/presenter/BGSoundsProgressPresenter.cpp => products/BellHybrid/apps/application-bell-background-sounds/presenter/BGSoundsProgressPresenter.cpp +1 -1
@@ 5,7 5,7 @@
#include "data/BGSoundsCommon.hpp"
#include "widgets/BGSoundsPlayer.hpp"
#include <ApplicationBellBackgroundSounds.hpp>
-#include <apps-common/widgets/ProgressTimer.hpp>
+#include <apps-common/widgets/ProgressTimerWithBarGraphAndCounter.hpp>
#include <common/models/TimeModel.hpp>
#include <service-db/Settings.hpp>
#include <Timers/TimerFactory.hpp>
M products/BellHybrid/apps/application-bell-background-sounds/windows/BGSoundsProgressWindow.cpp => products/BellHybrid/apps/application-bell-background-sounds/windows/BGSoundsProgressWindow.cpp +2 -2
@@ 6,7 6,7 @@
#include "data/BGSoundsStyle.hpp"
#include <apps-common/widgets/BellBaseLayout.hpp>
#include <apps-common/widgets/BarGraph.hpp>
-#include <apps-common/widgets/ProgressTimer.hpp>
+#include <apps-common/widgets/ProgressTimerWithBarGraphAndCounter.hpp>
#include <apps-common/GuiTimer.hpp>
#include <TextFixedSize.hpp>
#include <time/dateCommon.hpp>
@@ 115,7 115,7 @@ namespace gui
}
void BGSoundsProgressWindow::configureTimer()
{
- auto timer = std::make_unique<app::ProgressTimer>(
+ auto timer = std::make_unique<app::ProgressTimerWithBarGraphAndCounter>(
application, *this, bgSoundsTimerName, timerTick, app::ProgressCountdownMode::Increasing);
timer->attach(progressBar);
timer->attach(timerText);
M products/BellHybrid/apps/application-bell-main/CMakeLists.txt => products/BellHybrid/apps/application-bell-main/CMakeLists.txt +4 -0
@@ 5,6 5,8 @@ target_sources(application-bell-main
PRIVATE
ApplicationBellMain.cpp
widgets/BellBattery.cpp
+ widgets/ProgressTimerWithSnoozeTimer.cpp
+ widgets/SnoozeTimer.cpp
windows/BellBatteryShutdownWindow.cpp
windows/BellHomeScreenWindow.cpp
windows/BellMainMenuWindow.cpp
@@ 16,6 18,8 @@ target_sources(application-bell-main
presenters/StateController.cpp
widgets/BellBattery.hpp
+ widgets/ProgressTimerWithSnoozeTimer.hpp
+ widgets/SnoozeTimer.hpp
windows/BellBatteryShutdownWindow.hpp
windows/BellHomeScreenWindow.hpp
M products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.cpp => products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.cpp +22 -0
@@ 92,4 92,26 @@ namespace app::home_screen
getView()->setAlarmTime(alarmModel->getAlarmTime());
stateController->handleAlarmModelReady();
}
+
+ void HomeScreenPresenter::setSnoozeTimer(std::unique_ptr<app::ProgressTimerWithSnoozeTimer> &&_timer)
+ {
+ snoozeTimer = std::move(_timer);
+ }
+
+ void HomeScreenPresenter::startSnoozeTimer(std::chrono::seconds snoozeDuration)
+ {
+ snoozeTimer->reset(snoozeDuration, snoozeTick);
+ snoozeTimer->start();
+ }
+
+ void HomeScreenPresenter::stopSnoozeTimer()
+ {
+ snoozeTimer->start();
+ }
+
+ void HomeScreenPresenter::restartSnoozeTimer(std::chrono::seconds snoozeDuration)
+ {
+ snoozeTimer->reset(snoozeDuration, snoozeTick);
+ }
+
} // namespace app::home_screen
M products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.hpp => products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.hpp +22 -3
@@ 4,6 4,7 @@
#pragma once
#include "models/TemperatureModel.hpp"
+#include "widgets/ProgressTimerWithSnoozeTimer.hpp"
#include <apps-common/BasePresenter.hpp>
#include <common/models/AbstractAlarmModel.hpp>
@@ 39,6 40,14 @@ namespace app::home_screen
class AbstractBatteryModel;
class AbstractTemperatureModel;
+ enum class HeaderViewMode
+ {
+ Empty,
+ AlarmIcon,
+ AlarmIconAndTime,
+ SnoozeCountdown
+ };
+
class AbstractView
{
public:
@@ 46,11 55,9 @@ namespace app::home_screen
/// Alarm widget related API
virtual void setAlarmTriggered() = 0;
- virtual void setAlarmSnoozed() = 0;
virtual void setAlarmActive(bool) = 0;
virtual void setAlarmEdit(bool) = 0;
- virtual void setAlarmVisible(bool) = 0;
- virtual void setAlarmTimeVisible(bool) = 0;
+ virtual void setHeaderViewMode(HeaderViewMode mode) = 0;
virtual std::time_t getAlarmTime() const = 0;
virtual void setAlarmTime(std::time_t time) = 0;
virtual void setAlarmTimeFormat(utils::time::Locale::TimeFormat fmt) = 0;
@@ 84,6 91,10 @@ namespace app::home_screen
virtual void detachTimer() = 0;
virtual void handleAlarmRingingEvent() = 0;
virtual void handleAlarmModelReady() = 0;
+ virtual void setSnoozeTimer(std::unique_ptr<app::ProgressTimerWithSnoozeTimer> &&_timer) = 0;
+ virtual void startSnoozeTimer(std::chrono::seconds snoozeDuration) = 0;
+ virtual void stopSnoozeTimer() = 0;
+ virtual void restartSnoozeTimer(std::chrono::seconds snoozeDuration) = 0;
static constexpr auto defaultTimeout = std::chrono::milliseconds{5000};
};
@@ 115,6 126,12 @@ namespace app::home_screen
void handleAlarmRingingEvent() override;
void handleAlarmModelReady() override;
+ void setSnoozeTimer(std::unique_ptr<app::ProgressTimerWithSnoozeTimer> &&_timer) override;
+
+ void startSnoozeTimer(std::chrono::seconds snoozeDuration);
+ void stopSnoozeTimer();
+ void restartSnoozeTimer(std::chrono::seconds snoozeDuration);
+
private:
ApplicationCommon *app;
sys::TimerHandle timer;
@@ 123,7 140,9 @@ namespace app::home_screen
std::unique_ptr<AbstractTemperatureModel> temperatureModel;
std::unique_ptr<AbstractTimeModel> timeModel;
std::shared_ptr<AbstractController> stateController;
+ std::unique_ptr<ProgressTimerWithSnoozeTimer> snoozeTimer;
static constexpr auto timerName = "HS_timer";
+ static constexpr auto snoozeTick = std::chrono::seconds(1);
};
} // namespace app::home_screen
M products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp => products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp +20 -25
@@ 32,20 32,17 @@ namespace app::home_screen
{
namespace Helpers
{
- auto detachTimer = [](AbstractPresenter &presenter) { presenter.detachTimer(); };
auto switchToMenu = [](AbstractView &view) { view.switchToMenu(); };
auto makeAlarmEditable = [](AbstractView &view) { view.setAlarmEdit(true); };
auto makeAlarmNonEditable = [](AbstractView &view) { view.setAlarmEdit(false); };
- auto hideAlarmTime = [](AbstractView &view) { view.setAlarmTimeVisible(false); };
- auto showAlarmTime = [](AbstractView &view) { view.setAlarmTimeVisible(true); };
auto updateBottomStats =
[](AbstractView &view, AbstractBatteryModel &batteryModel, AbstractTemperatureModel &temperatureModel) {
view.setTemperature(temperatureModel.getTemperature());
view.setBatteryLevelState(batteryModel.getLevelState());
};
- auto setNewAlarmTime = [](AbstractView &view, AbstractAlarmModel &alarmModel) {
- alarmModel.setAlarmTime(view.getAlarmTime());
- };
+ auto setNewAlarmTime = [](AbstractView &view,
+ AbstractAlarmModel &alarmModel,
+ AbstractPresenter &presenter) { alarmModel.setAlarmTime(view.getAlarmTime()); };
auto isAlarmActive = [](AbstractAlarmModel &alarmModel) -> bool { return alarmModel.isActive(); };
auto isSnoozeAllowed = [](AbstractAlarmModel &alarmModel, AbstractController &controller) -> bool {
@@ 110,7 107,7 @@ namespace app::home_screen
alarmModel.update([&]() { presenter.handleAlarmModelReady(); });
view.setAlarmEdit(false);
view.setAlarmActive(false);
- view.setAlarmVisible(false);
+ view.setHeaderViewMode(HeaderViewMode::Empty);
view.setTemperature(temperatureModel.getTemperature());
view.setBatteryLevelState(batteryModel.getLevelState());
};
@@ 126,8 123,7 @@ namespace app::home_screen
controller.snooze(false);
view.setAlarmEdit(false);
view.setAlarmActive(false);
- view.setAlarmVisible(false);
- view.setAlarmTimeVisible(false);
+ view.setHeaderViewMode(HeaderViewMode::Empty);
view.setTemperature(temperatureModel.getTemperature());
};
} // namespace Deactivated
@@ 139,7 135,7 @@ namespace app::home_screen
presenter.spawnTimer();
view.setBottomDescription(utils::translate("app_bell_alarm_deactivated"));
view.setAlarmActive(false);
- view.setAlarmTimeVisible(false);
+ view.setHeaderViewMode(HeaderViewMode::AlarmIcon);
};
auto exit = [](AbstractPresenter &presenter) { presenter.detachTimer(); };
} // namespace DeactivatedWait
@@ 148,8 144,7 @@ namespace app::home_screen
{
auto entry = [](AbstractView &view, AbstractPresenter &presenter) {
view.setAlarmEdit(true);
- view.setAlarmTimeVisible(true);
- view.setAlarmVisible(true);
+ view.setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
};
auto exit = [](AbstractView &view, AbstractPresenter &presenter) {
view.setAlarmEdit(false);
@@ 192,8 187,7 @@ namespace app::home_screen
view.setBottomDescription(utils::time::getBottomDescription(
utils::time::calculateMinutesDifference(view.getAlarmTime(), timeModel.getCurrentTime())));
view.setAlarmActive(true);
- view.setAlarmVisible(true);
- view.setAlarmTimeVisible(true);
+ view.setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
};
auto exit = [](AbstractPresenter &presenter) { presenter.detachTimer(); };
} // namespace ActivatedWait
@@ 207,8 201,7 @@ namespace app::home_screen
controller.snooze(false);
view.setTemperature(temperatureModel.getTemperature());
view.setAlarmActive(true);
- view.setAlarmVisible(true);
- view.setAlarmTimeVisible(true);
+ view.setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
view.setAlarmTime(alarmModel.getAlarmTime());
};
} // namespace Activated
@@ 218,7 211,7 @@ namespace app::home_screen
auto entry =
[](AbstractView &view, AbstractTemperatureModel &temperatureModel, AbstractPresenter &presenter) {
presenter.spawnTimer(defaultAlarmRingingTime);
- view.setAlarmTimeVisible(false);
+ view.setHeaderViewMode(HeaderViewMode::AlarmIcon);
view.setAlarmTriggered();
view.setTemperature(temperatureModel.getTemperature());
};
@@ 231,7 224,7 @@ namespace app::home_screen
presenter.spawnTimer();
alarmModel.turnOff();
alarmModel.activate(false);
- view.setAlarmTimeVisible(false);
+ view.setHeaderViewMode(HeaderViewMode::AlarmIcon);
view.setBottomDescription(Helpers::getGreeting());
view.setAlarmActive(false);
};
@@ 243,8 236,10 @@ namespace app::home_screen
auto entry = [](AbstractView &view, AbstractAlarmModel &alarmModel, AbstractPresenter &presenter) {
presenter.spawnTimer();
alarmModel.snooze();
- view.setAlarmTimeVisible(false);
- view.setAlarmSnoozed();
+ view.setHeaderViewMode(HeaderViewMode::SnoozeCountdown);
+
+ const auto snoozeDuration = alarmModel.getTimeToNextSnooze();
+ presenter.startSnoozeTimer(snoozeDuration);
const auto bottomDescription = utils::translate("app_bellmain_home_screen_bottom_desc") + " " +
std::to_string(alarmModel.getSnoozeDuration()) + " min";
view.setBottomDescription(bottomDescription);
@@ 256,11 251,10 @@ namespace app::home_screen
{
auto entry =
[](AbstractView &view, AbstractPresenter &presenter, AbstractTemperatureModel &temperatureModel) {
- view.setAlarmTimeVisible(false);
- view.setAlarmSnoozed();
+ view.setHeaderViewMode(HeaderViewMode::SnoozeCountdown);
view.setTemperature(temperatureModel.getTemperature());
};
- auto exit = [](AbstractPresenter &presenter) {};
+ auto exit = [](AbstractPresenter &presenter) { presenter.stopSnoozeTimer(); };
} // namespace AlarmSnoozed
class StateMachine
@@ 278,7 272,7 @@ namespace app::home_screen
"Deactivated"_s + event<Events::LightPress>/ Helpers::switchToMenu,
"Deactivated"_s + event<Events::RotateLeftPress> / Helpers::makeAlarmEditable = "DeactivatedEdit"_s,
"Deactivated"_s + event<Events::RotateRightPress> / Helpers::makeAlarmEditable = "DeactivatedEdit"_s,
- "Deactivated"_s + event<Events::DeepUpPress> / Helpers::showAlarmTime = "ActivatedWait"_s,
+ "Deactivated"_s + event<Events::DeepUpPress> = "ActivatedWait"_s,
"Deactivated"_s + event<Events::TimeUpdate> / Helpers::updateBottomStats,
"DeactivatedWait"_s + sml::on_entry<_> / DeactivatedWait::entry,
@@ 316,6 310,7 @@ namespace app::home_screen
"ActivatedWait"_s + event<Events::BackPress> = "Activated"_s,
"ActivatedWait"_s + event<Events::RotateLeftPress> = "ActivatedEdit"_s,
"ActivatedWait"_s + event<Events::RotateRightPress> = "ActivatedEdit"_s,
+ "ActivatedWait"_s + event<Events::AlarmRinging> = "AlarmRinging"_s,
"Activated"_s + sml::on_entry<_> / Activated::entry,
"Activated"_s [not Helpers::isAlarmActive] = "Deactivated"_s,
@@ 323,7 318,7 @@ namespace app::home_screen
"Activated"_s + event<Events::RotateLeftPress> / Helpers::makeAlarmEditable = "ActivatedEdit"_s,
"Activated"_s + event<Events::RotateRightPress> / Helpers::makeAlarmEditable = "ActivatedEdit"_s,
"Activated"_s + event<Events::TimeUpdate> / Helpers::updateBottomStats,
- "Activated"_s + event<Events::DeepDownPress> / Helpers::hideAlarmTime = "DeactivatedWait"_s,
+ "Activated"_s + event<Events::DeepDownPress> = "DeactivatedWait"_s,
"Activated"_s + event<Events::AlarmRinging> = "AlarmRinging"_s,
"ActivatedEdit"_s + sml::on_entry<_> / AlarmEdit::entry,
A products/BellHybrid/apps/application-bell-main/widgets/ProgressTimerWithSnoozeTimer.cpp => products/BellHybrid/apps/application-bell-main/widgets/ProgressTimerWithSnoozeTimer.cpp +42 -0
@@ 0,0 1,42 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "ProgressTimerWithSnoozeTimer.hpp"
+#include "widgets/SnoozeTimer.hpp"
+
+#include <Text.hpp>
+#include <ProgressBar.hpp>
+#include <ApplicationCommon.hpp>
+#include <apps-common/GuiTimer.hpp>
+#include <gsl/assert>
+
+namespace
+{
+ inline constexpr auto increasingModePrefix = "-";
+}
+namespace app
+{
+ void ProgressTimerWithSnoozeTimer::update()
+ {
+ updateTime();
+ ProgressTimer::update();
+ }
+
+ void ProgressTimerWithSnoozeTimer::updateTime()
+ {
+ using utils::time::Duration;
+ if (timer == nullptr) {
+ return;
+ }
+ const auto secondsRemaining = duration - elapsed;
+ const Duration remainingDuration{std::time_t{secondsRemaining.count()}};
+
+ timer->setTime(remainingDuration.getMinutes(), remainingDuration.getSeconds());
+ }
+
+ void ProgressTimerWithSnoozeTimer::attach(gui::SnoozeTimer *_timer)
+ {
+ Expects(_timer != nullptr);
+ timer = _timer;
+ }
+} // namespace app
A products/BellHybrid/apps/application-bell-main/widgets/ProgressTimerWithSnoozeTimer.hpp => products/BellHybrid/apps/application-bell-main/widgets/ProgressTimerWithSnoozeTimer.hpp +32 -0
@@ 0,0 1,32 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+#pragma once
+
+#include <apps-common/widgets/ProgressTimer.hpp>
+#include <Timers/TimerHandle.hpp>
+#include <time/time_conversion.hpp>
+#include <atomic>
+#include <chrono>
+#include <string>
+
+namespace gui
+{
+ class SnoozeTimer;
+} // namespace gui
+
+namespace app
+{
+ class ProgressTimerWithSnoozeTimer : public ProgressTimer
+ {
+ gui::SnoozeTimer *timer = nullptr;
+
+ void update() override;
+ void updateTime();
+
+ public:
+ using ProgressTimer::ProgressTimer;
+
+ void attach(gui::SnoozeTimer *time);
+ };
+
+} // namespace app
A products/BellHybrid/apps/application-bell-main/widgets/SnoozeTimer.cpp => products/BellHybrid/apps/application-bell-main/widgets/SnoozeTimer.cpp +56 -0
@@ 0,0 1,56 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "SnoozeTimer.hpp"
+#include <FontManager.hpp>
+#include <RawFont.hpp>
+#include <gui/widgets/Label.hpp>
+#include <gui/widgets/ImageBox.hpp>
+#include <apps-common/widgets/TimeSetSpinner.hpp>
+
+namespace gui
+{
+ SnoozeTimer::SnoozeTimer(Item *parent, Position x, Position y, Length w, Length h) : HBox(parent, x, y, w, h)
+ {
+ setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+ setEdges(RectangleEdge::None);
+
+ auto alarmImg = new ImageBox(this, 0, 0, 0, 0, new Image("bell_alarm_snooze_W_M"));
+ alarmImg->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+ alarmImg->setMargins(Margins(10U, 0, 10U, 0));
+ alarmImg->setMinimumSizeToFitImage();
+
+ minusText = new TextFixedSize(this, 0, 0, 0, 0);
+ minusText->setText("-");
+ minusText->setFont(style::window::font::largelight);
+ minusText->setMargins(Margins(0, 0, 0, 0));
+ minusText->setMinimumHeightToFitText();
+ minusText->setMinimumWidthToFitText();
+ minusText->drawUnderline(false);
+ minusText->setEditMode(EditMode::Browse);
+ minusText->activeItem = false;
+ minusText->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Center));
+
+ timeSpinner = new TimeSetSpinner(this);
+ timeSpinner->setFont(style::window::font::largelight);
+ timeSpinner->setEditMode(EditMode::Browse);
+ timeSpinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+ timeSpinner->setMargins(Margins(0, 0, 10U, 0));
+ timeSpinner->setEdges(RectangleEdge::None);
+
+ resizeItems();
+ }
+
+ auto SnoozeTimer::setFont(std::string newFontName) noexcept -> void
+ {
+ fontName = std::move(newFontName);
+ minusText->setFont(fontName);
+ timeSpinner->setFont(fontName);
+ }
+
+ auto SnoozeTimer::setTime(std::uint8_t mins, std::uint8_t secs) noexcept -> void
+ {
+ timeSpinner->setTime(mins, secs);
+ }
+
+} /* namespace gui */
A products/BellHybrid/apps/application-bell-main/widgets/SnoozeTimer.hpp => products/BellHybrid/apps/application-bell-main/widgets/SnoozeTimer.hpp +42 -0
@@ 0,0 1,42 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <gui/widgets/BoxLayout.hpp>
+#include <gui/widgets/Style.hpp>
+#include <gui/widgets/TextFixedSize.hpp>
+#include <gui/widgets/TextConstants.hpp>
+#include <time/time_locale.hpp>
+#include <string>
+
+namespace gui
+{
+ class TimeSetSpinner;
+ class ImageBox;
+
+ class SnoozeTimer : public HBox
+ {
+ public:
+ enum class Status
+ {
+ UNKNOWN,
+ RINGING,
+ ACTIVATED,
+ DEACTIVATED,
+ SNOOZE
+ };
+
+ explicit SnoozeTimer(Item *parent = nullptr, Position x = 0U, Position y = 0U, Length w = 0U, Length h = 0U);
+
+ auto setFont(std::string newFontName) noexcept -> void;
+ auto setTime(std::uint8_t mins, std::uint8_t secs) noexcept -> void;
+
+ private:
+ TimeSetSpinner *timeSpinner = nullptr;
+ TextFixedSize *minusText = nullptr;
+
+ Status alarmStatus = Status::DEACTIVATED;
+ std::string fontName = style::window::font::largelight;
+ };
+} /* namespace gui */
M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp => products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp +39 -12
@@ 3,6 3,7 @@
#include "BellHomeScreenWindow.hpp"
#include "data/BellMainStyle.hpp"
+#include "widgets/SnoozeTimer.hpp"
#include <application-bell-main/ApplicationBellMain.hpp>
#include <apps-common/widgets/BellBaseLayout.hpp>
@@ 66,6 67,8 @@ namespace
tm.tm_min--;
}
}
+ inline constexpr auto snoozeTimerName = "SnoozeTimer";
+ inline constexpr std::chrono::seconds timerTick{1};
} // namespace
namespace gui
@@ 98,6 101,10 @@ namespace gui
alarm->setAlarmStatus(AlarmSetSpinner::Status::DEACTIVATED);
alarm->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+ snoozeTimer = new SnoozeTimer(body->firstBox);
+ snoozeTimer->setMinimumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
+ snoozeTimer->setVisible(false);
+
time = new TimeSetFmtSpinner(body->centerBox);
time->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::h);
time->setFont(bellMainStyle::mainWindow::time::font);
@@ 125,6 132,11 @@ namespace gui
bottomText->drawUnderline(false);
body->resize();
+
+ auto timer = std::make_unique<app::ProgressTimerWithSnoozeTimer>(
+ application, *this, snoozeTimerName, timerTick, app::ProgressCountdownMode::Increasing);
+ timer->attach(snoozeTimer);
+ presenter->setSnoozeTimer(std::move(timer));
}
void BellHomeScreenWindow::setAlarmTriggered()
@@ 132,11 144,6 @@ namespace gui
alarm->setAlarmStatus(AlarmSetSpinner::Status::RINGING);
}
- void BellHomeScreenWindow::setAlarmSnoozed()
- {
- alarm->setAlarmStatus(AlarmSetSpinner::Status::SNOOZE);
- }
-
void BellHomeScreenWindow::setAlarmActive(bool val)
{
if (val) {
@@ 147,14 154,34 @@ namespace gui
}
}
- void BellHomeScreenWindow::setAlarmVisible(bool val)
+ void BellHomeScreenWindow::setHeaderViewMode(app::home_screen::HeaderViewMode mode)
{
- alarm->setVisible(val);
- }
-
- void BellHomeScreenWindow::setAlarmTimeVisible(bool val)
- {
- alarm->setAlarmTimeVisible(val);
+ switch (mode) {
+ case app::home_screen::HeaderViewMode::Empty:
+ alarm->setVisible(false);
+ alarm->setAlarmTimeVisible(false);
+ snoozeTimer->setVisible(false);
+ alarm->informContentChanged();
+ break;
+ case app::home_screen::HeaderViewMode::AlarmIconAndTime:
+ alarm->setVisible(true);
+ alarm->setAlarmTimeVisible(true);
+ snoozeTimer->setVisible(false);
+ alarm->informContentChanged();
+ break;
+ case app::home_screen::HeaderViewMode::AlarmIcon:
+ alarm->setVisible(true);
+ alarm->setAlarmTimeVisible(false);
+ snoozeTimer->setVisible(false);
+ alarm->informContentChanged();
+ break;
+ case app::home_screen::HeaderViewMode::SnoozeCountdown:
+ alarm->setVisible(false);
+ alarm->setAlarmTimeVisible(false);
+ snoozeTimer->setVisible(true);
+ snoozeTimer->informContentChanged();
+ break;
+ }
}
void BellHomeScreenWindow::setTemperature(utils::temperature::Temperature newTemp)
M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.hpp => products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.hpp +3 -3
@@ 31,6 31,7 @@ namespace gui
class TextFixedSize;
class AlarmSetSpinner;
class TimeSetFmtSpinner;
+ class SnoozeTimer;
class BellHomeScreenWindow : public AppWindow, public app::home_screen::AbstractView
{
@@ 46,11 47,9 @@ namespace gui
bool onDatabaseMessage(sys::Message *msg) override;
void setAlarmTriggered() override;
- void setAlarmSnoozed() override;
void setAlarmActive(bool val) override;
void setAlarmEdit(bool val) override;
- void setAlarmVisible(bool val) override;
- void setAlarmTimeVisible(bool val) override;
+ void setHeaderViewMode(app::home_screen::HeaderViewMode mode) override;
std::time_t getAlarmTime() const override;
void setAlarmTime(std::time_t newTime) override;
void incAlarmMinute() override;
@@ 71,6 70,7 @@ namespace gui
BellBattery *battery{};
TextFixedSize *bottomText{};
AlarmSetSpinner *alarm{};
+ SnoozeTimer *snoozeTimer{};
std::unique_ptr<app::home_screen::AbstractPresenter> presenter;
M products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.cpp => products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.cpp +1 -1
@@ 5,7 5,7 @@
#include "application-bell-powernap/ApplicationBellPowerNap.hpp"
#include "data/PowerNapCommon.hpp"
-#include <apps-common/widgets/ProgressTimer.hpp>
+#include <apps-common/widgets/ProgressTimerWithBarGraphAndCounter.hpp>
#include <common/models/TimeModel.hpp>
#include <db/SystemSettings.hpp>
#include <service-db/Settings.hpp>
M products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.cpp => products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.cpp +2 -2
@@ 7,7 7,7 @@
#include "data/PowerNapSwitchData.hpp"
#include <apps-common/widgets/BellBaseLayout.hpp>
#include <apps-common/widgets/BarGraph.hpp>
-#include <apps-common/widgets/ProgressTimer.hpp>
+#include <apps-common/widgets/ProgressTimerWithBarGraphAndCounter.hpp>
#include <apps-common/GuiTimer.hpp>
#include <Text.hpp>
#include <keymap/KeyMap.hpp>
@@ 96,7 96,7 @@ namespace gui
}
void PowerNapProgressWindow::configureTimer()
{
- auto timer = std::make_unique<app::ProgressTimer>(
+ auto timer = std::make_unique<app::ProgressTimerWithBarGraphAndCounter>(
application, *this, powernapTimerName, timerTick, app::ProgressCountdownMode::Increasing);
timer->attach(progressBar);
timer->attach(timerText);
M products/BellHybrid/apps/common/include/common/models/AbstractAlarmModel.hpp => products/BellHybrid/apps/common/include/common/models/AbstractAlarmModel.hpp +2 -0
@@ 3,6 3,7 @@
#pragma once
+#include <chrono>
#include <ctime>
#include <cstdint>
#include <functional>
@@ 26,6 27,7 @@ namespace app
virtual bool isSnoozeActive() = 0;
virtual void turnOff() = 0;
virtual void snooze() = 0;
+ virtual std::chrono::seconds getTimeToNextSnooze() = 0;
/// Command model to update its internal data
virtual void update(AlarmModelReadyHandler callback = AlarmModelReadyHandler()) = 0;
};
M products/BellHybrid/apps/common/include/common/models/AlarmModel.hpp => products/BellHybrid/apps/common/include/common/models/AlarmModel.hpp +2 -0
@@ 36,6 36,7 @@ namespace app
bool isSnoozeActive() override;
void turnOff() override;
void snooze() override;
+ std::chrono::seconds getTimeToNextSnooze() override;
private:
enum class State
@@ 55,6 56,7 @@ namespace app
State state{State::Invalid};
SingleEventRecord cachedRecord;
std::uint32_t snoozeCount = 0;
+ TimePoint nextSnoozeTime = TIME_POINT_INVALID;
std::function<bool(sys::ResponseMessage *)> responseCallback;
M products/BellHybrid/apps/common/src/AlarmModel.cpp => products/BellHybrid/apps/common/src/AlarmModel.cpp +9 -2
@@ 92,6 92,7 @@ namespace app
auto request = AsyncRequest::createFromMessage(std::make_unique<alarms::TurnOffSnoozeRequestMessage>(alarm.ID),
service::name::service_time);
request->execute(app, this, responseCallback);
+ nextSnoozeTime = TIME_POINT_INVALID;
}
bool AlarmModel::isActive() const
{
@@ 122,6 123,7 @@ namespace app
void AlarmModel::turnOff()
{
snoozeCount = 0;
+ nextSnoozeTime = TIME_POINT_INVALID;
alarms::AlarmServiceAPI::requestTurnOffRingingAlarm(app, cachedRecord.parent->ID);
}
@@ 132,9 134,14 @@ namespace app
const auto snoozeDuration = utils::getNumericValue<std::uint32_t>(snoozeDurationStr);
snoozeCount++;
- auto newAlarmTime =
+ nextSnoozeTime =
std::chrono::floor<std::chrono::minutes>(TimePointNow()) + std::chrono::minutes(snoozeDuration);
- alarms::AlarmServiceAPI::requestSnoozeRingingAlarm(app, cachedRecord.parent->ID, newAlarmTime);
+ alarms::AlarmServiceAPI::requestSnoozeRingingAlarm(app, cachedRecord.parent->ID, nextSnoozeTime);
+ }
+
+ std::chrono::seconds AlarmModel::getTimeToNextSnooze()
+ {
+ return std::chrono::duration_cast<std::chrono::seconds>(nextSnoozeTime - TimePointNow());
}
AlarmEventRecord AlarmModel::generateDefaultAlarm() const
M products/BellHybrid/apps/common/src/TimeUtils.cpp => products/BellHybrid/apps/common/src/TimeUtils.cpp +4 -1
@@ 30,7 30,10 @@ namespace utils::time
const auto duration = Duration{timestamp};
const auto timeText = [](time_t hours, time_t minutes) -> std::string {
if (hours == 0) {
- if (minutes == 1) {
+ if (minutes == 0) {
+ return "24 h";
+ }
+ else if (minutes == 1) {
return translate("app_bellmain_home_screen_bottom_desc_less_than") + " 1 min";
}
else {