~aleteoryx/muditaos

cfdd234db1b41c2244c484ec72d3ac9c659cdfa5 — Paweł Joński 4 years ago e833690
[BH-1316] Vertical layouts

Add 2 vertical layouts
39 files changed, 1161 insertions(+), 305 deletions(-)

M module-apps/apps-common/widgets/AlarmSetSpinner.cpp
M module-apps/apps-common/widgets/AlarmSetSpinner.hpp
M module-apps/apps-common/widgets/TimeSetFmtSpinner.cpp
M module-apps/apps-common/widgets/TimeSetFmtSpinner.hpp
M module-apps/apps-common/widgets/TimeSetSpinner.hpp
M products/BellHybrid/apps/application-bell-main/ApplicationBellMain.cpp
M products/BellHybrid/apps/application-bell-main/include/application-bell-main/presenters/HomeScreenPresenter.hpp
M products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.cpp
M products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp
M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp
M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.hpp
M products/BellHybrid/apps/application-bell-onboarding/ApplicationBellOnBoarding.cpp
M products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp
M products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/models/TimeUnitsModel.hpp
M products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/presenter/TimeUnitsPresenter.hpp
M products/BellHybrid/apps/application-bell-settings/models/TimeUnitsModel.cpp
M products/BellHybrid/apps/application-bell-settings/presenter/LayoutWindowPresenter.cpp
M products/BellHybrid/apps/application-bell-settings/presenter/TimeUnitsPresenter.cpp
M products/BellHybrid/apps/common/CMakeLists.txt
M products/BellHybrid/apps/common/include/common/layouts/BaseHomeScreenLayoutProvider.hpp
M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassic.hpp
A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVertical.hpp
A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVerticalSimple.hpp
A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVerticalWithAmPm.hpp
M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayouts.hpp
A products/BellHybrid/apps/common/include/common/widgets/AlarmIcon.hpp
M products/BellHybrid/apps/common/include/common/widgets/BellBattery.hpp
A products/BellHybrid/apps/common/include/common/widgets/LayoutVertical.hpp
A products/BellHybrid/apps/common/include/common/widgets/TimeSetSpinnerVertical.hpp
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassic.cpp
A products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVertical.cpp
A products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalSimple.cpp
A products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalWithAmPm.cpp
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayouts.cpp
A products/BellHybrid/apps/common/src/widgets/AlarmIcon.cpp
M products/BellHybrid/apps/common/src/widgets/BellBattery.cpp
A products/BellHybrid/apps/common/src/widgets/LayoutVertical.cpp
A products/BellHybrid/apps/common/src/widgets/TimeSetSpinnerVertical.cpp
M products/BellHybrid/assets/assets_common.json
M module-apps/apps-common/widgets/AlarmSetSpinner.cpp => module-apps/apps-common/widgets/AlarmSetSpinner.cpp +6 -0
@@ 59,6 59,12 @@ namespace gui
        return this->focusItem->onInput(inputEvent);
    }

    auto AlarmSetSpinner::setArrowsVisible(bool visible) noexcept -> void
    {
        leftArrow->setVisible(visible);
        rightArrow->setVisible(visible);
    }

    auto AlarmSetSpinner::setFont(std::string newFontName) noexcept -> void
    {
        fontName = std::move(newFontName);

M module-apps/apps-common/widgets/AlarmSetSpinner.hpp => module-apps/apps-common/widgets/AlarmSetSpinner.hpp +1 -0
@@ 34,6 34,7 @@ namespace gui
        explicit AlarmSetSpinner(
            Item *parent = nullptr, Position x = 0U, Position y = 0U, Length w = 0U, Length h = 0U);

        auto setArrowsVisible(bool visible) noexcept -> void;
        auto setTime(std::time_t time) noexcept -> void;
        auto setFont(std::string newFontName) noexcept -> void;
        auto setEditMode(EditMode mode) noexcept -> void;

M module-apps/apps-common/widgets/TimeSetFmtSpinner.cpp => module-apps/apps-common/widgets/TimeSetFmtSpinner.cpp +5 -0
@@ 218,6 218,11 @@ namespace gui
        return fmt->getCurrentValue() == utils::time::Locale::getPM().c_str();
    }

    auto TimeSetFmtSpinner::getTimeFormat() const noexcept -> utils::time::Locale::TimeFormat
    {
        return timeFormat;
    }

    auto TimeSetFmtSpinner::setTime(std::time_t time) noexcept -> void
    {
        using namespace utils::time;

M module-apps/apps-common/widgets/TimeSetFmtSpinner.hpp => module-apps/apps-common/widgets/TimeSetFmtSpinner.hpp +2 -0
@@ 54,6 54,8 @@ namespace gui
        [[nodiscard]] auto getMinute() const noexcept -> int;
        [[nodiscard]] auto isPM() const noexcept -> bool;

        auto getTimeFormat() const noexcept -> utils::time::Locale::TimeFormat;

      private:
        enum class TraverseDir : bool
        {

M module-apps/apps-common/widgets/TimeSetSpinner.hpp => module-apps/apps-common/widgets/TimeSetSpinner.hpp +3 -0
@@ 46,6 46,7 @@ namespace gui
        std::map<std::string, std::string> colonFontMap = {
            {style::window::font::verybiglight, "alarm_colon_W_M"},
            {style::window::font::largelight, "alarm_colon_W_M"},
            {style::window::font::supersizeme, "alarm_colon_select_W_M"},
            {style::window::font::supersizemelight, "alarm_colon_select_W_M"},
            {style::window::font::huge, "alarm_colon_clock_W_M"}};



@@ 54,6 55,8 @@ namespace gui
             {style::time_set_spinner::small_margin, 0, style::time_set_spinner::small_margin, 0}},
            {style::window::font::largelight,
             {style::time_set_spinner::small_margin, 0, style::time_set_spinner::small_margin, 0}},
            {style::window::font::supersizeme,
             {style::time_set_spinner::big_margin, 0, style::time_set_spinner::big_margin, 0}},
            {style::window::font::supersizemelight,
             {style::time_set_spinner::big_margin, 0, style::time_set_spinner::big_margin, 0}},
            {style::window::font::huge,

M products/BellHybrid/apps/application-bell-main/ApplicationBellMain.cpp => products/BellHybrid/apps/application-bell-main/ApplicationBellMain.cpp +1 -1
@@ 177,7 177,7 @@ namespace app

    void ApplicationBellMain::setHomeScreenLayout(std::string layoutName)
    {
        auto homeScreenLayoutsList = gui::homeScreenLayouts();
        auto homeScreenLayoutsList = gui::factory::getAllLayouts();
        if (homeScreenLayoutsList.find(layoutName) == homeScreenLayoutsList.end()) {
            return;
        }

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 +9 -9
@@ 48,16 48,11 @@ namespace app::home_screen
        virtual ~AbstractView() noexcept = default;

        /// Alarm widget related API
        virtual void setAlarmTriggered()                                     = 0;
        virtual void setAlarmActive(bool)                                    = 0;
        virtual void setAlarmEdit(bool)                                      = 0;
        virtual void setViewState(ViewState state)                           = 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;
        virtual void setSnoozeFormat(utils::time::Locale::TimeFormat fmt)    = 0;
        virtual void incAlarmMinute()                                        = 0;
        virtual void decAlarmMinute()                                        = 0;

        /// Time widget related API
        virtual void setTime(std::time_t time)                          = 0;


@@ 65,14 60,11 @@ namespace app::home_screen

        /// Bottom box related API(descriptionn battery or time)
        virtual void setTemperature(utils::temperature::Temperature newTemp)    = 0;
        virtual void setBottomDescription(const UTF8 &desc)                     = 0;
        virtual void removeBottomDescription()                                  = 0;
        virtual void setTextDescription(const UTF8 &desc)                       = 0;
        virtual void setBatteryLevelState(const Store::Battery &batteryContext) = 0;

        /// Various
        virtual void setLayout(gui::LayoutGenerator layoutGenerator) = 0;
        virtual void switchToMenu()                                  = 0;
        virtual void switchToBatteryStatus()                         = 0;
        virtual void setSnoozeTime(std::time_t time)                 = 0;
    };



@@ 99,6 91,10 @@ namespace app::home_screen
        virtual bool isBatteryCharging() const                                                   = 0;
        virtual bool isAlarmActivatedByLatch() const                                             = 0;
        virtual void setLayout(gui::LayoutGenerator layoutGenerator)                             = 0;
        virtual void incAlarmMinute()                                                            = 0;
        virtual void decAlarmMinute()                                                            = 0;
        virtual void switchToMenu()                                                              = 0;
        virtual void switchToBatteryStatus()                                                     = 0;

        static constexpr auto defaultTimeout = std::chrono::milliseconds{5000};
    };


@@ 138,6 134,10 @@ namespace app::home_screen
        std::uint32_t getBatteryLvl() const override;
        bool isBatteryCharging() const override;
        bool isAlarmActivatedByLatch() const override;
        void incAlarmMinute();
        void decAlarmMinute();
        void switchToMenu();
        void switchToBatteryStatus();

        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 +77 -0
@@ 6,6 6,9 @@
#include "models/BatteryModel.hpp"
#include "models/TemperatureModel.hpp"

#include <windows/BellHomeScreenWindow.hpp>
#include <windows/BellBatteryStatusWindow.hpp>
#include <application-bell-main/ApplicationBellMain.hpp>
#include <apps-common/ApplicationCommon.hpp>
#include <common/layouts/BaseHomeScreenLayoutProvider.hpp>
#include <common/models/TimeModel.hpp>


@@ 17,6 20,53 @@
#include <service-evtmgr/Constants.hpp>
#include <switches/LatchStatusRequest.hpp>

namespace
{
    using utils::time::Locale;
    void increaseHour(struct tm &tm)
    {
        if (tm.tm_hour >= Locale::max_hour_24H_mode) {
            tm.tm_hour = 0;
            tm.tm_min  = 0;
        }
        else {
            tm.tm_hour++;
            tm.tm_min = 0;
        }
    }

    void decreaseHour(struct tm &tm)
    {
        if (tm.tm_hour <= Locale::min_hour_24H_mode) {
            tm.tm_hour = Locale::max_hour_24H_mode;
            tm.tm_min  = Locale::max_minutes;
        }
        else {
            tm.tm_hour--;
            tm.tm_min = utils::time::Locale::max_minutes;
        }
    }

    void handleMinuteIncrease(struct tm &tm)
    {
        if (tm.tm_min >= Locale::max_minutes) {
            increaseHour(tm);
        }
        else {
            tm.tm_min++;
        }
    }

    void handleMinuteDecrease(struct tm &tm)
    {
        if (tm.tm_min <= 0) {
            decreaseHour(tm);
        }
        else {
            tm.tm_min--;
        }
    }
}; // namespace
namespace app::home_screen
{
    HomeScreenPresenter::HomeScreenPresenter(ApplicationCommon *app,


@@ 168,4 218,31 @@ namespace app::home_screen
    {
        getView()->setLayout(layoutGenerator);
    }

    void HomeScreenPresenter::incAlarmMinute()
    {
        const auto alarmTime = getView()->getAlarmTime();
        auto newTime         = std::localtime(&alarmTime);
        handleMinuteIncrease(*newTime);
        getView()->setAlarmTime(std::mktime(newTime));
    }

    void HomeScreenPresenter::decAlarmMinute()
    {
        const auto alarmTime = getView()->getAlarmTime();
        auto newTime         = std::localtime(&alarmTime);
        handleMinuteDecrease(*newTime);
        getView()->setAlarmTime(std::mktime(newTime));
    }

    void HomeScreenPresenter::switchToMenu()
    {
        app->switchWindow(gui::window::name::bell_main_menu, nullptr);
    }

    void HomeScreenPresenter::switchToBatteryStatus()
    {
        app->switchWindow(gui::BellBatteryStatusWindow::name,
                          std::make_unique<gui::BellBatteryStatusWindow::Data>(getBatteryLvl(), isBatteryCharging()));
    }
} // namespace app::home_screen

M products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp => products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp +25 -56
@@ 65,10 65,8 @@ namespace app::home_screen
                return true;
            };

            auto switchToMenu          = [](AbstractView &view) { view.switchToMenu(); };
            auto makeAlarmEditable     = [](AbstractView &view) { view.setAlarmEdit(true); };
            auto makeAlarmNonEditable  = [](AbstractView &view) { view.setAlarmEdit(false); };
            auto switchToBatteryStatus = [](AbstractView &view) { view.switchToBatteryStatus(); };
            auto switchToMenu          = [](AbstractPresenter &presenter) { presenter.switchToMenu(); };
            auto switchToBatteryStatus = [](AbstractPresenter &presenter) { presenter.switchToBatteryStatus(); };
            auto updateTemperature     = [](AbstractView &view, AbstractTemperatureModel &temperatureModel) {
                view.setTemperature(temperatureModel.getTemperature());
            };


@@ 141,8 139,6 @@ namespace app::home_screen
                            AbstractPresenter &presenter,
                            AbstractAlarmModel &alarmModel) {
                alarmModel.update([&]() { presenter.handleAlarmModelReady(); });
                view.setAlarmEdit(false);
                view.setAlarmActive(false);
                view.setTemperature(temperatureModel.getTemperature());
                view.setBatteryLevelState(batteryModel.getLevelState());
            };


