M harmony_changelog.md => harmony_changelog.md +1 -0
@@ 13,6 13,7 @@
* Added entering WFI when CPU is idle to reduce power consumption
* Added switching SDRAM to self-refresh before entering WFI for further power consumption reduction
* Added watchdog protection to WFI mode
+* Added low battery warning when the alarm is activated
### Changed / Improved
M image/system_a/data/lang/Deutsch.json => image/system_a/data/lang/Deutsch.json +1 -0
@@ 116,6 116,7 @@
"app_bell_turn_off_question": "Schalten Sie das Ger\u00e4t aus?",
"app_bell_welcome_charge_message": "<text>Charge Harmony<br/>und leicht dr\u00fccken</text>",
"app_bell_welcome_message": "<text>Mudita Harmony<br/>ist ausgeschaltet</text>",
+ "app_bell_alarm_lowBattery_info": "Lade deinen Harmony, damit der Wecker auch sicher klingelt",
"app_bellmain_alarm": "Alarm",
"app_bellmain_bedtime": "Schlafenzeit",
"app_bellmain_home_screen_bottom_desc": "Der n\u00e4chste Alarm klingelt",
M image/system_a/data/lang/English.json => image/system_a/data/lang/English.json +1 -0
@@ 150,6 150,7 @@
"app_bell_turn_off_question": "Turn off Mudita Harmony?",
"app_bell_welcome_charge_message": "<text>Charge Harmony<br/>and press light click</text>",
"app_bell_welcome_message": "<text>Mudita Harmony<br/>is switched OFF</text>",
+ "app_bell_alarm_lowBattery_info": "Charge your Harmony to make sure your alarm will ring",
"app_bellmain_alarm": "Alarm",
"app_bellmain_bedtime": "Bedtime",
"app_bellmain_home_screen_bottom_desc": "Next alarm will ring",
M image/system_a/data/lang/Espanol.json => image/system_a/data/lang/Espanol.json +1 -0
@@ 115,6 115,7 @@
"app_bell_turn_off_question": "\u00bfApagar Mudita Harmony?",
"app_bell_welcome_charge_message": "<text>Carga tu Harmony<br/>y pulsa levemente</text>",
"app_bell_welcome_message": "<text>Mudita Harmony<br/>est\u00e1 apagado</text>",
+ "app_bell_alarm_lowBattery_info": "Carga tu Harmony para asegurarte de que suene la alarma",
"app_bellmain_alarm": "Alarma",
"app_bellmain_bedtime": "Hora de dormir",
"app_bellmain_home_screen_bottom_desc": "La siguiente alarma sonar\u00e1",
M image/system_a/data/lang/Francais.json => image/system_a/data/lang/Francais.json +1 -0
@@ 117,6 117,7 @@
"app_bell_turn_off_question": "\u00c9teindre l'appareil ?",
"app_bell_welcome_charge_message": "<text>Rechargez Harmony<br/>et appuyez l\u00e9g\u00e8rement</text>",
"app_bell_welcome_message": "<text>Mudita Harmony<br/>est d\u00e9sactiv\u00e9</text>",
+ "app_bell_alarm_lowBattery_info": "Chargez votre Harmony pour vous assurer que l'alarme sonne",
"app_bellmain_alarm": "Alarme",
"app_bellmain_bedtime": "Heure du coucher",
"app_bellmain_home_screen_bottom_desc": "La prochaine alarme sonnera",
M image/system_a/data/lang/Polski.json => image/system_a/data/lang/Polski.json +1 -0
@@ 116,6 116,7 @@
"app_bell_turn_off_question": "Wy\u0142\u0105czy\u0107 Mudita Harmony?",
"app_bell_welcome_charge_message": "<text>Na\u0142aduj Harmony<br/>i kliknij lekko</text>",
"app_bell_welcome_message": "<text>Mudita Harmony<br/>jest wy\u0142\u0105czony</text>",
+ "app_bell_alarm_lowBattery_info": "Naładuj Harmony aby mieć pewność, że alarm zadzwoni",
"app_bellmain_alarm": "Alarm",
"app_bellmain_bedtime": "Pora snu",
"app_bellmain_home_screen_bottom_desc": "Alarm zadzwoni",
M products/BellHybrid/apps/Application.cpp => products/BellHybrid/apps/Application.cpp +6 -3
@@ 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 <Application.hpp>
@@ 48,6 48,7 @@ namespace app
alarmModel = std::make_unique<app::AlarmModel>(this);
alarmModel->update(nullptr);
+ batteryModel = std::make_unique<app::BatteryModel>(this);
return sys::ReturnCodes::Success;
}
@@ 60,14 61,16 @@ namespace app
case ID::AlarmActivated:
windowsFactory.attach(
window::alarm_activated_window, [this](app::ApplicationCommon *app, const std::string &name) {
- auto presenter = std::make_unique<app::popup::AlarmActivatedPresenter>(*alarmModel);
+ auto presenter =
+ std::make_unique<app::popup::AlarmActivatedPresenter>(*alarmModel, *batteryModel);
return std::make_unique<gui::AlarmActivatedWindow>(app, std::move(presenter));
});
break;
case ID::AlarmDeactivated:
windowsFactory.attach(
window::alarm_deactivated_window, [this](app::ApplicationCommon *app, const std::string &name) {
- auto presenter = std::make_unique<app::popup::AlarmActivatedPresenter>(*alarmModel);
+ auto presenter =
+ std::make_unique<app::popup::AlarmActivatedPresenter>(*alarmModel, *batteryModel);
return std::make_unique<gui::AlarmDeactivatedWindow>(app, std::move(presenter));
});
break;
M products/BellHybrid/apps/application-bell-alarm/ApplicationBellAlarm.cpp => products/BellHybrid/apps/application-bell-alarm/ApplicationBellAlarm.cpp +2 -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
#include "ApplicationBellAlarm.hpp"
@@ 53,7 53,7 @@ namespace app
});
windowsFactory.attach(gui::window::name::bellAlarmSet, [&](ApplicationCommon *app, const std::string &) {
- auto alarmPresenter = std::make_unique<bell_alarm::BellAlarmSetPresenter>(app, *alarmModel);
+ auto alarmPresenter = std::make_unique<bell_alarm::BellAlarmSetPresenter>(app, *alarmModel, *batteryModel);
return std::make_unique<gui::BellAlarmSetWindow>(app, std::move(alarmPresenter));
});
M products/BellHybrid/apps/application-bell-alarm/presenter/BellAlarmSetPresenter.cpp => products/BellHybrid/apps/application-bell-alarm/presenter/BellAlarmSetPresenter.cpp +29 -3
@@ 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 "BellAlarmSetPresenter.hpp"
@@ 7,8 7,10 @@
namespace app::bell_alarm
{
- BellAlarmSetPresenter::BellAlarmSetPresenter(app::ApplicationCommon *app, AbstractAlarmModel &alarmModel)
- : app{app}, alarmModel{alarmModel}
+ BellAlarmSetPresenter::BellAlarmSetPresenter(app::ApplicationCommon *app,
+ AbstractAlarmModel &alarmModel,
+ AbstractBatteryModel &batteryModel)
+ : app{app}, alarmModel{alarmModel}, batteryModel{batteryModel}
{}
bool BellAlarmSetPresenter::isAlarmActive() const noexcept
@@ 26,4 28,28 @@ namespace app::bell_alarm
app::manager::Controller::sendAction(
app, app::manager::actions::Launch, std::make_unique<app::ApplicationLaunchData>(app::applicationBellName));
}
+
+ Layout BellAlarmSetPresenter::getLayout()
+ {
+ if (not isAlarmActive()) {
+ layout = Layout::AlarmInactive;
+ }
+ else if (layout == Layout::Undefined) {
+ const auto batteryStatus = batteryModel.getLevelState();
+ const units::SOC soc = batteryStatus.level;
+ const auto state = batteryStatus.state;
+ if (not batteryModel.isBatteryCharging(state) && soc < constants::lowBatteryInfoThreshold) {
+ layout = Layout::LowBatteryInfo;
+ }
+ else {
+ layout = Layout::AlarmInfo;
+ }
+ }
+ return layout;
+ }
+
+ void BellAlarmSetPresenter::lowBatteryInfoHandled()
+ {
+ layout = Layout::AlarmInfo;
+ }
} // namespace app::bell_alarm
M products/BellHybrid/apps/application-bell-alarm/presenter/BellAlarmSetPresenter.hpp => products/BellHybrid/apps/application-bell-alarm/presenter/BellAlarmSetPresenter.hpp +19 -2
@@ 1,10 1,11 @@
-// Copyright (c) 2017-2022, 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 <apps-common/BasePresenter.hpp>
#include <common/models/AbstractAlarmModel.hpp>
+#include <common/models/BatteryModel.hpp>
#include <memory>
namespace app
@@ 14,6 15,14 @@ namespace app
namespace app::bell_alarm
{
+ enum class Layout
+ {
+ Undefined,
+ LowBatteryInfo,
+ AlarmInfo,
+ AlarmInactive
+ };
+
class BellAlarmSetContract
{
public:
@@ 28,21 37,29 @@ namespace app::bell_alarm
virtual time_t getAlarmTime() const noexcept = 0;
virtual bool isAlarmActive() const noexcept = 0;
virtual void activate() = 0;
+ virtual Layout getLayout() = 0;
+ virtual void lowBatteryInfoHandled() = 0;
};
};
class BellAlarmSetPresenter : public BellAlarmSetContract::Presenter
{
public:
- explicit BellAlarmSetPresenter(app::ApplicationCommon *app, AbstractAlarmModel &alarmModel);
+ BellAlarmSetPresenter(app::ApplicationCommon *app,
+ AbstractAlarmModel &alarmModel,
+ AbstractBatteryModel &batteryModel);
time_t getAlarmTime() const noexcept;
bool isAlarmActive() const noexcept;
void activate() override;
+ Layout getLayout();
+ void lowBatteryInfoHandled();
private:
app::ApplicationCommon *app{};
AbstractAlarmModel &alarmModel;
+ AbstractBatteryModel &batteryModel;
+ Layout layout{Layout::Undefined};
};
} // namespace app::bell_alarm
M products/BellHybrid/apps/application-bell-alarm/windows/BellAlarmSetWindow.cpp => products/BellHybrid/apps/application-bell-alarm/windows/BellAlarmSetWindow.cpp +78 -17
@@ 1,8 1,9 @@
-// Copyright (c) 2017-2021, 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 "BellAlarmSetWindow.hpp"
#include "data/BellAlarmStyle.hpp"
+#include <common/data/StyleCommon.hpp>
#include <application-bell-alarm/ApplicationBellAlarm.hpp>
#include <gui/input/InputEvent.hpp>
@@ 10,6 11,11 @@
#include <common/TimeUtils.hpp>
+namespace
+{
+ constexpr std::chrono::seconds screenTimeout{5};
+} // namespace
+
namespace gui
{
BellAlarmSetWindow::BellAlarmSetWindow(app::ApplicationCommon *app,
@@ 24,7 30,7 @@ namespace gui
{
AppWindow::buildInterface();
buildLayout();
- registerCallbacks();
+ resetTimer(screenTimeout);
}
void BellAlarmSetWindow::buildLayout()
@@ 33,41 39,96 @@ namespace gui
header->setTitleVisibility(false);
navBar->setVisible(false);
- icon = new Icon(this, 0, 0, style::window_width, style::window_height, {}, {});
- icon->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
+ switch (presenter->getLayout()) {
+ case app::bell_alarm::Layout::AlarmInactive:
+ buildAlarmInactiveLayout();
+ break;
+ case app::bell_alarm::Layout::LowBatteryInfo:
+ buildLowBatteryLayout();
+ break;
+ case app::bell_alarm::Layout::AlarmInfo:
+ case app::bell_alarm::Layout::Undefined:
+ buildAlarmInfoLayout();
+ break;
+ }
+ }
+
+ void BellAlarmSetWindow::buildLowBatteryLayout()
+ {
+ icon = new Icon(this,
+ 0,
+ 0,
+ style::window_width,
+ style::window_height,
+ "bell_status_battery_lvl0",
+ {},
+ gui::ImageTypeSpecifier::W_G);
+ icon->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));
+ icon->image->setMargins({0, gui::bell_style::warning_icon_top_margin, 0, 0});
+ icon->text->setMaximumWidth(gui::bell_style::warning_text_width);
+ icon->text->setFont(style::window::font::verybiglight);
+ icon->text->setRichText(utils::translate("app_bell_alarm_lowBattery_info"));
+
+ timerCallback = [this](Item &, sys::Timer &timer) {
+ lowBatteryInfoHandled();
+ return true;
+ };
+ }
+
+ void BellAlarmSetWindow::buildAlarmInfoLayout()
+ {
+ icon = new Icon(this, 0, 0, style::window_width, style::window_height, "big_alarm_W_G", {});
+ icon->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));
icon->image->setMargins(
{0, bell_alarm_style::icon::imageTopMargin, 0, bell_alarm_style::icon::imageBottomMargin});
icon->text->setFont(style::window::font::verybiglight);
+ icon->text->setRichText(utils::time::getBottomDescription(
+ utils::time::calculateMinutesDifference(presenter->getAlarmTime(), utils::time::getCurrentTime())));
+
+ timerCallback = [this](Item &, sys::Timer &timer) {
+ presenter->activate();
+ return true;
+ };
}
- void BellAlarmSetWindow::registerCallbacks()
+ void BellAlarmSetWindow::buildAlarmInactiveLayout()
{
+ icon = new Icon(this, 0, 0, style::window_width, style::window_height, "big_no-alarm_W_G", {});
+ icon->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));
+ icon->image->setMargins(
+ {0, bell_alarm_style::icon::imageTopMargin, 0, bell_alarm_style::icon::imageBottomMargin});
+ icon->text->setFont(style::window::font::verybiglight);
+ icon->text->setRichText(utils::translate("app_bell_alarm_set_not_active"));
+
timerCallback = [this](Item &, sys::Timer &timer) {
presenter->activate();
return true;
};
}
- void BellAlarmSetWindow::onBeforeShow(ShowMode mode, SwitchData *data)
+ void BellAlarmSetWindow::rebuild()
{
- WindowWithTimer::onBeforeShow(mode, data);
+ erase();
+ buildInterface();
+ }
- if (presenter->isAlarmActive()) {
- icon->image->set("big_alarm_W_G");
- icon->text->setRichText(utils::time::getBottomDescription(
- utils::time::calculateMinutesDifference(presenter->getAlarmTime(), utils::time::getCurrentTime())));
- }
- else {
- icon->image->set("big_no-alarm_W_G");
- icon->text->setRichText(utils::translate("app_bell_alarm_set_not_active"));
- }
+ void BellAlarmSetWindow::lowBatteryInfoHandled()
+ {
+ presenter->lowBatteryInfoHandled();
+ rebuild();
+ application->refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
}
bool BellAlarmSetWindow::onInput(const InputEvent &inputEvent)
{
if (inputEvent.isShortRelease(KeyCode::KEY_ENTER) || inputEvent.isShortRelease(KeyCode::KEY_RF)) {
detachTimerIfExists();
- presenter->activate();
+ if (presenter->getLayout() == app::bell_alarm::Layout::LowBatteryInfo) {
+ lowBatteryInfoHandled();
+ }
+ else {
+ presenter->activate();
+ }
return true;
}
return false;
M products/BellHybrid/apps/application-bell-alarm/windows/BellAlarmSetWindow.hpp => products/BellHybrid/apps/application-bell-alarm/windows/BellAlarmSetWindow.hpp +6 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, 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
@@ 15,13 15,16 @@ namespace gui
public:
explicit BellAlarmSetWindow(app::ApplicationCommon *app,
std::shared_ptr<app::bell_alarm::BellAlarmSetContract::Presenter> presenter);
+ void rebuild() override;
protected:
void buildInterface() override;
void buildLayout();
- void registerCallbacks();
bool onInput(const InputEvent &inputEvent) override;
- void onBeforeShow(ShowMode mode, SwitchData *data) override;
+ void buildLowBatteryLayout();
+ void buildAlarmInfoLayout();
+ void buildAlarmInactiveLayout();
+ void lowBatteryInfoHandled();
private:
constexpr static auto alarmSummaryDisplayDuration = std::chrono::seconds{5};
M products/BellHybrid/apps/application-bell-main/include/application-bell-main/presenters/HomeScreenPresenter.hpp => products/BellHybrid/apps/application-bell-main/include/application-bell-main/presenters/HomeScreenPresenter.hpp +2 -0
@@ 108,6 108,7 @@ namespace app::home_screen
virtual bool isLowBatteryWarningNeeded() = 0;
virtual void updateBatteryLevelInterval() = 0;
virtual void refreshUserSession() = 0;
+ virtual bool isLowBatteryLevel() const = 0;
static constexpr auto defaultTimeout = std::chrono::milliseconds{5000};
};
@@ 161,6 162,7 @@ namespace app::home_screen
bool isLowBatteryWarningNeeded() override;
void updateBatteryLevelInterval() override;
void refreshUserSession() override;
+ bool isLowBatteryLevel() const override;
void setLayout(gui::LayoutGenerator layoutGenerator) override;
M products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.cpp => products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.cpp +7 -0
@@ 308,4 308,11 @@ namespace app::home_screen
batteryLevelNotificationModel.updateBatteryLevelInterval(getBatteryLvl());
}
+ bool HomeScreenPresenter::isLowBatteryLevel() const
+ {
+ const auto batteryStatus = batteryModel.getLevelState();
+ return not batteryModel.isBatteryCharging(batteryStatus.state) &&
+ (batteryStatus.level < constants::lowBatteryInfoThreshold);
+ }
+
} // namespace app::home_screen
M products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp => products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp +41 -10
@@ 91,6 91,7 @@ namespace app::home_screen
view.setBatteryLevelState(batteryModel.getLevelState());
};
auto switchToBatteryStatus = [](AbstractPresenter &presenter) { presenter.switchToBatteryStatus(); };
+ auto isLowBatteryLevel = [](AbstractPresenter &presenter) { return presenter.isLowBatteryLevel(); };
} // namespace Helpers
@@ 122,7 123,9 @@ namespace app::home_screen
{};
struct BatteryUpdate
{};
- struct LowBatteryWarning
+ struct LowBatterySessionWarning
+ {};
+ struct LowBatteryAlarmWarning
{};
} // namespace Events
@@ 217,6 220,16 @@ namespace app::home_screen
auto exit = [](AbstractView &view, AbstractPresenter &presenter) { presenter.detachTimer(); };
} // namespace ActivatedWait
+ namespace ActivatedLowBattery
+ {
+ auto entry = [](AbstractView &view, AbstractPresenter &presenter, AbstractTimeModel &timeModel) {
+ presenter.spawnTimer();
+ view.setTextDescription(utils::translate("app_bell_alarm_lowBattery_info"));
+ view.setViewState(ViewState::ActivatedLowBattery);
+ };
+ auto exit = [](AbstractView &view, AbstractPresenter &presenter) { presenter.detachTimer(); };
+ } // namespace ActivatedLowBattery
+
namespace Activated
{
auto entry = [](AbstractController &controller,
@@ 303,18 316,20 @@ namespace app::home_screen
"Deactivated"_s + event<Events::LightPress> [not Helpers::isLowBatteryWarningToShow] / Helpers::switchToMenu,
"Deactivated"_s + event<Events::RotateLeftPress> [not Helpers::isLowBatteryWarningToShow] = "DeactivatedEdit"_s,
"Deactivated"_s + event<Events::RotateRightPress> [not Helpers::isLowBatteryWarningToShow] = "DeactivatedEdit"_s,
- "Deactivated"_s + event<Events::DeepUpPress> = "ActivatedWait"_s,
+ "Deactivated"_s + event<Events::DeepUpPress> [not Helpers::isLowBatteryLevel] = "ActivatedWait"_s,
+ "Deactivated"_s + event<Events::LowBatteryAlarmWarning> = "ActivatedLowBattery"_s,
"Deactivated"_s + event<Events::TimeUpdate> / Helpers::updateTemperature,
"Deactivated"_s + event<Events::BackPress> / Helpers::endUserSessionWithDelay,
"Deactivated"_s + event<Events::LongBackPress> [not Helpers::isLowBatteryWarningToShow] / Helpers::switchToBatteryStatus,
"Deactivated"_s + event<Events::BatteryUpdate> / Helpers::updateBatteryStatus,
- "Deactivated"_s + event<Events::LowBatteryWarning> [Helpers::isLowBatteryWarningToShow] / Helpers::showLowBatteryWarning,
+ "Deactivated"_s + event<Events::LowBatterySessionWarning> [Helpers::isLowBatteryWarningToShow] / Helpers::showLowBatteryWarning,
"DeactivatedWait"_s + sml::on_entry<_> / DeactivatedWait::entry,
"DeactivatedWait"_s + sml::on_exit<_> / DeactivatedWait::exit,
"DeactivatedWait"_s + event<Events::Timer> = "Deactivated"_s,
"DeactivatedWait"_s + event<Events::LightPress> = "Deactivated"_s,
- "DeactivatedWait"_s + event<Events::DeepUpPress> = "ActivatedWait"_s,
+ "DeactivatedWait"_s + event<Events::DeepUpPress> [not Helpers::isLowBatteryLevel] = "ActivatedWait"_s,
+ "DeactivatedWait"_s + event<Events::LowBatteryAlarmWarning> = "ActivatedLowBattery"_s,
"DeactivatedWait"_s + event<Events::RotateLeftPress> = "DeactivatedEdit"_s,
"DeactivatedWait"_s + event<Events::RotateRightPress> = "DeactivatedEdit"_s,
"DeactivatedWait"_s + event<Events::BackPress> = "Deactivated"_s,
@@ 325,7 340,8 @@ namespace app::home_screen
"DeactivatedEdit"_s + event<Events::Timer> / AlarmEdit::revertChanges = "Deactivated"_s,
"DeactivatedEdit"_s + event<Events::RotateLeftPress> / AlarmEdit::processRotateLeft,
"DeactivatedEdit"_s + event<Events::RotateRightPress> / AlarmEdit::processRotateRight,
- "DeactivatedEdit"_s + event<Events::DeepUpPress> / Helpers::setNewAlarmTime = "ActivatedWait"_s,
+ "DeactivatedEdit"_s + event<Events::DeepUpPress> [not Helpers::isLowBatteryLevel] / Helpers::setNewAlarmTime = "ActivatedWait"_s,
+ "DeactivatedEdit"_s + event<Events::LowBatteryAlarmWarning> / Helpers::setNewAlarmTime = "ActivatedLowBattery"_s,
"DeactivatedEdit"_s + event<Events::LightPress> / Helpers::setNewAlarmTime = "WaitForConfirmation"_s,
"DeactivatedEdit"_s + event<Events::BackPress> / AlarmEdit::revertChanges = "Deactivated"_s,
"DeactivatedEdit"_s + event<Events::BatteryUpdate> / Helpers::updateBatteryStatus,
@@ 333,12 349,23 @@ namespace app::home_screen
"WaitForConfirmation"_s + sml::on_entry<_> / WaitForConfirmation::entry,
"WaitForConfirmation"_s + sml::on_exit<_> / WaitForConfirmation::exit,
"WaitForConfirmation"_s + event<Events::Timer> = "Deactivated"_s,
- "WaitForConfirmation"_s + event<Events::DeepUpPress> / WaitForConfirmation::action = "ActivatedWait"_s,
+ "WaitForConfirmation"_s + event<Events::DeepUpPress> [not Helpers::isLowBatteryLevel] / WaitForConfirmation::action = "ActivatedWait"_s,
+ "WaitForConfirmation"_s + event<Events::LowBatteryAlarmWarning> / WaitForConfirmation::action = "ActivatedLowBattery"_s,
"WaitForConfirmation"_s + event<Events::LightPress>/ Helpers::switchToMenu = "Deactivated"_s,
"WaitForConfirmation"_s + event<Events::BackPress> = "Deactivated"_s,
"WaitForConfirmation"_s + event<Events::RotateLeftPress> = "DeactivatedEdit"_s,
"WaitForConfirmation"_s + event<Events::RotateRightPress> = "DeactivatedEdit"_s,
+ "ActivatedLowBattery"_s + sml::on_entry<_> / ActivatedLowBattery::entry,
+ "ActivatedLowBattery"_s + sml::on_exit<_> / ActivatedLowBattery::exit,
+ "ActivatedLowBattery"_s + event<Events::Timer> = "ActivatedWait"_s,
+ "ActivatedLowBattery"_s + event<Events::LightPress> = "ActivatedWait"_s,
+ "ActivatedLowBattery"_s + event<Events::DeepDownPress> = "DeactivatedWait"_s,
+ "ActivatedLowBattery"_s + event<Events::BackPress> = "ActivatedWait"_s,
+ "ActivatedLowBattery"_s + event<Events::RotateLeftPress> = "ActivatedEdit"_s,
+ "ActivatedLowBattery"_s + event<Events::RotateRightPress> = "ActivatedEdit"_s,
+ "ActivatedLowBattery"_s + event<Events::AlarmRinging> = "AlarmRinging"_s,
+
"ActivatedWait"_s + sml::on_entry<_> / ActivatedWait::entry,
"ActivatedWait"_s + sml::on_exit<_> / ActivatedWait::exit,
"ActivatedWait"_s + event<Events::Timer> = "Activated"_s,
@@ 360,7 387,7 @@ namespace app::home_screen
"Activated"_s + event<Events::BackPress> / Helpers::endUserSessionWithDelay,
"Activated"_s + event<Events::LongBackPress> [not Helpers::isLowBatteryWarningToShow] / Helpers::switchToBatteryStatus,
"Activated"_s + event<Events::BatteryUpdate> / Helpers::updateBatteryStatus,
- "Activated"_s + event<Events::LowBatteryWarning> [Helpers::isLowBatteryWarningToShow] / Helpers::showLowBatteryWarning,
+ "Activated"_s + event<Events::LowBatterySessionWarning> [Helpers::isLowBatteryWarningToShow] / Helpers::showLowBatteryWarning,
"ActivatedEdit"_s + sml::on_entry<_> / AlarmEdit::entry,
"ActivatedEdit"_s + sml::on_exit<_> / AlarmEdit::exit,
@@ 391,7 418,8 @@ namespace app::home_screen
"AlarmRingingDeactivatedWait"_s + sml::on_entry<_> / AlarmRingingDeactivatedWait::entry,
"AlarmRingingDeactivatedWait"_s + sml::on_exit<_> / AlarmRingingDeactivatedWait::exit,
"AlarmRingingDeactivatedWait"_s + event<Events::Timer> = "Deactivated"_s,
- "AlarmRingingDeactivatedWait"_s + event<Events::DeepUpPress> = "ActivatedWait"_s,
+ "AlarmRingingDeactivatedWait"_s + event<Events::DeepUpPress> [not Helpers::isLowBatteryLevel] = "ActivatedWait"_s,
+ "AlarmRingingDeactivatedWait"_s + event<Events::LowBatteryAlarmWarning> = "ActivatedLowBattery"_s,
"AlarmRingingDeactivatedWait"_s + event<Events::BackPress> = "Deactivated"_s,
"AlarmRingingDeactivatedWait"_s + event<Events::LightPress>/ Helpers::switchToMenu = "Deactivated"_s,
"AlarmRingingDeactivatedWait"_s + event<Events::RotateLeftPress> = "DeactivatedEdit"_s,
@@ 413,7 441,7 @@ namespace app::home_screen
"AlarmSnoozed"_s + event<Events::TimeUpdate> / Helpers::updateTemperature,
"AlarmSnoozed"_s + event<Events::BatteryUpdate> / Helpers::updateBatteryStatus,
"AlarmSnoozed"_s + event<Events::LongBackPress> [not Helpers::isLowBatteryWarningToShow] / Helpers::switchToBatteryStatus,
- "AlarmSnoozed"_s + event<Events::LowBatteryWarning> [Helpers::isLowBatteryWarningToShow] / Helpers::showLowBatteryWarning
+ "AlarmSnoozed"_s + event<Events::LowBatterySessionWarning> [Helpers::isLowBatteryWarningToShow] / Helpers::showLowBatteryWarning
);
// clang-format on
}
@@ 523,6 551,9 @@ namespace app::home_screen
break;
case KeyMap::DeepPressUp:
pimpl->sm->process_event(Events::DeepUpPress{});
+ if (presenter.isLowBatteryLevel()) {
+ pimpl->sm->process_event(Events::LowBatteryAlarmWarning{});
+ }
break;
case KeyMap::DeepPressDown:
pimpl->sm->process_event(Events::DeepDownPress{});
@@ 532,7 563,7 @@ namespace app::home_screen
}
if (key != KeyMap::DeepPressUp && key != KeyMap::DeepPressDown && presenter.isLowBatteryWarningNeeded()) {
- pimpl->sm->process_event(Events::LowBatteryWarning{});
+ pimpl->sm->process_event(Events::LowBatterySessionWarning{});
}
return true;
M products/BellHybrid/apps/application-bell-meditation-timer/presenter/MeditationTimerPresenter.cpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/MeditationTimerPresenter.cpp +2 -9
@@ 11,18 11,11 @@
namespace
{
- using State = Store::Battery::State;
constexpr auto spinnerMax = 180U;
constexpr auto spinnerMin = 1U;
constexpr auto spinnerStep = 1U;
constexpr auto emptyValue = 0U;
constexpr auto defaultValue = 15U;
- constexpr units::SOC lowBatteryThreshold{10};
-
- bool isBatteryCharging(const State state)
- {
- return state == State::Charging or state == State::ChargingDone;
- }
} // namespace
namespace app::meditation
@@ 72,8 65,8 @@ namespace app::meditation
const auto batteryState = batteryModel.getLevelState();
const units::SOC soc = batteryState.level;
- const bool isCharging = isBatteryCharging(batteryState.state);
- if (not lowBatteryInfoModel.isInfoHandled() && not isCharging && soc < lowBatteryThreshold) {
+ const bool isCharging = batteryModel.isBatteryCharging(batteryState.state);
+ if (not lowBatteryInfoModel.isInfoHandled() && not isCharging && soc < constants::lowBatteryInfoThreshold) {
auto lowBatterySwitchData =
std::make_unique<gui::AppsBatteryStatusSwitchData>(soc, isCharging, switchToNextScreen);
app->switchWindow(windows::meditationLowBattery, std::move(lowBatterySwitchData));
M products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationRunningLoopPresenter.cpp => products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationRunningLoopPresenter.cpp +5 -0
@@ 124,4 124,9 @@ namespace app::relaxation
{
return batteryModel.getLevelState();
}
+
+ bool RelaxationRunningLoopPresenter::isBatteryCharging(Store::Battery::State state) const
+ {
+ return batteryModel.isBatteryCharging(state);
+ }
} // namespace app::relaxation
M products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationRunningLoopPresenter.hpp => products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationRunningLoopPresenter.hpp +2 -0
@@ 57,6 57,7 @@ namespace app::relaxation
virtual bool isPaused() = 0;
virtual void onBeforeShow() = 0;
virtual Store::Battery getBatteryState() = 0;
+ virtual bool isBatteryCharging(Store::Battery::State state) const = 0;
};
};
@@ 80,6 81,7 @@ namespace app::relaxation
bool isPaused() override;
void onBeforeShow() override;
Store::Battery getBatteryState() override;
+ bool isBatteryCharging(Store::Battery::State state) const override;
void onFinished();
M products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationTimerSelectPresenter.cpp => products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationTimerSelectPresenter.cpp +10 -0
@@ 47,6 47,16 @@ namespace app::relaxation
return batteryModel.getLevelState();
}
+ bool RelaxationTimerSelectPresenter::isBatteryCharging(Store::Battery::State state) const
+ {
+ return batteryModel.isBatteryCharging(state);
+ }
+
+ bool RelaxationTimerSelectPresenter::isBatteryBelowLowLevelThreshold(units::SOC soc) const
+ {
+ return soc < constants::lowBatteryInfoThreshold;
+ }
+
bool RelaxationTimerSelectPresenter::isLowBatteryWindowHandled() const
{
return lowBatteryInfoModel.isInfoHandled();
M products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationTimerSelectPresenter.hpp => products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationTimerSelectPresenter.hpp +4 -0
@@ 43,6 43,8 @@ namespace app::relaxation
virtual std::chrono::minutes getCurrentTimerValue() const = 0;
virtual void setTimerValue(std::chrono::minutes) = 0;
virtual Store::Battery getBatteryState() = 0;
+ virtual bool isBatteryCharging(Store::Battery::State state) const = 0;
+ virtual bool isBatteryBelowLowLevelThreshold(units::SOC soc) const = 0;
[[nodiscard]] virtual bool isLowBatteryWindowHandled() const = 0;
virtual void handleLowBatteryWindow() = 0;
};
@@ 58,6 60,8 @@ namespace app::relaxation
std::chrono::minutes getCurrentTimerValue() const override;
void setTimerValue(std::chrono::minutes) override;
Store::Battery getBatteryState() override;
+ bool isBatteryCharging(Store::Battery::State state) const override;
+ bool isBatteryBelowLowLevelThreshold(units::SOC soc) const override;
[[nodiscard]] bool isLowBatteryWindowHandled() const override;
void handleLowBatteryWindow() override;
M products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationRunningLoopWindow.cpp => products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationRunningLoopWindow.cpp +1 -7
@@ 13,7 13,6 @@
namespace
{
- using State = Store::Battery::State;
constexpr auto relaxationLoopTimerName{"RelaxationLoopTimer"};
constexpr std::chrono::seconds relaxationLoopTimerPeriod{1};
constexpr units::SOC dischargingLevelShowTop{20};
@@ 22,11 21,6 @@ namespace
/* charsMultiplier is set a little bit less than max lines which is 2, because of final text formatting */
constexpr auto charsMultiplier{1.8f};
- bool isBatteryCharging(const State state)
- {
- return state == State::Charging or state == State::ChargingDone;
- }
-
gui::Text *createTitle(gui::VBox *parent)
{
namespace relaxationStyle = gui::relaxationStyle;
@@ 217,7 211,7 @@ namespace gui
auto state = batteryStatus.state;
if (soc < dischargingLevelShowTop) {
- battery->update(soc, isBatteryCharging(state));
+ battery->update(soc, presenter->isBatteryCharging(state));
bottomText->setVisible(false);
battery->setVisible(true);
battery->informContentChanged();
M products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationTimerSelectWindow.cpp => products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationTimerSelectWindow.cpp +3 -9
@@ 14,12 14,10 @@
namespace
{
- using State = Store::Battery::State;
using minutes = std::chrono::minutes;
using namespace std::chrono_literals;
constexpr minutes onceValue{minutes::zero()};
constexpr minutes loopValue{8760h};
- constexpr units::SOC lowBatteryThreshold{10};
const std::string getOnceValueText()
{
@@ 62,11 60,6 @@ namespace
}
return range;
}
-
- bool isBatteryCharging(const State state)
- {
- return state == State::Charging or state == State::ChargingDone;
- }
} // namespace
namespace gui
{
@@ 202,8 195,9 @@ namespace gui
const auto batteryState = presenter->getBatteryState();
const units::SOC soc = batteryState.level;
- const bool isCharging = isBatteryCharging(batteryState.state);
- if (not presenter->isLowBatteryWindowHandled() && not isCharging && soc < lowBatteryThreshold) {
+ const bool isCharging = presenter->isBatteryCharging(batteryState.state);
+ if (not presenter->isLowBatteryWindowHandled() && not isCharging &&
+ presenter->isBatteryBelowLowLevelThreshold(soc)) {
auto lowBatterySwitchData =
std::make_unique<AppsBatteryStatusSwitchData>(soc, isCharging, switchToNextScreen);
lowBatterySwitchData->ignoreCurrentWindowOnStack = true;
M products/BellHybrid/apps/common/include/common/data/StyleCommon.hpp => products/BellHybrid/apps/common/include/common/data/StyleCommon.hpp +4 -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
#pragma once
@@ 15,6 15,9 @@ namespace gui::bell_style
inline constexpr auto popup_icon_top_margin = 120;
inline constexpr auto popup_icon_bottom_margin = 30;
+ inline constexpr auto warning_icon_top_margin = 100;
+ inline constexpr auto warning_text_width = 400;
+
} // namespace gui::bell_style
namespace itStyle
M products/BellHybrid/apps/common/include/common/layouts/BaseHomeScreenLayoutProvider.hpp => products/BellHybrid/apps/common/include/common/layouts/BaseHomeScreenLayoutProvider.hpp +2 -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
#pragma once
@@ 18,6 18,7 @@ namespace app::home_screen
DeactivatedWait,
WaitForConfirmation,
AlarmEdit,
+ ActivatedLowBattery,
ActivatedWait,
Activated,
AlarmRinging,
M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassic.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassic.hpp +10 -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
#pragma once
@@ 27,6 27,7 @@ namespace gui
class BellBattery;
class BellConnectionStatus;
class DuoHBox;
+ class Icon;
enum class LayoutClassicVersion
{
@@ 44,6 45,12 @@ namespace gui
SnoozeIconAndTime,
};
+ enum class ScreenViewMode
+ {
+ Main,
+ Warning
+ };
+
class HomeScreenLayoutClassic : public BaseHomeScreenLayoutProvider, protected BellBaseLayout
{
public:
@@ 66,6 73,7 @@ namespace gui
protected:
void setHeaderViewMode(HeaderViewMode mode);
+ void setScreenMode(ScreenViewMode mode);
virtual void buildInterface();
virtual bool isBatteryVisibilityAllowed(const Store::Battery &batteryContext);
void removeTextDescription();
@@ 85,5 93,6 @@ namespace gui
TextFixedSize *bottomText = nullptr;
AlarmSetSpinner *alarm = nullptr;
SnoozeTimer *snoozeTimer = nullptr;
+ Icon *lowBatteryWarning = nullptr;
};
}; // namespace gui
M products/BellHybrid/apps/common/include/common/models/BatteryModel.hpp => products/BellHybrid/apps/common/include/common/models/BatteryModel.hpp +9 -1
@@ 1,10 1,11 @@
-// Copyright (c) 2017-2021, 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 <module-utils/EventStore/EventStore.hpp>
#include <service-db/Settings.hpp>
+#include <Units.hpp>
#include <cstdint>
#include <functional>
@@ 17,12 18,18 @@ namespace app
namespace app
{
+ namespace constants
+ {
+ inline constexpr units::SOC lowBatteryInfoThreshold{10};
+ }
+
class AbstractBatteryModel
{
public:
virtual ~AbstractBatteryModel() noexcept = default;
virtual Store::Battery getLevelState() const = 0;
+ virtual bool isBatteryCharging(Store::Battery::State state) const = 0;
};
class BatteryModel : public AbstractBatteryModel
@@ 30,6 37,7 @@ namespace app
public:
explicit BatteryModel(app::ApplicationCommon *app);
Store::Battery getLevelState() const;
+ bool isBatteryCharging(Store::Battery::State state) const;
private:
mutable settings::Settings settings;
M => +5 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, 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
@@ 18,13 18,16 @@ namespace gui
public:
AlarmActivatedWindow(app::ApplicationCommon *app,
std::shared_ptr<app::popup::AlarmActivatedPresenter> presenter);
void rebuild() override;
private:
bool onInput(const InputEvent &inputEvent) override;
void buildInterface() override;
void onBeforeShow(ShowMode mode, SwitchData *data) override;
void returnToPreviousWindow();
void setAlarmTime(time_t alarmTime);
void buildLowBatteryLayout();
void buildAlarmInfoLayout();
void lowBatteryInfoHandled();
Icon *icon{};
};
M => +16 -2
@@ 1,15 1,23 @@
// 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 <apps-common/BasePresenter.hpp>
#include <common/models/AbstractAlarmModel.hpp>
#include <common/models/BatteryModel.hpp>
#include <memory>
namespace app::popup
{
enum class Layout
{
Undefined,
LowBatteryInfo,
AlarmInfo
};
class AlarmActivatedContract
{
public:
@@ 38,18 46,24 @@ namespace app::popup
virtual ~Presenter() noexcept = default;
virtual time_t getAlarmTime() const noexcept = 0;
virtual bool isAlarmActive() const noexcept = 0;
virtual Layout getLayout() = 0;
virtual void lowBatteryInfoHandled() = 0;
};
};
class AlarmActivatedPresenter : public AlarmActivatedContract::Presenter
{
public:
AlarmActivatedPresenter(AbstractAlarmModel &alarmModel);
AlarmActivatedPresenter(AbstractAlarmModel &alarmModel, AbstractBatteryModel &batteryModel);
time_t getAlarmTime() const noexcept;
bool isAlarmActive() const noexcept;
Layout getLayout();
void lowBatteryInfoHandled();
private:
AbstractAlarmModel &alarmModel;
AbstractBatteryModel &batteryModel;
Layout layout{Layout::Undefined};
};
} // namespace app::popup
M products/BellHybrid/apps/common/src/BatteryModel.cpp => products/BellHybrid/apps/common/src/BatteryModel.cpp +6 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, 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 "models/BatteryModel.hpp"
@@ 18,4 18,9 @@ namespace app
{
return Store::Battery::get();
}
+
+ bool BatteryModel::isBatteryCharging(Store::Battery::State state) const
+ {
+ return (state == Store::Battery::State::Charging) or (state == Store::Battery::State::ChargingDone);
+ }
} // namespace app
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassic.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassic.cpp +56 -1
@@ 1,9 1,10 @@
-// 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 "layouts/HomeScreenLayoutClassic.hpp"
#include "layouts/HomeScreenLayoutNames.hpp"
#include "data/BellMainStyle.hpp"
+#include "data/StyleCommon.hpp"
#include "widgets/BellBattery.hpp"
#include "widgets/BellConnectionStatus.hpp"
#include "widgets/DuoHBox.hpp"
@@ 15,6 16,7 @@
#include <time/time_constants.hpp>
#include <widgets/AlarmSetSpinner.hpp>
#include <widgets/TimeSetFmtSpinner.hpp>
+#include <widgets/Icon.hpp>
namespace
{
@@ 111,6 113,22 @@ namespace gui
bottomText->drawUnderline(false);
bottomText->setVisible(false);
+ lowBatteryWarning = new Icon(this,
+ 0,
+ 0,
+ style::window_width,
+ style::window_height,
+ "bell_status_battery_lvl0",
+ {},
+ gui::ImageTypeSpecifier::W_G);
+ lowBatteryWarning->setAlignment(
+ gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));
+ lowBatteryWarning->image->setMargins({0, gui::bell_style::warning_icon_top_margin, 0, 0});
+ lowBatteryWarning->text->setMaximumWidth(gui::bell_style::warning_text_width);
+ lowBatteryWarning->text->setFont(style::window::font::verybiglight);
+ lowBatteryWarning->text->setRichText(utils::translate("app_bell_alarm_lowBattery_info"));
+ lowBatteryWarning->setVisible(false);
+
resizeItems();
}
@@ 125,12 143,14 @@ namespace gui
case app::home_screen::ViewState::Deactivated:
alarm->setAlarmStatus(AlarmSetSpinner::Status::DEACTIVATED);
setHeaderViewMode(HeaderViewMode::Empty);
+ setScreenMode(ScreenViewMode::Main);
alarm->setEditMode(EditMode::Browse);
removeTextDescription();
break;
case app::home_screen::ViewState::DeactivatedWait:
alarm->setAlarmStatus(AlarmSetSpinner::Status::DEACTIVATED);
setHeaderViewMode(HeaderViewMode::AlarmIcon);
+ setScreenMode(ScreenViewMode::Main);
alarm->setEditMode(EditMode::Browse);
break;
case app::home_screen::ViewState::WaitForConfirmation:
@@ 139,36 159,49 @@ namespace gui
case app::home_screen::ViewState::AlarmEdit:
alarm->setEditMode(EditMode::Edit);
setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
+ setScreenMode(ScreenViewMode::Main);
removeTextDescription();
break;
+ case app::home_screen::ViewState::ActivatedLowBattery:
+ alarm->setAlarmStatus(AlarmSetSpinner::Status::DEACTIVATED);
+ setHeaderViewMode(HeaderViewMode::Empty);
+ setScreenMode(ScreenViewMode::Warning);
+ alarm->setEditMode(EditMode::Browse);
+ break;
case app::home_screen::ViewState::ActivatedWait:
alarm->setAlarmStatus(AlarmSetSpinner::Status::ACTIVATED);
setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
+ setScreenMode(ScreenViewMode::Main);
alarm->setEditMode(EditMode::Browse);
break;
case app::home_screen::ViewState::Activated:
alarm->setAlarmStatus(AlarmSetSpinner::Status::ACTIVATED);
setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
+ setScreenMode(ScreenViewMode::Main);
alarm->setEditMode(EditMode::Browse);
removeTextDescription();
break;
case app::home_screen::ViewState::AlarmRinging:
alarm->setAlarmStatus(AlarmSetSpinner::Status::RINGING);
setHeaderViewMode(HeaderViewMode::AlarmIcon);
+ setScreenMode(ScreenViewMode::Main);
alarm->setEditMode(EditMode::Browse);
removeTextDescription();
break;
case app::home_screen::ViewState::AlarmRingingDeactivatedWait:
alarm->setAlarmStatus(AlarmSetSpinner::Status::DEACTIVATED);
setHeaderViewMode(HeaderViewMode::AlarmIcon);
+ setScreenMode(ScreenViewMode::Main);
alarm->setEditMode(EditMode::Browse);
break;
case app::home_screen::ViewState::AlarmSnoozedWait:
setHeaderViewMode(HeaderViewMode::SnoozeIcon);
+ setScreenMode(ScreenViewMode::Main);
alarm->setEditMode(EditMode::Browse);
break;
case app::home_screen::ViewState::AlarmSnoozed:
setHeaderViewMode(HeaderViewMode::SnoozeIconAndTime);
+ setScreenMode(ScreenViewMode::Main);
alarm->setEditMode(EditMode::Browse);
removeTextDescription();
break;
@@ 215,6 248,28 @@ namespace gui
}
}
+ void HomeScreenLayoutClassic::setScreenMode(ScreenViewMode mode)
+ {
+ switch (mode) {
+ case ScreenViewMode::Main:
+ lowBatteryWarning->setVisible(false);
+ firstBox->setVisible(true);
+ firstBox->informContentChanged();
+ lastBox->setVisible(true);
+ lastBox->informContentChanged();
+ centerBox->setVisible(true);
+ centerBox->informContentChanged();
+ break;
+ case ScreenViewMode::Warning:
+ firstBox->setVisible(false);
+ lastBox->setVisible(false);
+ centerBox->setVisible(false);
+ lowBatteryWarning->setVisible(true);
+ lowBatteryWarning->informContentChanged();
+ break;
+ }
+ }
+
void HomeScreenLayoutClassic::setTextDescription(const UTF8 &desc)
{
statusBox->setVisible(false);
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVertical.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVertical.cpp +8 -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 "layouts/HomeScreenLayoutVertical.hpp"
@@ 47,6 47,7 @@ namespace gui
setScreenMode(ScreenMode::AlarmActivatedDeactivated);
alarmTopIcon->setStatus(AlarmIcon::Status::DEACTIVATED);
alarmActivatedDeactivatedScreen->image->set("big_no-alarm_W_G", {});
+ alarmActivatedDeactivatedScreen->image->setMaximumWidth(alarmActivatedDeactivatedScreen->image->getWidth());
break;
case app::home_screen::ViewState::WaitForConfirmation:
setScreenMode(ScreenMode::AlarmActivatedDeactivated);
@@ 54,10 55,16 @@ namespace gui
case app::home_screen::ViewState::AlarmEdit:
setScreenMode(ScreenMode::AlarmEdit);
break;
+ case app::home_screen::ViewState::ActivatedLowBattery:
+ setScreenMode(ScreenMode::AlarmActivatedDeactivated);
+ alarmTopIcon->setStatus(AlarmIcon::Status::DEACTIVATED);
+ alarmActivatedDeactivatedScreen->image->set("bell_status_battery_lvl0", gui::ImageTypeSpecifier::W_G);
+ break;
case app::home_screen::ViewState::ActivatedWait:
setScreenMode(ScreenMode::AlarmActivatedDeactivated);
alarmTopIcon->setStatus(AlarmIcon::Status::ACTIVATED);
alarmActivatedDeactivatedScreen->image->set("big_alarm_W_G", {});
+ alarmActivatedDeactivatedScreen->image->setMaximumWidth(alarmActivatedDeactivatedScreen->image->getWidth());
break;
case app::home_screen::ViewState::Activated:
alarmActivatedDeactivatedScreen->image->set("big_alarm_W_G", {});
M => +54 -10
@@ 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 <ApplicationCommon.hpp>
@@ 18,6 18,7 @@
namespace
{
constexpr unsigned int y_position = 22U;
constexpr std::chrono::seconds screenTimeout{5};
} // namespace
namespace gui
@@ 29,11 30,6 @@ namespace gui
{
getPresenter()->attach(this);
buildInterface();
timerCallback = [this](Item &, sys::Timer &) {
returnToPreviousWindow();
return true;
};
}
void AlarmActivatedWindow::buildInterface()
@@ 44,16 40,59 @@ namespace gui
header->setTitleVisibility(false);
navBar->setVisible(false);
getPresenter()->getLayout() == app::popup::Layout::LowBatteryInfo ? buildLowBatteryLayout()
: buildAlarmInfoLayout();
}
void AlarmActivatedWindow::buildLowBatteryLayout()
{
icon = new Icon(this,
0,
0,
style::window_width,
style::window_height,
"bell_status_battery_lvl0",
{},
gui::ImageTypeSpecifier::W_G);
icon->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));
icon->image->setMargins({0, bell_style::warning_icon_top_margin, 0, 0});
icon->text->setMaximumWidth(bell_style::warning_text_width);
icon->text->setFont(style::window::font::verybiglight);
icon->text->setRichText(utils::translate("app_bell_alarm_lowBattery_info"));
timerCallback = [this](Item &, sys::Timer &timer) {
lowBatteryInfoHandled();
return true;
};
resetTimer(screenTimeout);
}
void AlarmActivatedWindow::buildAlarmInfoLayout()
{
icon = new Icon(this, 0, 0, style::window_width, style::window_height, "big_alarm_W_G", {});
icon->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));
icon->image->setMargins({0, bell_style::popup_icon_top_margin, 0, bell_style::popup_icon_bottom_margin});
icon->text->setFont(style::window::font::verybiglight);
setAlarmTime(getPresenter()->getAlarmTime());
timerCallback = [this](Item &, sys::Timer &) {
returnToPreviousWindow();
return true;
};
resetTimer(screenTimeout);
}
void AlarmActivatedWindow::onBeforeShow(ShowMode mode, SwitchData *data)
void AlarmActivatedWindow::rebuild()
{
setAlarmTime(getPresenter()->getAlarmTime());
WindowWithTimer::onBeforeShow(mode, data);
erase();
buildInterface();
}
void AlarmActivatedWindow::lowBatteryInfoHandled()
{
getPresenter()->lowBatteryInfoHandled();
rebuild();
application->refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
}
void AlarmActivatedWindow::returnToPreviousWindow()
@@ 75,7 114,12 @@ namespace gui
{
if (inputEvent.isShortRelease(KeyCode::KEY_ENTER) || inputEvent.isShortRelease(KeyCode::KEY_RF)) {
detachTimerIfExists();
returnToPreviousWindow();
if (getPresenter()->getLayout() == app::popup::Layout::LowBatteryInfo) {
lowBatteryInfoHandled();
}
else {
returnToPreviousWindow();
}
return true;
}
return false;
M => +24 -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
#include <common/popups/presenter/AlarmActivatedPresenter.hpp>
@@ 8,7 8,8 @@
namespace app::popup
{
AlarmActivatedPresenter::AlarmActivatedPresenter(AbstractAlarmModel &alarmModel) : alarmModel{alarmModel}
AlarmActivatedPresenter::AlarmActivatedPresenter(AbstractAlarmModel &alarmModel, AbstractBatteryModel &batteryModel)
: alarmModel{alarmModel}, batteryModel{batteryModel}
{}
bool AlarmActivatedPresenter::isAlarmActive() const noexcept
@@ 21,4 22,25 @@ namespace app::popup
return alarmModel.getAlarmTime();
}
Layout AlarmActivatedPresenter::getLayout()
{
if (layout == Layout::Undefined) {
const auto batteryStatus = batteryModel.getLevelState();
const units::SOC soc = batteryStatus.level;
const auto state = batteryStatus.state;
if (not batteryModel.isBatteryCharging(state) && soc < constants::lowBatteryInfoThreshold) {
layout = Layout::LowBatteryInfo;
}
else {
layout = Layout::AlarmInfo;
}
}
return layout;
}
void AlarmActivatedPresenter::lowBatteryInfoHandled()
{
layout = Layout::AlarmInfo;
}
} // namespace app::popup
M products/BellHybrid/apps/common/src/widgets/LayoutVertical.cpp => products/BellHybrid/apps/common/src/widgets/LayoutVertical.cpp +11 -5
@@ 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 "widgets/LayoutVertical.hpp"
@@ 114,15 114,21 @@ namespace gui
setAlarmScreen->setVisible(false);
// Activation / Deactivation
- alarmActivatedDeactivatedScreen =
- new Icon(this, 0, 0, style::window_width, style::window_height, "big_alarm_W_G", {});
+ alarmActivatedDeactivatedScreen = new Icon(this,
+ 0,
+ 0,
+ style::window_width,
+ style::window_height,
+ "bell_status_battery_lvl0",
+ {},
+ gui::ImageTypeSpecifier::W_G);
alarmActivatedDeactivatedScreen->setMinimumSize(style::window_width, style::window_height);
alarmActivatedDeactivatedScreen->setAlignment(
gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));
- alarmActivatedDeactivatedScreen->image->setMargins(
- {0, bell_style::popup_icon_top_margin, 0, bell_style::popup_icon_bottom_margin});
+ alarmActivatedDeactivatedScreen->image->setMargins({0, bell_style::warning_icon_top_margin, 0, 0});
alarmActivatedDeactivatedScreen->image->setAlignment(
Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+ alarmActivatedDeactivatedScreen->text->setMaximumWidth(bell_style::warning_text_width);
alarmActivatedDeactivatedScreen->text->setFont(style::window::font::verybiglight);
alarmActivatedDeactivatedScreen->resizeItems();
alarmActivatedDeactivatedScreen->setVisible(false);
M products/BellHybrid/apps/include/Application.hpp => products/BellHybrid/apps/include/Application.hpp +3 -1
@@ 1,10 1,11 @@
-// Copyright (c) 2017-2022, 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 <ApplicationCommon.hpp>
#include <common/models/AlarmModel.hpp>
+#include <common/models/BatteryModel.hpp>
namespace app
{
@@ 33,6 34,7 @@ namespace app
virtual void onStop();
std::unique_ptr<app::AlarmModel> alarmModel;
+ std::unique_ptr<AbstractBatteryModel> batteryModel;
private:
sys::MessagePointer handleKBDKeyEvent(sys::Message *msgl) override;