@@ 155,8 151,6 @@ namespace app::home_screen
                            AbstractTemperatureModel &temperatureModel,
                            AbstractBatteryModel &batteryModel) {
                controller.snooze(false);
                view.setAlarmEdit(false);
                view.setAlarmActive(false);
                view.setViewState(ViewState::Deactivated);
                view.setTemperature(temperatureModel.getTemperature());
                view.setBatteryLevelState(batteryModel.getLevelState());


@@ 168,37 162,29 @@ namespace app::home_screen
            auto entry = [](AbstractView &view, AbstractPresenter &presenter, AbstractAlarmModel &alarmModel) {
                alarmModel.activate(false);
                presenter.spawnTimer();
                view.setBottomDescription(utils::translate("app_bell_alarm_deactivated"));
                view.setAlarmActive(false);
                view.setTextDescription(utils::translate("app_bell_alarm_deactivated"));
                view.setViewState(ViewState::DeactivatedWait);
            };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) {
                presenter.detachTimer();
                view.removeBottomDescription();
            };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) { presenter.detachTimer(); };
        } // namespace DeactivatedWait

        namespace AlarmEdit
        {
            auto entry =
                [](AbstractView &view, AbstractPresenter &presenter, AbstractTemperatureModel &temperatureModel) {
                    view.setAlarmEdit(true);
                    view.setViewState(ViewState::AlarmEdit);
                    view.setTemperature(temperatureModel.getTemperature());
                };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) {
                view.setAlarmEdit(false);
                presenter.detachTimer();
            };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) { presenter.detachTimer(); };

            auto processRotateLeft = [](AbstractView &view, AbstractPresenter &presenter) {
            auto processRotateLeft = [](AbstractPresenter &presenter) {
                presenter.spawnTimer(defaultAlarmSetTime);
                view.decAlarmMinute();
                presenter.decAlarmMinute();
            };

            auto processRotateRight = [](AbstractView &view, AbstractPresenter &presenter) {
            auto processRotateRight = [](AbstractPresenter &presenter) {
                presenter.spawnTimer(defaultAlarmSetTime);
                view.incAlarmMinute();
                presenter.incAlarmMinute();
            };
        } // namespace AlarmEdit



@@ 206,16 192,12 @@ namespace app::home_screen
        {
            auto entry = [](AbstractView &view, AbstractPresenter &presenter) {
                presenter.spawnTimer();
                view.setBottomDescription(utils::translate("app_bellmain_home_screen_bottom_desc_dp"));
                view.setTextDescription(utils::translate("app_bellmain_home_screen_bottom_desc_dp"));
                view.setViewState(ViewState::WaitForConfirmation);
            };
            auto exit = [](AbstractPresenter &presenter) { presenter.detachTimer(); };

            auto action = [](AbstractView &view) {
                view.setAlarmEdit(false);
                view.setAlarmActive(true);
                view.removeBottomDescription();
            };
            auto action = [](AbstractView &view) {};
        } // namespace WaitForConfirmation

        namespace ActivatedWait


@@ 226,15 208,11 @@ namespace app::home_screen
                            AbstractTimeModel &timeModel) {
                alarmModel.activate(true);
                presenter.spawnTimer();
                view.setBottomDescription(utils::time::getBottomDescription(
                view.setTextDescription(utils::time::getBottomDescription(
                    utils::time::calculateMinutesDifference(view.getAlarmTime(), timeModel.getCurrentTime())));
                view.setAlarmActive(true);
                view.setViewState(ViewState::ActivatedWait);
            };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) {
                presenter.detachTimer();
                view.removeBottomDescription();
            };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) { presenter.detachTimer(); };
        } // namespace ActivatedWait

        namespace Activated


@@ 246,7 224,6 @@ namespace app::home_screen
                            AbstractBatteryModel &batteryModel) {
                controller.snooze(false);
                view.setTemperature(temperatureModel.getTemperature());
                view.setAlarmActive(true);
                view.setViewState(ViewState::Activated);
                view.setAlarmTime(alarmModel.getAlarmTime());
                view.setBatteryLevelState(batteryModel.getLevelState());


@@ 259,7 236,6 @@ namespace app::home_screen
                [](AbstractView &view, AbstractTemperatureModel &temperatureModel, AbstractPresenter &presenter) {
                    presenter.spawnTimer(defaultAlarmRingingTime);
                    view.setViewState(ViewState::AlarmRinging);
                    view.setAlarmTriggered();
                    view.setTemperature(temperatureModel.getTemperature());
                };
            auto exit = [](AbstractPresenter &presenter) { presenter.detachTimer(); };


@@ 272,13 248,9 @@ namespace app::home_screen
                alarmModel.turnOff();
                alarmModel.activate(false);
                view.setViewState(ViewState::AlarmRingingDeactivatedWait);
                view.setBottomDescription(Helpers::getGreeting());
                view.setAlarmActive(false);
            };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) {
                presenter.detachTimer();
                view.removeBottomDescription();
                view.setTextDescription(Helpers::getGreeting());
            };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) { presenter.detachTimer(); };
        } // namespace AlarmRingingDeactivatedWait

        namespace AlarmSnoozedWait


@@ 289,12 261,9 @@ namespace app::home_screen
                view.setViewState(ViewState::AlarmSnoozedWait);
                const auto bottomDescription =
                    utils::time::getBottomDescription(alarmModel.getSnoozeDuration().count());
                view.setBottomDescription(bottomDescription);
            };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) {
                presenter.detachTimer();
                view.removeBottomDescription();
                view.setTextDescription(bottomDescription);
            };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) { presenter.detachTimer(); };
        } // namespace AlarmSnoozedWait

        namespace AlarmSnoozed


@@ 326,8 295,8 @@ namespace app::home_screen

                                             "Deactivated"_s + sml::on_entry<_> / Deactivated::entry,
                                             "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::RotateLeftPress> = "DeactivatedEdit"_s,
                                             "Deactivated"_s + event<Events::RotateRightPress> = "DeactivatedEdit"_s,
                                             "Deactivated"_s + event<Events::DeepUpPress> = "ActivatedWait"_s,
                                             "Deactivated"_s + event<Events::TimeUpdate> / Helpers::updateTemperature,
                                             "Deactivated"_s + event<Events::LongBackPress>  / Helpers::switchToBatteryStatus,


@@ 336,7 305,7 @@ namespace app::home_screen
                                             "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>/ Helpers::switchToMenu = "Deactivated"_s,
                                             "DeactivatedWait"_s + event<Events::LightPress> = "Deactivated"_s,
                                             "DeactivatedWait"_s + event<Events::DeepUpPress> = "ActivatedWait"_s,
                                             "DeactivatedWait"_s + event<Events::RotateLeftPress> = "DeactivatedEdit"_s,
                                             "DeactivatedWait"_s + event<Events::RotateRightPress> = "DeactivatedEdit"_s,


@@ 355,7 324,7 @@ namespace app::home_screen

                                             "WaitForConfirmation"_s + sml::on_entry<_> / WaitForConfirmation::entry,
                                             "WaitForConfirmation"_s + sml::on_exit<_> / WaitForConfirmation::exit,
                                             "WaitForConfirmation"_s + event<Events::Timer> / Helpers::makeAlarmNonEditable = "Deactivated"_s,
                                             "WaitForConfirmation"_s + event<Events::Timer> = "Deactivated"_s,
                                             "WaitForConfirmation"_s + event<Events::DeepUpPress> / WaitForConfirmation::action = "ActivatedWait"_s,
                                             "WaitForConfirmation"_s + event<Events::LightPress>/ Helpers::switchToMenu = "Deactivated"_s,
                                             "WaitForConfirmation"_s + event<Events::BackPress> = "Deactivated"_s,


@@ 364,8 333,8 @@ namespace app::home_screen

                                             "ActivatedWait"_s + sml::on_entry<_> / ActivatedWait::entry,
                                             "ActivatedWait"_s + sml::on_exit<_> / ActivatedWait::exit,
                                             "ActivatedWait"_s + event<Events::Timer> / Helpers::makeAlarmNonEditable = "Activated"_s,
                                             "ActivatedWait"_s + event<Events::LightPress>/ Helpers::switchToMenu = "Activated"_s,
                                             "ActivatedWait"_s + event<Events::Timer> = "Activated"_s,
                                             "ActivatedWait"_s + event<Events::LightPress> = "Activated"_s,
                                             "ActivatedWait"_s + event<Events::DeepDownPress> = "DeactivatedWait"_s,
                                             "ActivatedWait"_s + event<Events::BackPress> = "Activated"_s,
                                             "ActivatedWait"_s + event<Events::RotateLeftPress> = "ActivatedEdit"_s,


@@ 375,8 344,8 @@ namespace app::home_screen
                                             "Activated"_s + sml::on_entry<_> / Activated::entry,
                                             "Activated"_s [not Helpers::isAlarmActive] = "Deactivated"_s,
                                             "Activated"_s + event<Events::LightPress>/ Helpers::switchToMenu = "Activated"_s,
                                             "Activated"_s + event<Events::RotateLeftPress> / Helpers::makeAlarmEditable = "ActivatedEdit"_s,
                                             "Activated"_s + event<Events::RotateRightPress> / Helpers::makeAlarmEditable = "ActivatedEdit"_s,
                                             "Activated"_s + event<Events::RotateLeftPress> = "ActivatedEdit"_s,
                                             "Activated"_s + event<Events::RotateRightPress> = "ActivatedEdit"_s,
                                             "Activated"_s + event<Events::TimeUpdate> / Helpers::updateTemperature,
                                             "Activated"_s + event<Events::DeepDownPress>  = "DeactivatedWait"_s,
                                             "Activated"_s + event<Events::AlarmRinging>  = "AlarmRinging"_s,

M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp => products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp +2 -106
@@ 24,50 24,6 @@
#include <chrono>
namespace
{
    using utils::time::Locale;
    void increaseHour(struct tm &tm)
    {
        if (tm.tm_hour >= Locale::max_hour_24H_mode) {
            tm.tm_hour = 0;
            tm.tm_min  = 0;
        }
        else {
            tm.tm_hour++;
            tm.tm_min = 0;
        }
    }

    void decreaseHour(struct tm &tm)
    {
        if (tm.tm_hour <= Locale::min_hour_24H_mode) {
            tm.tm_hour = Locale::max_hour_24H_mode;
            tm.tm_min  = Locale::max_minutes;
        }
        else {
            tm.tm_hour--;
            tm.tm_min = utils::time::Locale::max_minutes;
        }
    }

    void handleMinuteIncrease(struct tm &tm)
    {
        if (tm.tm_min >= Locale::max_minutes) {
            increaseHour(tm);
        }
        else {
            tm.tm_min++;
        }
    }

    void handleMinuteDecrease(struct tm &tm)
    {
        if (tm.tm_min <= 0) {
            decreaseHour(tm);
        }
        else {
            tm.tm_min--;
        }
    }
    inline constexpr auto snoozeTimerName = "SnoozeTimer";
    inline constexpr std::chrono::seconds timerTick{1};
} // namespace


@@ 108,20 64,6 @@ namespace gui
        }
    }

    void BellHomeScreenWindow::setAlarmTriggered()
    {
        if (currentLayout) {
            currentLayout->setAlarmTriggered();
        }
    }

    void BellHomeScreenWindow::setAlarmActive(bool val)
    {
        if (currentLayout) {
            currentLayout->setAlarmActive(val);
        }
    }

    void BellHomeScreenWindow::setViewState(app::home_screen::ViewState state)
    {
        if (currentLayout) {


@@ 137,20 79,12 @@ namespace gui
        }
    }

    void BellHomeScreenWindow::setBottomDescription(const UTF8 &desc)
    {
        if (currentLayout) {
            currentLayout->setBottomDescription(desc);
        }
    }

    void BellHomeScreenWindow::removeBottomDescription()
    void BellHomeScreenWindow::setTextDescription(const UTF8 &desc)
    {
        if (currentLayout) {
            currentLayout->removeBottomDescription();
            currentLayout->setTextDescription(desc);
        }
    }

    void BellHomeScreenWindow::setBatteryLevelState(const Store::Battery &batteryContext)
    {
        if (currentLayout) {


@@ 186,13 120,6 @@ namespace gui
        }
    }

    void BellHomeScreenWindow::setAlarmEdit(bool val)
    {
        if (currentLayout) {
            currentLayout->setAlarmEdit(val);
        }
    }

    std::time_t BellHomeScreenWindow::getAlarmTime() const
    {
        if (currentLayout) {


@@ 210,26 137,6 @@ namespace gui
        }
    }

    void BellHomeScreenWindow::incAlarmMinute()
    {
        if (currentLayout) {
            const auto alarmTime = currentLayout->getAlarmTime();
            auto newTime         = std::localtime(&alarmTime);
            handleMinuteIncrease(*newTime);
            currentLayout->setAlarmTime(std::mktime(newTime));
        }
    }

    void BellHomeScreenWindow::decAlarmMinute()
    {
        if (currentLayout) {
            const auto alarmTime = currentLayout->getAlarmTime();
            auto newTime         = std::localtime(&alarmTime);
            handleMinuteDecrease(*newTime);
            currentLayout->setAlarmTime(std::mktime(newTime));
        }
    }

    void BellHomeScreenWindow::setSnoozeTime(std::time_t newTime)
    {
        if (currentLayout) {


@@ 237,11 144,6 @@ namespace gui
        }
    }

    void BellHomeScreenWindow::switchToMenu()
    {
        application->switchWindow(window::name::bell_main_menu, nullptr);
    }

    bool BellHomeScreenWindow::onInput(const InputEvent &inputEvent)
    {
        if (inputEvent.isShortRelease() || inputEvent.isLongRelease()) {


@@ 269,12 171,6 @@ namespace gui
        }
        return true;
    }
    void BellHomeScreenWindow::switchToBatteryStatus()
    {
        application->switchWindow(gui::BellBatteryStatusWindow::name,
                                  std::make_unique<gui::BellBatteryStatusWindow::Data>(presenter->getBatteryLvl(),
                                                                                       presenter->isBatteryCharging()));
    }

    bool BellHomeScreenWindow::updateBatteryStatus()
    {

M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.hpp => products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.hpp +1 -10
@@ 27,27 27,18 @@ namespace gui
        void onBeforeShow(ShowMode mode, SwitchData *data) override;
        bool onDatabaseMessage(sys::Message *msg) override;

        void setAlarmTriggered() override;
        void setAlarmActive(bool val) override;
        void setAlarmEdit(bool val) override;
        void setViewState(app::home_screen::ViewState state) override;
        std::time_t getAlarmTime() const override;
        void setAlarmTime(std::time_t newTime) override;
        void setSnoozeTime(std::time_t newTime) override;
        void incAlarmMinute() override;
        void decAlarmMinute() override;

        void setTemperature(utils::temperature::Temperature newTemp) override;
        void setBottomDescription(const UTF8 &desc) override;
        void removeBottomDescription() override;
        void setTextDescription(const UTF8 &desc) override;
        void setBatteryLevelState(const Store::Battery &batteryContext) override;
        void setTime(std::time_t newTime) override;
        void setTimeFormat(utils::time::Locale::TimeFormat fmt) override;
        void setAlarmTimeFormat(utils::time::Locale::TimeFormat fmt) override;
        void setSnoozeFormat(utils::time::Locale::TimeFormat fmt) override;
        void switchToMenu() override;
        void switchToBatteryStatus() override;

        bool updateBatteryStatus() override;

        std::shared_ptr<app::home_screen::AbstractPresenter> presenter;

M products/BellHybrid/apps/application-bell-onboarding/ApplicationBellOnBoarding.cpp => products/BellHybrid/apps/application-bell-onboarding/ApplicationBellOnBoarding.cpp +4 -2
@@ 18,6 18,7 @@
#include <common/BellPowerOffPresenter.hpp>
#include <common/windows/BellFinishedWindow.hpp>
#include <common/windows/BellWelcomeWindow.hpp>
#include <common/models/LayoutModel.hpp>

#include <application-bell-settings/models/TemperatureUnitModel.hpp>
#include <application-bell-settings/models/TimeUnitsModel.hpp>


@@ 74,11 75,12 @@ namespace app
            });

        windowsFactory.attach(
            gui::window::name::onBoardingSettingsWindow, [](ApplicationCommon *app, const std::string &name) {
            gui::window::name::onBoardingSettingsWindow, [this](ApplicationCommon *app, const std::string &name) {
                auto layoutModel          = std::make_unique<bell_settings::LayoutModel>(this);
                auto temperatureUnitModel = std::make_unique<bell_settings::TemperatureUnitModel>(app);
                auto timeUnitsProvider    = std::make_shared<bell_settings::TimeUnitsModelFactoryResetValues>(app);
                auto presenter            = std::make_unique<bell_settings::TimeUnitsWindowPresenter>(
                    timeUnitsProvider, std::move(temperatureUnitModel));
                    this, timeUnitsProvider, std::move(temperatureUnitModel), std::move(layoutModel));
                return std::make_unique<gui::OnBoardingSettingsWindow>(app, std::move(presenter), name);
            });


M products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp => products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp +3 -2
@@ 134,11 134,12 @@ namespace app
            });

        windowsFactory.attach(
            gui::window::name::bellSettingsTimeUnits, [](ApplicationCommon *app, const std::string &name) {
            gui::window::name::bellSettingsTimeUnits, [this](ApplicationCommon *app, const std::string &name) {
                auto layoutModel          = std::make_unique<bell_settings::LayoutModel>(this);
                auto temperatureUnitModel = std::make_unique<bell_settings::TemperatureUnitModel>(app);
                auto timeUnitsProvider    = std::make_shared<bell_settings::TimeUnitsModel>(app);
                auto presenter            = std::make_unique<bell_settings::TimeUnitsWindowPresenter>(
                    timeUnitsProvider, std::move(temperatureUnitModel));
                    this, timeUnitsProvider, std::move(temperatureUnitModel), std::move(layoutModel));
                return std::make_unique<gui::BellSettingsTimeUnitsWindow>(app, std::move(presenter));
            });


M products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/models/TimeUnitsModel.hpp => products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/models/TimeUnitsModel.hpp +3 -0
@@ 43,6 43,9 @@ namespace app::bell_settings
        [[nodiscard]] auto getMinimalItemSpaceRequired() const -> unsigned int override;

        [[nodiscard]] auto getTemperatureUnit() const -> utils::temperature::Temperature::Unit;

        [[nodiscard]] auto getTimeFormat() const -> utils::time::Locale::TimeFormat;

        auto setTemperatureUnit(utils::temperature::Temperature::Unit unit) -> void;

      protected:

M products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/presenter/TimeUnitsPresenter.hpp => products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/presenter/TimeUnitsPresenter.hpp +7 -2
@@ 10,6 10,7 @@
namespace app::bell_settings
{
    class AbstractTemperatureUnitModel;
    class AbstractLayoutModel;

    class TimeUnitsWindowContract
    {


@@ 35,8 36,10 @@ namespace app::bell_settings
    class TimeUnitsWindowPresenter : public TimeUnitsWindowContract::Presenter
    {
      public:
        explicit TimeUnitsWindowPresenter(std::shared_ptr<TimeUnitsModel> pagesProvider,
                                          std::unique_ptr<AbstractTemperatureUnitModel> temperatureUnitModel);
        explicit TimeUnitsWindowPresenter(app::ApplicationCommon *app,
                                          std::shared_ptr<TimeUnitsModel> pagesProvider,
                                          std::unique_ptr<AbstractTemperatureUnitModel> temperatureUnitModel,
                                          std::unique_ptr<AbstractLayoutModel> layoutModel);

        auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
        auto clearData() -> void override;


@@ 45,7 48,9 @@ namespace app::bell_settings
        auto createData() -> void override;

      private:
        app::ApplicationCommon *app{};
        std::shared_ptr<TimeUnitsModel> pagesProvider;
        std::unique_ptr<AbstractTemperatureUnitModel> temperatureUnitModel;
        std::unique_ptr<AbstractLayoutModel> layoutModel;
    };
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/models/TimeUnitsModel.cpp => products/BellHybrid/apps/application-bell-settings/models/TimeUnitsModel.cpp +5 -0
@@ 120,6 120,11 @@ namespace app::bell_settings
#endif
    }

    auto TimeUnitsModel::getTimeFormat() const -> utils::time::Locale::TimeFormat
    {
        return timeFmtSetListItem->getTimeFmt();
    }

    auto TimeUnitsModel::setTemperatureUnit(const utils::temperature::Temperature::Unit unit) -> void
    {
#if CONFIG_ENABLE_TEMP == 1

M products/BellHybrid/apps/application-bell-settings/presenter/LayoutWindowPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/LayoutWindowPresenter.cpp +14 -43
@@ 71,49 71,20 @@ namespace app::bell_settings

    void LayoutWindowPresenter::initLayoutOptions()
    {
        auto layoutsList = gui::homeScreenLayouts();

        auto layoutClassicWithTemp = layoutsList.at("ClassicWithTemp")();
        layoutClassicWithTemp->setAlarmEdit(false);
        layoutClassicWithTemp->setAlarmActive(true);
        layoutClassicWithTemp->setTime(clockTime);
        // layoutClassicWithTemp->setTimeFormat(timeModel->getTimeFormat());
        layoutClassicWithTemp->setAlarmTime(alarmTime);
        layoutClassicWithTemp->setBatteryLevelState(batteryState);
        layoutClassicWithTemp->setViewState(app::home_screen::ViewState::Activated);
        layoutClassicWithTemp->setTemperature(temperature);

        auto layoutClassicWithBattery = layoutsList.at("ClassicWithBattery")();
        layoutClassicWithBattery->setAlarmEdit(false);
        layoutClassicWithBattery->setAlarmActive(true);
        layoutClassicWithBattery->setTime(clockTime);
        // Commented out to remove "AM"/"PM" from time spinner
        // layoutClassicWithBattery->setTimeFormat(timeModel->getTimeFormat());
        layoutClassicWithBattery->setAlarmTime(alarmTime);
        layoutClassicWithBattery->setBatteryLevelState(batteryState);
        layoutClassicWithBattery->setViewState(app::home_screen::ViewState::Activated);

        auto layoutClassicWithAmPm = layoutsList.at("ClassicWithAmPm")();
        layoutClassicWithAmPm->setAlarmEdit(false);
        layoutClassicWithAmPm->setAlarmActive(true);
        layoutClassicWithAmPm->setTime(clockTime);
        // layoutClassicWithAmPm->setTimeFormat(timeModel->getTimeFormat());
        layoutClassicWithAmPm->setAlarmTime(alarmTime);
        layoutClassicWithAmPm->setBatteryLevelState(batteryState);
        layoutClassicWithAmPm->setViewState(app::home_screen::ViewState::Activated);

        auto layoutClassic = layoutsList.at("Classic")();
        layoutClassic->setAlarmEdit(false);
        layoutClassic->setAlarmActive(true);
        layoutClassic->setTime(clockTime);
        // layoutClassic->setTimeFormat(timeModel->getTimeFormat());
        layoutClassic->setAlarmTime(alarmTime);
        layoutClassic->setBatteryLevelState(batteryState);
        layoutClassic->setViewState(app::home_screen::ViewState::Activated);

        layoutOptions.push_back({layoutClassicWithTemp->getLayout(), "ClassicWithTemp"});
        layoutOptions.push_back({layoutClassicWithBattery->getLayout(), "ClassicWithBattery"});
        layoutOptions.push_back({layoutClassicWithAmPm->getLayout(), "ClassicWithAmPm"});
        layoutOptions.push_back({layoutClassic->getLayout(), "Classic"});
        auto layoutsList = timeModel->getTimeFormat() == utils::time::Locale::TimeFormat::FormatTime24H
                               ? gui::factory::getLayoutsFormat24h()
                               : gui::factory::getLayoutsFormat12h();

        for (auto &layoutEntry : layoutsList) {
            auto layout = layoutEntry.second();
            layout->setViewState(app::home_screen::ViewState::Activated);
            layout->setTimeFormat(timeModel->getTimeFormat());
            layout->setTime(clockTime);
            layout->setAlarmTime(alarmTime);
            layout->setBatteryLevelState(batteryState);
            layout->setTemperature(temperature);
            layoutOptions.push_back({layout->getLayout(), layoutEntry.first});
        }
    }
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/presenter/TimeUnitsPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/TimeUnitsPresenter.cpp +34 -2
@@ 4,12 4,21 @@
#include "models/TemperatureUnitModel.hpp"
#include "presenter/TimeUnitsPresenter.hpp"

#include <common/layouts/HomeScreenLayouts.hpp>
#include <common/models/LayoutModel.hpp>

#include <appmgr/messages/ChangeHomescreenLayoutMessage.hpp>
#include <service-appmgr/Constants.hpp>

namespace app::bell_settings
{
    TimeUnitsWindowPresenter::TimeUnitsWindowPresenter(
        app::ApplicationCommon *app,
        std::shared_ptr<TimeUnitsModel> pagesProvider,
        std::unique_ptr<AbstractTemperatureUnitModel> temperatureUnitModel)
        : pagesProvider(std::move(pagesProvider)), temperatureUnitModel{std::move(temperatureUnitModel)}
        std::unique_ptr<AbstractTemperatureUnitModel> temperatureUnitModel,
        std::unique_ptr<AbstractLayoutModel> layoutModel)
        : app{app}, pagesProvider(std::move(pagesProvider)), temperatureUnitModel{std::move(temperatureUnitModel)},
          layoutModel{std::move(layoutModel)}
    {}

    auto TimeUnitsWindowPresenter::getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider>


@@ 26,6 35,29 @@ namespace app::bell_settings
    {
        pagesProvider->saveData();
        temperatureUnitModel->set(pagesProvider->getTemperatureUnit());
        auto timeFormat    = pagesProvider->getTimeFormat();
        auto currentLayout = layoutModel->getValue();

        auto isCurrentLayout12h = true;
        if (timeFormat == utils::time::Locale::TimeFormat::FormatTime24H) {
            for (const auto &layout : gui::factory::getLayoutsFormat24h()) {
                if (layout.first == currentLayout) {
                    isCurrentLayout12h = false;
                    break;
                }
            }
            if (isCurrentLayout12h) {
                std::string fallbackLayout;
                if (currentLayout.rfind("Classic", 0) == 0) {
                    fallbackLayout = "Classic";
                }
                else if (currentLayout.rfind("Vertical", 0) == 0) {
                    fallbackLayout = "VerticalSimple";
                }
                auto layoutChangeRequest = std::make_shared<ChangeHomescreenLayoutMessage>(fallbackLayout);
                app->bus.sendUnicast(layoutChangeRequest, service::name::appmgr);
            }
        }
    }

    auto TimeUnitsWindowPresenter::loadData() -> void

M products/BellHybrid/apps/common/CMakeLists.txt => products/BellHybrid/apps/common/CMakeLists.txt +12 -0
@@ 34,12 34,15 @@ target_sources(application-bell-common
        src/popups/BellTurnOffOptionWindow.cpp
        src/popups/BellRebootWindow.cpp
        src/popups/presenter/AlarmActivatedPresenter.cpp
        src/widgets/AlarmIcon.cpp
        src/widgets/ListItems.cpp
        src/widgets/BellBattery.cpp
        src/widgets/BellStatusClock.cpp
        src/widgets/DuoHBox.cpp
        src/widgets/ProgressTimerWithSnoozeTimer.cpp
        src/widgets/SnoozeTimer.cpp
        src/widgets/LayoutVertical.cpp
        src/widgets/TimeSetSpinnerVertical.cpp

        src/options/BellOptionWindow.cpp
        src/options/BellShortOptionWindow.cpp


@@ 51,6 54,9 @@ target_sources(application-bell-common
        src/layouts/HomeScreenLayoutClassicWithAmPm.cpp
        src/layouts/HomeScreenLayoutClassicWithBattery.cpp
        src/layouts/HomeScreenLayoutClassicWithTemp.cpp
        src/layouts/HomeScreenLayoutVertical.cpp
        src/layouts/HomeScreenLayoutVerticalSimple.cpp
        src/layouts/HomeScreenLayoutVerticalWithAmPm.cpp

    PUBLIC
        include/common/BellListItemProvider.hpp


@@ 83,6 89,7 @@ target_sources(application-bell-common
        include/common/popups/BedtimeNotificationWindow.hpp
        include/common/popups/BellTurnOffOptionWindow.hpp
        include/common/popups/BellRebootWindow.hpp
        include/common/widgets/AlarmIcon.hpp
        include/common/widgets/BellBattery.hpp
        include/common/widgets/BellSideListItemWithCallbacks.hpp
        include/common/widgets/BellStatusClock.hpp


@@ 90,6 97,8 @@ target_sources(application-bell-common
        include/common/widgets/ProgressTimerWithSnoozeTimer.hpp
        include/common/widgets/SnoozeTimer.hpp
        include/common/widgets/ListItems.hpp
        include/common/widgets/LayoutVertical.hpp
        include/common/widgets/TimeSetSpinnerVertical.hpp
        include/common/options/BellOptionWindow.hpp
        include/common/options/BellShortOptionWindow.hpp
        include/common/options/OptionBellMenu.hpp


@@ 99,6 108,9 @@ target_sources(application-bell-common
        include/common/layouts/HomeScreenLayoutClassicWithAmPm.hpp
        include/common/layouts/HomeScreenLayoutClassicWithBattery.hpp
        include/common/layouts/HomeScreenLayoutClassicWithTemp.hpp
        include/common/layouts/HomeScreenLayoutVertical.hpp
        include/common/layouts/HomeScreenLayoutVerticalSimple.hpp
        include/common/layouts/HomeScreenLayoutVerticalWithAmPm.hpp
)

target_link_libraries(application-bell-common

M products/BellHybrid/apps/common/include/common/layouts/BaseHomeScreenLayoutProvider.hpp => products/BellHybrid/apps/common/include/common/layouts/BaseHomeScreenLayoutProvider.hpp +6 -9
@@ 46,22 46,19 @@ namespace gui
            return name;
        }

        virtual void setAlarmTriggered()                                        = 0;
        virtual void setAlarmActive(bool val)                                   = 0;
        virtual void setViewState(app::home_screen::ViewState state)            = 0;
        virtual void setTemperature(utils::temperature::Temperature newTemp)    = 0;
        virtual void setBottomDescription(const UTF8 &desc)                     = 0;
        virtual void removeBottomDescription()                                  = 0;
        virtual void setTextDescription(const UTF8 &desc)                       = 0;
        virtual void setBatteryLevelState(const Store::Battery &batteryContext) = 0;
        virtual void setTime(std::time_t newTime)                               = 0;
        virtual void setTimeFormat(utils::time::Locale::TimeFormat fmt)         = 0;
        virtual void setAlarmTimeFormat(utils::time::Locale::TimeFormat fmt)    = 0;
        virtual void setSnoozeFormat(utils::time::Locale::TimeFormat fmt)       = 0;
        virtual void setAlarmEdit(bool val)                                     = 0;
        virtual std::time_t getAlarmTime() const                                = 0;
        virtual void setAlarmTime(std::time_t newTime)                          = 0;
        virtual void setSnoozeTime(std::time_t newTime)                         = 0;
        virtual SnoozeTimer *getSnoozeTimer()                                   = 0;
        virtual Item *getLayout()                                               = 0;

        virtual void setTemperature(utils::temperature::Temperature newTemp){};
        virtual void setTimeFormat(utils::time::Locale::TimeFormat fmt){};
        virtual void setSnoozeFormat(utils::time::Locale::TimeFormat fmt){};
        virtual void setSnoozeTime(std::time_t newTime){};
    };
}; // namespace gui

M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassic.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassic.hpp +2 -6
@@ 51,17 51,12 @@ namespace gui
        HomeScreenLayoutClassic(std::string name);

        virtual auto setViewState(app::home_screen::ViewState state) -> void override;
        virtual auto setTemperature(utils::temperature::Temperature newTemp) -> void override;
        virtual auto setTime(std::time_t newTime) -> void override;
        auto setAlarmTriggered() -> void override;
        auto setAlarmActive(bool val) -> void override;
        auto setBottomDescription(const UTF8 &desc) -> void override;
        auto removeBottomDescription() -> void override;
        auto setTextDescription(const UTF8 &desc) -> void override;
        auto setBatteryLevelState(const Store::Battery &batteryContext) -> void override;
        auto setTimeFormat(utils::time::Locale::TimeFormat fmt) -> void override;
        auto setAlarmTimeFormat(utils::time::Locale::TimeFormat fmt) -> void override;
        auto setSnoozeFormat(utils::time::Locale::TimeFormat fmt) -> void override;
        auto setAlarmEdit(bool val) -> void override;
        auto getAlarmTime() const -> std::time_t override;
        auto setAlarmTime(std::time_t newTime) -> void override;
        auto setSnoozeTime(std::time_t newTime) -> void override;


@@ 73,6 68,7 @@ namespace gui
        auto setHeaderViewMode(HeaderViewMode mode) -> void;
        virtual auto buildInterface() -> void;
        virtual bool isBatteryVisibilityAllowed(const Store::Battery &batteryContext);
        auto removeTextDescription() -> void;

        TimeSetFmtSpinner *time{};
        DuoHBox *statusBox{};

A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVertical.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVertical.hpp +60 -0
@@ 0,0 1,60 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "BaseHomeScreenLayoutProvider.hpp"
#include "widgets/LayoutVertical.hpp"

#include <apps-common/widgets/BellBaseLayout.hpp>
#include <module-gui/gui/widgets/Item.hpp>

namespace gui
{

    class BellBaseLayout;
    class TextFixedSize;
    class AlarmIcon;
    class AlarmSetSpinner;
    class TimeSetSpinnerVertical;
    class TimeSetFmtSpinner;
    class SnoozeTimer;
    class BellBattery;
    class DuoHBox;
    class Icon;
    class Item;

    namespace battery_vertical
    {
        constexpr auto chargingLevelHideBot    = 100;
        constexpr auto dischargingLevelShowTop = 20;
    }; // namespace battery_vertical

    enum class ScreenMode
    {
        Main,
        AlarmEdit,
        AlarmActivatedDeactivated,
    };

    class HomeScreenLayoutVertical : public BaseHomeScreenLayoutProvider, public LayoutVertical
    {
      public:
        HomeScreenLayoutVertical(std::string name);

        virtual auto setViewState(app::home_screen::ViewState state) -> void override;
        virtual auto setTime(std::time_t newTime) -> void override;
        auto setTextDescription(const UTF8 &desc) -> void override;
        auto setBatteryLevelState(const Store::Battery &batteryContext) -> void override;
        auto setAlarmTimeFormat(utils::time::Locale::TimeFormat fmt) -> void override;
        auto getAlarmTime() const -> std::time_t override;
        auto setAlarmTime(std::time_t newTime) -> void override;

        auto getSnoozeTimer() -> SnoozeTimer * override;
        auto getLayout() -> Item * override;

      protected:
        auto setScreenMode(ScreenMode mode) -> void;
        virtual bool isBatteryVisibilityAllowed(const Store::Battery &batteryContext);
    };
}; // namespace gui

A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVerticalSimple.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVerticalSimple.hpp +16 -0
@@ 0,0 1,16 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "HomeScreenLayoutVertical.hpp"

namespace gui
{

    class HomeScreenLayoutVerticalSimple : public HomeScreenLayoutVertical
    {
      public:
        HomeScreenLayoutVerticalSimple(std::string name);
    };
}; // namespace gui

A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVerticalWithAmPm.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVerticalWithAmPm.hpp +27 -0
@@ 0,0 1,27 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "HomeScreenLayoutVertical.hpp"

namespace style::homescreen_vertical_ampm
{
    constexpr inline auto alarm_margin_top   = 83U;
    constexpr inline auto battery_margin_bot = 68U;
    constexpr inline auto fmt_margin_bot     = 77U;
} // namespace style::homescreen_vertical_ampm

namespace gui
{

    class HomeScreenLayoutVerticalWithAmPm : public HomeScreenLayoutVertical
    {
      public:
        HomeScreenLayoutVerticalWithAmPm(std::string name);

        auto setTime(std::time_t newTime) -> void override;

        TextFixedSize *fmt{};
    };
}; // namespace gui

M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayouts.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayouts.hpp +8 -3
@@ 10,8 10,13 @@
namespace gui
{
    class BaseHomeScreenLayoutProvider;

    using LayoutGenerator = std::function<BaseHomeScreenLayoutProvider *()>;

    std::map<std::string, LayoutGenerator> homeScreenLayouts();
}; // namespace gui
    namespace factory
    {
        std::map<std::string, LayoutGenerator> getLayoutsFormat24h();
        std::map<std::string, LayoutGenerator> getLayoutsFormat12h();

        std::map<std::string, LayoutGenerator> getAllLayouts();
    } // namespace factory
};    // namespace gui

A products/BellHybrid/apps/common/include/common/widgets/AlarmIcon.hpp => products/BellHybrid/apps/common/include/common/widgets/AlarmIcon.hpp +29 -0
@@ 0,0 1,29 @@
// 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/Style.hpp>
#include <gui/widgets/ImageBox.hpp>

namespace gui
{
    class ImageBox;

    class AlarmIcon : public ImageBox
    {
      public:
        enum class Status
        {
            UNKNOWN,
            RINGING,
            ACTIVATED,
            DEACTIVATED,
            SNOOZE
        };

        explicit AlarmIcon(Item *parent = nullptr, Position x = 0U, Position y = 0U, Length w = 0U, Length h = 0U);

        auto setStatus(Status status) noexcept -> void;
    };
} /* namespace gui */

M products/BellHybrid/apps/common/include/common/widgets/BellBattery.hpp => products/BellHybrid/apps/common/include/common/widgets/BellBattery.hpp +3 -3
@@ 30,8 30,8 @@ namespace gui

    enum class BatteryPercentMode
    {
        Dynamic,
        Static,
        Show, // Show always
        Hide  // Never show percentage
    };

    class BellBattery : public gui::HBox


@@ 43,7 43,7 @@ namespace gui
        std::uint32_t getLevel();

      private:
        BatteryPercentMode batteryPercentMode = BatteryPercentMode::Dynamic;
        BatteryPercentMode batteryPercentMode = BatteryPercentMode::Show;
        TextFixedSize *percentText;
        Image *img;
    };

A products/BellHybrid/apps/common/include/common/widgets/LayoutVertical.hpp => products/BellHybrid/apps/common/include/common/widgets/LayoutVertical.hpp +50 -0
@@ 0,0 1,50 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "layouts/BaseHomeScreenLayoutProvider.hpp"

#include <apps-common/widgets/BellBaseLayout.hpp>

namespace style::homescreen_vertical
{
    constexpr inline auto side_box_w   = 180U;
    constexpr inline auto center_box_w = 240U;
} // namespace style::homescreen_vertical

namespace gui
{
    class BellBaseLayout;
    class TextFixedSize;
    class AlarmIcon;
    class AlarmSetSpinner;
    class TimeSetSpinnerVertical;
    class TimeSetFmtSpinner;
    class SnoozeTimer;
    class BellBattery;
    class DuoHBox;
    class Icon;

    class LayoutVertical : public HBox
    {
      public:
        LayoutVertical(
            Item *parent, const uint32_t &x = 0, const uint32_t &y = 0, const uint32_t &w = 0, const uint32_t &h = 0);

        HBox *mainScreen{};
        BellBaseLayout *setAlarmScreen{};
        Icon *alarmActivatedDeactivatedScreen{};
        AlarmIcon *alarmMainIcon{};
        BellBattery *battery{};

        // Main Screen
        TimeSetSpinnerVertical *time{};
        VBox *leftBox{};
        VBox *rightBox{};

        // Set Alarm Screen
        AlarmIcon *alarmTopIcon{};
        TimeSetFmtSpinner *setAlarmFmtSpinner{};
    };
}; // namespace gui

A products/BellHybrid/apps/common/include/common/widgets/TimeSetSpinnerVertical.hpp => products/BellHybrid/apps/common/include/common/widgets/TimeSetSpinnerVertical.hpp +77 -0
@@ 0,0 1,77 @@
// 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 <widgets/spinners/Spinners.hpp>
#include <gui/widgets/Style.hpp>
#include <gui/widgets/text/TextConstants.hpp>
#include <time/time_locale.hpp>

#include <string>

namespace style::time_set_spinner_vertical
{
    namespace focus
    {
        inline constexpr auto size = 6U;
    } // namespace focus

    inline constexpr auto small_margin = 6U;
    inline constexpr auto big_margin   = 44U;
} // namespace style::time_set_spinner_vertical

namespace gui
{
    /// Time set spinner widget class with option for dynamic switching between 24/12-hour format
    /// Automatically recalculates hour upon switching format
    /// Can be used as a basic time displaying widget when @ref EditMode set to 'Browse'
    /// @ref KeyCode::KEY_ENTER switches hour -> minute -> time format
    /// @ref KeyCode::KEY_RF switches back
    /// Two time formats are supported:
    /// utils::time::Locale::TimeFormat::FormatTime12H
    /// utils::time::Locale::TimeFormat::FormatTime24H
    class TimeSetSpinnerVertical : public VBox
    {
      public:
        TimeSetSpinnerVertical(
            Item *parent                               = nullptr,
            uint32_t x                                 = 0U,
            uint32_t y                                 = 0U,
            uint32_t w                                 = 0U,
            uint32_t h                                 = 0U,
            utils::time::Locale::TimeFormat timeFormat = utils::time::Locale::TimeFormat::FormatTime12H);

        /// Switches currently displayed time format
        auto setTimeFormat(utils::time::Locale::TimeFormat fmt) noexcept -> void;
        auto setHour(int value) noexcept -> void;
        auto setMinute(int value) noexcept -> void;
        auto setTime(std::time_t time) noexcept -> void;
        auto setFont(const std::string &newFontName) noexcept -> void;
        auto updateFont(TextFixedSize *elem, const std::string &fontName) noexcept -> void;

        [[nodiscard]] auto getTime() const noexcept -> std::time_t;
        [[nodiscard]] auto getHour() const noexcept -> int;
        [[nodiscard]] auto getMinute() const noexcept -> int;
        [[nodiscard]] auto isPM() const noexcept -> bool;

        auto getTimeFormat() const noexcept -> utils::time::Locale::TimeFormat;

        auto getHourMargins(const std::string &font) const noexcept -> Margins;

      private:
        std::map<std::string, Margins> spaceMarginsMap = {
            {style::window::font::verybiglight, {0, 0, 0, style::time_set_spinner_vertical::small_margin}},
            {style::window::font::largelight, {0, 0, 0, style::time_set_spinner_vertical::small_margin}},
            {style::window::font::supersizemelight, {0, 0, 0, style::time_set_spinner_vertical::big_margin}},
            {style::window::font::huge, {0, 0, 0, style::time_set_spinner_vertical::big_margin}}};

        void handleContentChanged() override;

        UIntegerSpinnerFixed *hour   = nullptr;
        UIntegerSpinnerFixed *minute = nullptr;
        std::string fontName         = style::window::font::supersizemelight;

        utils::time::Locale::TimeFormat timeFormat = utils::time::Locale::TimeFormat::FormatTime12H;
    };
} /* namespace gui */

M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassic.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassic.cpp +20 -40
@@ 59,7 59,7 @@ namespace gui
        battery->setEdges(RectangleEdge::None);
        battery->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        battery->setVisible(true);
        battery->setBatteryPercentMode(BatteryPercentMode::Static);
        battery->setBatteryPercentMode(BatteryPercentMode::Show);

        statusBox->setItems(battery, nullptr);



@@ 80,61 80,54 @@ namespace gui
        return snoozeTimer;
    }

    void HomeScreenLayoutClassic::setAlarmTriggered()
    {
        alarm->setAlarmStatus(AlarmSetSpinner::Status::RINGING);
    }

    void HomeScreenLayoutClassic::setAlarmActive(bool val)
    {
        if (val) {
            alarm->setAlarmStatus(AlarmSetSpinner::Status::ACTIVATED);
        }
        else {
            alarm->setAlarmStatus(AlarmSetSpinner::Status::DEACTIVATED);
        }
    }

    void HomeScreenLayoutClassic::setViewState(app::home_screen::ViewState state)
    {
        switch (state) {
        case app::home_screen::ViewState::Deactivated:
            setAlarmEdit(false);
            setAlarmActive(false);
            alarm->setAlarmStatus(AlarmSetSpinner::Status::DEACTIVATED);
            setHeaderViewMode(HeaderViewMode::Empty);
            alarm->setEditMode(EditMode::Browse);
            removeTextDescription();
            break;
        case app::home_screen::ViewState::DeactivatedWait:
            setAlarmActive(false);
            alarm->setAlarmStatus(AlarmSetSpinner::Status::DEACTIVATED);
            setHeaderViewMode(HeaderViewMode::AlarmIcon);
            alarm->setEditMode(EditMode::Browse);
            break;
        case app::home_screen::ViewState::WaitForConfirmation:
            setBottomDescription(utils::translate("app_bellmain_home_screen_bottom_desc_dp"));
            setTextDescription(utils::translate("app_bellmain_home_screen_bottom_desc_dp"));
            break;
        case app::home_screen::ViewState::AlarmEdit:
            setAlarmEdit(true);
            alarm->setEditMode(EditMode::Edit);
            setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
            break;
        case app::home_screen::ViewState::ActivatedWait:
            setAlarmActive(true);
            alarm->setAlarmStatus(AlarmSetSpinner::Status::ACTIVATED);
            setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
            alarm->setEditMode(EditMode::Browse);
            break;
        case app::home_screen::ViewState::Activated:
            setAlarmActive(true);
            alarm->setAlarmStatus(AlarmSetSpinner::Status::ACTIVATED);
            setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
            alarm->setEditMode(EditMode::Browse);
            removeTextDescription();
            break;
        case app::home_screen::ViewState::AlarmRinging:
            setAlarmTriggered();
            alarm->setAlarmStatus(AlarmSetSpinner::Status::RINGING);
            setHeaderViewMode(HeaderViewMode::AlarmIcon);
            removeTextDescription();
            break;
        case app::home_screen::ViewState::AlarmRingingDeactivatedWait:
            setAlarmActive(false);
            alarm->setAlarmStatus(AlarmSetSpinner::Status::DEACTIVATED);
            setHeaderViewMode(HeaderViewMode::AlarmIcon);
            break;
        case app::home_screen::ViewState::AlarmSnoozedWait:
            setHeaderViewMode(HeaderViewMode::SnoozeIcon);
            alarm->setEditMode(EditMode::Browse);
            break;
        case app::home_screen::ViewState::AlarmSnoozed:
            setHeaderViewMode(HeaderViewMode::SnoozeIconAndTime);
            removeTextDescription();
            break;
        }
    }


@@ 177,10 170,7 @@ namespace gui
        }
    }

    void HomeScreenLayoutClassic::setTemperature(utils::temperature::Temperature newTemp)
    {}

    void HomeScreenLayoutClassic::setBottomDescription(const UTF8 &desc)
    void HomeScreenLayoutClassic::setTextDescription(const UTF8 &desc)
    {
        statusBox->setVisible(false);
        bottomText->setVisible(true);


@@ 188,7 178,7 @@ namespace gui
        bottomText->informContentChanged();
    }

    void HomeScreenLayoutClassic::removeBottomDescription()
    void HomeScreenLayoutClassic::removeTextDescription()
    {
        bottomText->setText("");
        statusBox->setVisible(true);


@@ 238,16 228,6 @@ namespace gui
        snoozeTimer->setTimeFormat(fmt);
    }

    void HomeScreenLayoutClassic::setAlarmEdit(bool val)
    {
        if (not val) {
            alarm->setEditMode(EditMode::Browse);
        }
        else {
            alarm->setEditMode(EditMode::Edit);
        };
    }

    std::time_t HomeScreenLayoutClassic::getAlarmTime() const
    {
        const auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());

A products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVertical.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVertical.cpp +164 -0
@@ 0,0 1,164 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "layouts/HomeScreenLayoutVertical.hpp"
#include "data/BellMainStyle.hpp"
#include "widgets/BellBattery.hpp"
#include "widgets/DuoHBox.hpp"
#include "widgets/SnoozeTimer.hpp"

#include <common/data/StyleCommon.hpp>
#include <apps-common/actions/AlarmRingingData.hpp>
#include <gui/input/InputEvent.hpp>
#include <gui/widgets/Icon.hpp>
#include <gui/widgets/text/TextFixedSize.hpp>
#include <gui/widgets/Style.hpp>
#include <time/time_constants.hpp>
#include <widgets/AlarmIcon.hpp>
#include <widgets/AlarmSetSpinner.hpp>
#include <widgets/TimeSetSpinnerVertical.hpp>

namespace gui
{
    HomeScreenLayoutVertical::HomeScreenLayoutVertical(std::string name)
        : BaseHomeScreenLayoutProvider(std::move(name)),
          LayoutVertical(nullptr, 0, 0, style::window_width, style::window_height)
    {}

    SnoozeTimer *HomeScreenLayoutVertical::getSnoozeTimer()
    {
        return nullptr;
    }

    void HomeScreenLayoutVertical::setViewState(app::home_screen::ViewState state)
    {
        switch (state) {
        case app::home_screen::ViewState::Deactivated:
            alarmMainIcon->setVisible(false);
            alarmTopIcon->setStatus(AlarmIcon::Status::DEACTIVATED);
            setScreenMode(ScreenMode::Main);
            break;
        case app::home_screen::ViewState::DeactivatedWait:
            setScreenMode(ScreenMode::AlarmActivatedDeactivated);
            alarmTopIcon->setStatus(AlarmIcon::Status::DEACTIVATED);
            alarmActivatedDeactivatedScreen->image->set("big_no-alarm_W_G", {});
            break;
        case app::home_screen::ViewState::WaitForConfirmation:
            setScreenMode(ScreenMode::AlarmActivatedDeactivated);
            break;
        case app::home_screen::ViewState::AlarmEdit:
            setScreenMode(ScreenMode::AlarmEdit);
            break;
        case app::home_screen::ViewState::ActivatedWait:
            setScreenMode(ScreenMode::AlarmActivatedDeactivated);
            alarmTopIcon->setStatus(AlarmIcon::Status::ACTIVATED);
            alarmActivatedDeactivatedScreen->image->set("big_alarm_W_G", {});
            break;
        case app::home_screen::ViewState::Activated:
            alarmMainIcon->setVisible(true);
            alarmMainIcon->setStatus(AlarmIcon::Status::ACTIVATED);
            alarmTopIcon->setStatus(AlarmIcon::Status::ACTIVATED);
            setScreenMode(ScreenMode::Main);
            break;
        case app::home_screen::ViewState::AlarmRinging:
            setScreenMode(ScreenMode::Main);
            alarmMainIcon->setStatus(AlarmIcon::Status::RINGING);
            break;
        case app::home_screen::ViewState::AlarmRingingDeactivatedWait:
            setScreenMode(ScreenMode::AlarmActivatedDeactivated);
            break;
        case app::home_screen::ViewState::AlarmSnoozedWait:
            alarmMainIcon->setStatus(AlarmIcon::Status::SNOOZE);
            alarmActivatedDeactivatedScreen->image->set("big_alarm_snoozed_W_M", {});
            setScreenMode(ScreenMode::AlarmActivatedDeactivated);
            break;
        case app::home_screen::ViewState::AlarmSnoozed:
            alarmMainIcon->setStatus(AlarmIcon::Status::SNOOZE);
            setScreenMode(ScreenMode::Main);
            break;
        }
    }

    auto HomeScreenLayoutVertical::setScreenMode(ScreenMode mode) -> void
    {
        switch (mode) {
        case ScreenMode::Main:
            mainScreen->setVisible(true);
            setAlarmScreen->setVisible(false);
            alarmActivatedDeactivatedScreen->setVisible(false);
            mainScreen->informContentChanged();
            break;
        case ScreenMode::AlarmEdit:
            mainScreen->setVisible(false);
            setAlarmScreen->setVisible(true);
            alarmActivatedDeactivatedScreen->setVisible(false);
            setAlarmScreen->informContentChanged();
            // This is an ugly hack to update format on alarm spinner.
            // Will not be neccessary when visible flags get fixed
            setAlarmFmtSpinner->setTimeFormat(setAlarmFmtSpinner->getTimeFormat());
            break;
        case ScreenMode::AlarmActivatedDeactivated:
            mainScreen->setVisible(false);
            setAlarmScreen->setVisible(false);
            alarmActivatedDeactivatedScreen->setVisible(true);
            alarmActivatedDeactivatedScreen->informContentChanged();
            break;
        }
        resizeItems();
    }

    void HomeScreenLayoutVertical::setTextDescription(const UTF8 &desc)
    {
        alarmActivatedDeactivatedScreen->text->setRichText(desc);
        alarmActivatedDeactivatedScreen->text->informContentChanged();
    }

    bool HomeScreenLayoutVertical::isBatteryVisibilityAllowed(const Store::Battery &batteryContext)
    {
        return (batteryContext.level < battery_vertical::dischargingLevelShowTop) ||
               (batteryContext.state == Store::Battery::State::Charging &&
                batteryContext.level != battery_vertical::chargingLevelHideBot);
    }

    void HomeScreenLayoutVertical::setBatteryLevelState(const Store::Battery &batteryContext)
    {
        battery->update(batteryContext);
        if (isBatteryVisibilityAllowed(batteryContext)) {
            battery->setVisible(true);
        }
        else {
            battery->setVisible(false);
        }
        battery->informContentChanged();
    }

    void HomeScreenLayoutVertical::setTime(std::time_t newTime)
    {
        time->setTime(newTime);
    }

    void HomeScreenLayoutVertical::setAlarmTimeFormat(utils::time::Locale::TimeFormat fmt)
    {
        setAlarmFmtSpinner->setTimeFormat(fmt);
    }

    std::time_t HomeScreenLayoutVertical::getAlarmTime() const
    {
        const auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
        auto alarmTime = setAlarmFmtSpinner->getTime();
        if (alarmTime < now) {
            alarmTime += utils::time::secondsInDay;
        }
        return alarmTime;
    }

    void HomeScreenLayoutVertical::setAlarmTime(std::time_t newTime)
    {
        setAlarmFmtSpinner->setTime(newTime);
    }

    auto HomeScreenLayoutVertical::getLayout() -> Item *
    {
        return this;
    }
}; // namespace gui

A products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalSimple.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalSimple.cpp +38 -0
@@ 0,0 1,38 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "layouts/HomeScreenLayoutVerticalSimple.hpp"
#include "data/BellMainStyle.hpp"
#include "widgets/BellBattery.hpp"
#include "widgets/DuoHBox.hpp"
#include "widgets/SnoozeTimer.hpp"

#include <apps-common/actions/AlarmRingingData.hpp>
#include <gui/input/InputEvent.hpp>
#include <gui/widgets/Icon.hpp>
#include <gui/widgets/text/TextFixedSize.hpp>
#include <gui/widgets/Style.hpp>
#include <time/time_constants.hpp>
#include <widgets/AlarmIcon.hpp>
#include <widgets/AlarmSetSpinner.hpp>
#include <widgets/TimeSetSpinnerVertical.hpp>

namespace gui
{
    HomeScreenLayoutVerticalSimple::HomeScreenLayoutVerticalSimple(std::string name)
        : HomeScreenLayoutVertical(std::move(name))
    {
        using namespace bellMainStyle;

        leftBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        leftBox->addWidget(battery);
        battery->informContentChanged();

        rightBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        rightBox->addWidget(alarmMainIcon);
        alarmMainIcon->informContentChanged();

        leftBox->resizeItems();
        rightBox->resizeItems();
    }
}; // namespace gui

A products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalWithAmPm.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalWithAmPm.cpp +69 -0
@@ 0,0 1,69 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "layouts/HomeScreenLayoutVerticalWithAmPm.hpp"
#include "data/BellMainStyle.hpp"
#include "widgets/BellBattery.hpp"
#include "widgets/SnoozeTimer.hpp"

#include <apps-common/actions/AlarmRingingData.hpp>
#include <gui/input/InputEvent.hpp>
#include <gui/widgets/Icon.hpp>
#include <gui/widgets/text/TextFixedSize.hpp>
#include <gui/widgets/Style.hpp>
#include <time/time_constants.hpp>
#include <widgets/AlarmIcon.hpp>
#include <widgets/AlarmSetSpinner.hpp>
#include <widgets/TimeSetSpinnerVertical.hpp>

namespace gui
{
    HomeScreenLayoutVerticalWithAmPm::HomeScreenLayoutVerticalWithAmPm(std::string name)
        : HomeScreenLayoutVertical(std::move(name))
    {
        using namespace bellMainStyle;

        leftBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        auto leftTopBox = new gui::VBox(leftBox);
        leftTopBox->setMinimumSize(leftTopBox->parent->getWidth(), leftTopBox->parent->getHeight() / 2);
        leftTopBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        leftTopBox->setEdges(RectangleEdge::None);

        auto leftBottomBox = new gui::VBox(leftBox);
        leftBottomBox->setMinimumSize(leftBottomBox->parent->getWidth(), leftBottomBox->parent->getHeight() / 2);
        leftBottomBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        leftBottomBox->setEdges(RectangleEdge::None);

        leftTopBox->addWidget(alarmMainIcon);
        leftTopBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
        alarmMainIcon->setMargins(Margins{0, style::homescreen_vertical_ampm::alarm_margin_top, 0, 0});

        leftBottomBox->addWidget(battery);
        leftBottomBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Bottom));
        battery->setMargins(Margins{0, 0, 0, style::homescreen_vertical_ampm::battery_margin_bot});

        rightBox->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Bottom));
        fmt = new TextFixedSize(rightBox, 0, 0, 0, 0);
        fmt->setMaximumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
        fmt->setFont(mainWindow::bottomDescription::font_small);
        fmt->setEdges(RectangleEdge::None);
        fmt->activeItem = false;
        fmt->drawUnderline(false);
        fmt->setMargins(Margins{0, 0, 0, style::homescreen_vertical_ampm::fmt_margin_bot});
        fmt->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Bottom));

        alarmMainIcon->informContentChanged();
        battery->informContentChanged();
        fmt->informContentChanged();
    }

    auto HomeScreenLayoutVerticalWithAmPm::setTime(std::time_t newTime) -> void
    {
        HomeScreenLayoutVertical::setTime(newTime);

        const auto t     = std::localtime(&newTime);
        const auto hours = std::chrono::hours{t->tm_hour};
        const auto isPM  = date::is_pm(hours);
        fmt->setText(isPM ? utils::time::Locale::getPM() : utils::time::Locale::getAM());
    }
}; // namespace gui

M products/BellHybrid/apps/common/src/layouts/HomeScreenLayouts.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayouts.cpp +24 -6
@@ 7,15 7,33 @@
#include <common/layouts/HomeScreenLayoutClassicWithAmPm.hpp>
#include <common/layouts/HomeScreenLayoutClassicWithBattery.hpp>
#include <common/layouts/HomeScreenLayoutClassicWithTemp.hpp>
#include <common/layouts/HomeScreenLayoutVertical.hpp>
#include <common/layouts/HomeScreenLayoutVerticalSimple.hpp>
#include <common/layouts/HomeScreenLayoutVerticalWithAmPm.hpp>

namespace gui
namespace gui::factory
{
    std::map<std::string, LayoutGenerator> homeScreenLayouts()
    std::map<std::string, LayoutGenerator> getLayoutsFormat24h()
    {
        return {{"ClassicWithTemp", []() { return new HomeScreenLayoutClassicWithTemp("ClassicWithTemp"); }},
                {"Classic", []() { return new HomeScreenLayoutClassic("Classic"); }},
        return {{"Classic", []() { return new HomeScreenLayoutClassic("Classic"); }},
                {"ClassicWithTemp", []() { return new HomeScreenLayoutClassicWithTemp("ClassicWithTemp"); }},
                {"ClassicWithBattery", []() { return new HomeScreenLayoutClassicWithBattery("ClassicWithBattery"); }},
                {"VerticalSimple", []() { return new HomeScreenLayoutVerticalSimple("VerticalSimple"); }}};
    };

    std::map<std::string, LayoutGenerator> getLayoutsFormat12h()
    {
        return {{"Classic", []() { return new HomeScreenLayoutClassic("Classic"); }},
                {"ClassicWithTemp", []() { return new HomeScreenLayoutClassicWithTemp("ClassicWithTemp"); }},
                {"ClassicWithAmPm", []() { return new HomeScreenLayoutClassicWithAmPm("ClassicWithAmPm"); }},
                {"ClassicWithBattery", []() { return new HomeScreenLayoutClassicWithBattery("ClassicWithBattery"); }}};
                {"ClassicWithBattery", []() { return new HomeScreenLayoutClassicWithBattery("ClassicWithBattery"); }},
                {"VerticalSimple", []() { return new HomeScreenLayoutVerticalSimple("VerticalSimple"); }},
                {"VerticalWithAmPm", []() { return new HomeScreenLayoutVerticalWithAmPm("VerticalWithAmPm"); }}};
    };

    std::map<std::string, LayoutGenerator> getAllLayouts()
    {
        return getLayoutsFormat12h();
    };

} // namespace gui
} // namespace gui::factory

A products/BellHybrid/apps/common/src/widgets/AlarmIcon.cpp => products/BellHybrid/apps/common/src/widgets/AlarmIcon.cpp +46 -0
@@ 0,0 1,46 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <common/widgets/AlarmIcon.hpp>

#include <FontManager.hpp>
#include <RawFont.hpp>
#include <apps-common/widgets/TimeSetFmtSpinner.hpp>

namespace gui
{
    AlarmIcon::AlarmIcon(Item *parent, Position x, Position y, Length w, Length h)
        : ImageBox(parent, x, y, w, h, new Image("bell_alarm_deactivated_W_M"))
    {}

    auto AlarmIcon::setStatus(Status status) noexcept -> void
    {
        switch (status) {
        case Status::ACTIVATED:
            setImage("bell_alarm_activated_W_M");
            break;
        case Status::DEACTIVATED:
            setImage("bell_alarm_deactivated_W_M");
            break;
        case Status::RINGING:
            setImage("bell_alarm_ringing_W_G");
            setMinimumSizeToFitImage();
            break;
        case Status::SNOOZE:
            setImage("bell_alarm_snooze_W_M");
            break;
        case Status::UNKNOWN:
            setImage("bell_alarm_deactivated_W_M");
            break;
        default:
            setImage("bell_alarm_deactivated_W_M");
            break;
        }

        setMinimumSizeToFitImage();
        setMaximumSize(widgetMinimumArea.w, widgetMinimumArea.h);

        informContentChanged();
    }

} /* namespace gui */

M products/BellHybrid/apps/common/src/widgets/BellBattery.cpp => products/BellHybrid/apps/common/src/widgets/BellBattery.cpp +7 -5
@@ 33,6 33,7 @@ namespace gui
        percentText->setEdges(RectangleEdge::None);
        percentText->activeItem = false;
        percentText->drawUnderline(false);
        percentText->setVisible(false);
    }

    void BellBattery::update(const Store::Battery &batteryContext)


@@ 43,29 44,30 @@ namespace gui
        }

        const auto level = batteryContext.level;
        percentText->setText(std::to_string(level) + "%");

        if (batteryContext.state == Store::Battery::State::Charging) {
            img->set(battery::battery_charging, gui::ImageTypeSpecifier::W_M);
        }
        else {
            img->set(image->data(), gui::ImageTypeSpecifier::W_M);
            img->informContentChanged();
        }

        if (batteryPercentMode == BatteryPercentMode::Static || level < lowBatteryLimit ||
            batteryContext.state == Store::Battery::State::Charging) {
            percentText->setText(std::to_string(level) + "%");
        if (batteryPercentMode == BatteryPercentMode::Show) {
            percentText->setVisible(true);
        }
        else {
            percentText->setVisible(false);
        }
        percentText->informContentChanged();
        img->informContentChanged();
    }

    void BellBattery::setBatteryPercentMode(BatteryPercentMode mode)
    {
        batteryPercentMode = mode;
        if (batteryPercentMode == BatteryPercentMode::Hide) {
            percentText->setVisible(false);
        }
    }

    std::uint32_t BellBattery::getLevel()

A products/BellHybrid/apps/common/src/widgets/LayoutVertical.cpp => products/BellHybrid/apps/common/src/widgets/LayoutVertical.cpp +103 -0
@@ 0,0 1,103 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "widgets/LayoutVertical.hpp"
#include "data/BellMainStyle.hpp"
#include "widgets/BellBattery.hpp"
#include "widgets/DuoHBox.hpp"
#include "widgets/SnoozeTimer.hpp"

#include <common/data/StyleCommon.hpp>
#include <apps-common/actions/AlarmRingingData.hpp>
#include <gui/input/InputEvent.hpp>
#include <gui/widgets/Icon.hpp>
#include <gui/widgets/text/TextFixedSize.hpp>
#include <gui/widgets/Style.hpp>
#include <time/time_constants.hpp>
#include <widgets/AlarmIcon.hpp>
#include <widgets/AlarmSetSpinner.hpp>
#include <widgets/TimeSetSpinnerVertical.hpp>

namespace gui
{
    LayoutVertical::LayoutVertical(
        Item *parent, const uint32_t &x, const uint32_t &y, const uint32_t &w, const uint32_t &h)
        : HBox(parent, x, y, w, h)
    {
        using namespace bellMainStyle;

        // Main Screen
        mainScreen = new HBox(this);
        mainScreen->setMinimumSize(style::window_width, style::window_height);

        leftBox = new VBox(mainScreen, 0, 0, 0, 0);
        leftBox->setMinimumSize(style::homescreen_vertical::side_box_w, style::window_height);
        leftBox->setEdges(RectangleEdge::None);

        auto centerBox = new VBox(mainScreen, 0, 0, 0, 0);
        centerBox->setMinimumSize(style::homescreen_vertical::center_box_w, style::window_height);
        centerBox->setEdges(RectangleEdge::None);

        time = new TimeSetSpinnerVertical(centerBox);
        time->setFont(mainWindow::time::font);
        time->setMinimumSize(style::homescreen_vertical::center_box_w, style::window_height);
        time->setEdges(RectangleEdge::None);
        time->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        rightBox = new VBox(mainScreen, 0, 0, 0, 0);
        rightBox->setMinimumSize(style::homescreen_vertical::side_box_w, style::window_height);
        rightBox->setEdges(RectangleEdge::None);

        alarmMainIcon = new AlarmIcon(nullptr);
        alarmMainIcon->setMinimumSize(style::bell_base_layout::outer_layouts_w,
                                      style::bell_base_layout::outer_layouts_h);
        alarmMainIcon->setStatus(AlarmIcon::Status::DEACTIVATED);
        alarmMainIcon->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        battery = new BellBattery(nullptr, 0, 0, 0, 0);
        battery->setMinimumSize(battery::battery_widget_w, battery::battery_widget_h);
        battery->setEdges(RectangleEdge::None);
        battery->setVisible(true);
        battery->setBatteryPercentMode(BatteryPercentMode::Hide);
        battery->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        // Set Alarm Screen
        setAlarmScreen = new BellBaseLayout(this);
        setAlarmScreen->setMinimumSize(style::window_width, style::window_height);
        alarmTopIcon = new AlarmIcon(setAlarmScreen->firstBox);
        alarmTopIcon->setStatus(AlarmIcon::Status::DEACTIVATED);
        alarmTopIcon->setMinimumSize(style::bell_base_layout::outer_layouts_w,
                                     style::bell_base_layout::outer_layouts_h);

        alarmTopIcon->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        setAlarmFmtSpinner = new TimeSetFmtSpinner(setAlarmScreen->getCenterBox());
        setAlarmFmtSpinner->setMinimumSize(style::bell_base_layout::w, style::bell_base_layout::h);
        setAlarmFmtSpinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        setAlarmFmtSpinner->setFont(style::window::font::supersizemelight);
        setAlarmFmtSpinner->activeItem = false;

        setAlarmScreen->getCenterBox()->setAlignment(
            Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        setAlarmScreen->resizeItems();
        setAlarmScreen->setVisible(false);

        // Activation / Deactivation
        alarmActivatedDeactivatedScreen =
            new Icon(this, 0, 0, style::window_width, style::window_height, "big_alarm_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->setAlignment(
            Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        alarmActivatedDeactivatedScreen->text->setFont(style::window::font::verybiglight);
        alarmActivatedDeactivatedScreen->resizeItems();
        alarmActivatedDeactivatedScreen->setVisible(false);
        alarmActivatedDeactivatedScreen->image->setEdges(RectangleEdge::All);

        resizeItems();
    }
}; // namespace gui

A products/BellHybrid/apps/common/src/widgets/TimeSetSpinnerVertical.cpp => products/BellHybrid/apps/common/src/widgets/TimeSetSpinnerVertical.cpp +197 -0
@@ 0,0 1,197 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <common/widgets/TimeSetSpinnerVertical.hpp>

#include <date/date.h>
#include <gui/core/FontManager.hpp>
#include <gui/core/RawFont.hpp>
#include <widgets/spinners/Spinners.hpp>

static constexpr auto hourMin         = 0;
static constexpr auto hourMax         = 23;
static constexpr auto hourDoubleDigit = 10;
static constexpr auto hourStep        = 1;
static constexpr auto minuteMin       = 0;
static constexpr auto minuteMax       = 59;
static constexpr auto minuteStep      = 1;

namespace gui
{

    TimeSetSpinnerVertical::TimeSetSpinnerVertical(
        Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h, utils::time::Locale::TimeFormat timeFormat)
        : VBox{parent, x, y, w, h}
    {
        using namespace utils;

        setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        setEdges(RectangleEdge::None);

        hour =
            new UIntegerSpinnerFixed(UIntegerSpinnerFixed::Range{hourMin, hourMax, hourStep}, Boundaries::Continuous);
        updateFont(hour, fontName);

        hour->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        hour->setEdges(RectangleEdge::None);
        hour->setPenFocusWidth(style::time_set_spinner_vertical::focus::size);
        hour->setCurrentValue(0);
        hour->setMargins(getHourMargins(fontName));

        addWidget(hour);

        minute = new UIntegerSpinnerFixed(UIntegerSpinnerFixed::Range{minuteMin, minuteMax, minuteStep},
                                          Boundaries::Continuous);
        updateFont(minute, fontName);
        minute->setPenFocusWidth(style::time_set_spinner_vertical::focus::size);

        minute->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        minute->setEdges(RectangleEdge::None);
        minute->setCurrentValue(0);
        addWidget(minute);

        resizeItems();

        setTimeFormat(timeFormat);
    }

    auto TimeSetSpinnerVertical::setTimeFormat(utils::time::Locale::TimeFormat newFormat) noexcept -> void
    {
        using namespace utils;

        switch (newFormat) {
        case utils::time::Locale::TimeFormat::FormatTime12H: {
            auto hours = std::chrono::hours(hour->getCurrentValue());
            hour->setRange(UIntegerSpinnerFixed::Range{
                time::Locale::min_hour_12H_mode, time::Locale::max_hour_12H_mode, hourStep});

            if (timeFormat != newFormat) {
                hour->setCurrentValue(date::make12(hours).count());
            }

        } break;
        case utils::time::Locale::TimeFormat::FormatTime24H: {
            auto hours = std::chrono::hours(hour->getCurrentValue());
            hour->setRange(UIntegerSpinnerFixed::Range{
                time::Locale::min_hour_24H_mode, time::Locale::max_hour_24H_mode, hourStep});

            if (newFormat != timeFormat) {
                hour->setCurrentValue(date::make24(hours, isPM()).count());
            }
        } break;
        default:
            break;
        }

        timeFormat = newFormat;
    }

    auto TimeSetSpinnerVertical::setMinute(int value) noexcept -> void
    {
        minute->setCurrentValue(value);
    }

    auto TimeSetSpinnerVertical::getHour() const noexcept -> int
    {
        return hour->getCurrentValue();
    }

    auto TimeSetSpinnerVertical::getMinute() const noexcept -> int
    {
        return minute->getCurrentValue();
    }

    auto TimeSetSpinnerVertical::setHour(int value) noexcept -> void
    {
        hour->setCurrentValue(value);
    }

    auto TimeSetSpinnerVertical::updateFont(TextFixedSize *elem, const std::string &fontName) noexcept -> void
    {
        elem->setFont(fontName);
        elem->setMinimumHeightToFitText();
        elem->setMinimumWidthToFitText();

        elem->setText(elem->getText());
    }

    auto TimeSetSpinnerVertical::setFont(const std::string &newFontName) noexcept -> void
    {
        fontName = newFontName;

        updateFont(hour, fontName);
        updateFont(minute, fontName);
        auto hourMargins = getHourMargins(fontName);
        hour->setMargins(getHourMargins(fontName));

        auto width = hour->widgetMinimumArea.w > minute->widgetMinimumArea.w ? hour->widgetMinimumArea.w
                                                                             : minute->widgetMinimumArea.w;

        auto verticalMargin = hourMargins.top + hourMargins.bottom;
        setMinimumSize(width, hour->widgetMinimumArea.h + minute->widgetMinimumArea.h + verticalMargin);
        resizeItems();
    }

    auto TimeSetSpinnerVertical::isPM() const noexcept -> bool
    {
        return timeFormat == utils::time::Locale::TimeFormat::FormatTime12H;
    }

    auto TimeSetSpinnerVertical::getTimeFormat() const noexcept -> utils::time::Locale::TimeFormat
    {
        return timeFormat;
    }

    auto TimeSetSpinnerVertical::setTime(std::time_t time) noexcept -> void
    {
        using namespace utils::time;
        const auto t = std::localtime(&time);

        if (timeFormat == Locale::TimeFormat::FormatTime24H) {
            hour->setCurrentValue(t->tm_hour);
            minute->setCurrentValue(t->tm_min);
        }
        else {
            const auto hours   = std::chrono::hours{t->tm_hour};
            const auto time12H = date::make12(hours);
            hour->setCurrentValue(time12H.count());
            minute->setCurrentValue(t->tm_min);
        }
    }

    auto TimeSetSpinnerVertical::getTime() const noexcept -> std::time_t
    {
        using namespace utils::time;
        const auto now     = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
        const auto newTime = std::localtime(&now);
        if (timeFormat == Locale::TimeFormat::FormatTime24H) {
            newTime->tm_hour = hour->getCurrentValue();
        }
        else {
            newTime->tm_hour = date::make24(std::chrono::hours{hour->getCurrentValue()}, isPM()).count();
        }
        newTime->tm_min = minute->getCurrentValue();

        return std::mktime(newTime);
    }

    void TimeSetSpinnerVertical::handleContentChanged()
    {
        hour->setMinimumWidthToFitText();
        minute->setMinimumWidthToFitText();

        auto width = hour->widgetMinimumArea.w > minute->widgetMinimumArea.w ? hour->widgetMinimumArea.w
                                                                             : minute->widgetMinimumArea.w;

        setMinimumSize(width, hour->widgetMinimumArea.h + minute->widgetMinimumArea.h + 10);
        setMaximumWidth(widgetMinimumArea.w);

        VBox::informContentChanged();
    }

    auto TimeSetSpinnerVertical::getHourMargins(const std::string &font) const noexcept -> Margins
    {
        return spaceMarginsMap.find(font)->second;
    }

} // namespace gui

M products/BellHybrid/assets/assets_common.json => products/BellHybrid/assets/assets_common.json +1 -0
@@ 18,6 18,7 @@
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/bell_status_battery_lvl0_W_G.vpi", "output": "assets/images/bell/bell_status_battery_lvl0_W_G.vpi"},
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/bell_alarm_activated_W_M.vpi", "output": "assets/images/bell/bell_alarm_activated_W_M.vpi"},
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/big_alarm_W_G.vpi", "output": "assets/images/bell/big_alarm_W_G.vpi"},
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/big_alarm_snoozed_W_M.vpi", "output": "assets/images/bell/big_alarm_snoozed_W_M.vpi"},
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/bell_battery_lvl2_W_M.vpi", "output": "assets/images/bell/bell_battery_lvl2_W_M.vpi"},
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/bell_mudita_logo_W_G.vpi", "output": "assets/images/bell/bell_mudita_logo_W_G.vpi"},
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/bell_status_battery_lvl5_W_G.vpi", "output": "assets/images/bell/bell_status_battery_lvl5_W_G.vpi"},