~aleteoryx/muditaos

dff73e2bcea338f454d5f3a98d06b9b755bddd69 — Paweł Joński 4 years ago 5dec023
[BH-1315] Change homescreen mechanism

Backend for changable homescreen layouts
28 files changed, 1008 insertions(+), 259 deletions(-)

M image/assets/images/bell/bell_battery_lvl3_W_M.vpi
M module-services/service-appmgr/include/service-appmgr/Actions.hpp
M products/BellHybrid/apps/application-bell-main/ApplicationBellMain.cpp
M products/BellHybrid/apps/application-bell-main/CMakeLists.txt
M products/BellHybrid/apps/application-bell-main/include/application-bell-main/ApplicationBellMain.hpp
R products/BellHybrid/apps/application-bell-main/{ => include}/application-bell-main/presenters/HomeScreenPresenter.hpp
A products/BellHybrid/apps/application-bell-main/layouts/BaseHomeScreenLayoutProvider.hpp
A products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassic.cpp
A products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassic.hpp
A products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithAmPm.cpp
A products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithAmPm.hpp
A products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithBattery.cpp
A products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithBattery.hpp
A products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithTemp.cpp
A products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithTemp.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/widgets/BellBattery.cpp
M products/BellHybrid/apps/application-bell-main/widgets/BellBattery.hpp
A products/BellHybrid/apps/application-bell-main/widgets/DuoHBox.cpp
A products/BellHybrid/apps/application-bell-main/widgets/DuoHBox.hpp
M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp
M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.hpp
A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayouts.hpp
M products/BellHybrid/services/appmgr/ApplicationManager.cpp
M products/BellHybrid/services/appmgr/CMakeLists.txt
A products/BellHybrid/services/appmgr/include/appmgr/messages/ChangeHomescreenLayoutMessage.hpp
A products/BellHybrid/services/appmgr/include/appmgr/messages/ChangeHomescreenLayoutParams.hpp
M image/assets/images/bell/bell_battery_lvl3_W_M.vpi => image/assets/images/bell/bell_battery_lvl3_W_M.vpi +0 -0
M module-services/service-appmgr/include/service-appmgr/Actions.hpp => module-services/service-appmgr/include/service-appmgr/Actions.hpp +1 -0
@@ 59,6 59,7 @@ namespace app::manager
            NotificationsChanged,
            ShowPopup,
            AbortPopup,
            ChangeHomescreenLayout,
            UserAction // The last enumerator in the Action enum.
                       // All user-defined actions shall have values greater than UserAction.
                       // All system-wide actions shall have values lesser than UserAction.

M products/BellHybrid/apps/application-bell-main/ApplicationBellMain.cpp => products/BellHybrid/apps/application-bell-main/ApplicationBellMain.cpp +31 -4
@@ 2,9 2,13 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "include/application-bell-main/ApplicationBellMain.hpp"
#include "layouts/BaseHomeScreenLayoutProvider.hpp"
#include "layouts/HomeScreenLayoutClassic.hpp"
#include "layouts/HomeScreenLayoutClassicWithAmPm.hpp"
#include "layouts/HomeScreenLayoutClassicWithBattery.hpp"
#include "layouts/HomeScreenLayoutClassicWithTemp.hpp"
#include "models/BatteryModel.hpp"
#include "models/TemperatureModel.hpp"
#include "presenters/HomeScreenPresenter.hpp"

#include "windows/BellBatteryShutdownWindow.hpp"
#include "windows/BellHomeScreenWindow.hpp"


@@ 13,6 17,7 @@

#include <apps-common/messages/AppMessage.hpp>
#include <common/BellPowerOffPresenter.hpp>
#include <common/layouts/HomeScreenLayouts.hpp>
#include <common/models/AlarmModel.hpp>
#include <common/models/TimeModel.hpp>
#include <common/windows/BellWelcomeWindow.hpp>


@@ 20,11 25,14 @@
#include <service-db/DBNotificationMessage.hpp>
#include <windows/Dialog.hpp>
#include <service-appmgr/Controller.hpp>
#include <appmgr/messages/ChangeHomescreenLayoutMessage.hpp>
#include <appmgr/messages/ChangeHomescreenLayoutParams.hpp>
#include <system/messages/SystemManagerMessage.hpp>
#include <common/popups/BedtimeNotificationWindow.hpp>

namespace app
{

    ApplicationBellMain::ApplicationBellMain(std::string name,
                                             std::string parent,
                                             StatusIndicators statusIndicators,


@@ 33,6 41,7 @@ namespace app
        : Application(name, parent, statusIndicators, startInBackground, stackDepth)
    {
        bus.channels.push_back(sys::BusChannel::ServiceDBNotifications);

        addActionReceiver(manager::actions::ShowAlarm, [this](auto &&data) {
            switchWindow(gui::name::window::main_window, std::move(data));
            return actionHandled();


@@ 50,6 59,12 @@ namespace app
            return actionHandled();
        });

        addActionReceiver(manager::actions::ChangeHomescreenLayout, [this](auto &&data) {
            auto msgLayout = dynamic_cast<gui::ChangeHomescreenLayoutParams *>(data.get());
            setHomeScreenLayout(msgLayout->getNewHomescreenLayoutName());
            return actionHandled();
        });

        addActionReceiver(app::manager::actions::DisplayLowBatteryScreen, [this](auto &&data) {
            /**
             * Due to the way of handling shutdown sequence by GUI renderer and applications it is required to leave


@@ 75,14 90,17 @@ namespace app

    void ApplicationBellMain::createUserInterface()
    {
        windowsFactory.attach(gui::name::window::main_window, [](ApplicationCommon *app, const std::string &name) {
        windowsFactory.attach(gui::name::window::main_window, [this](ApplicationCommon *app, const std::string &name) {
            auto timeModel        = std::make_unique<app::TimeModel>();
            auto batteryModel     = std::make_unique<app::home_screen::BatteryModel>(app);
            auto temperatureModel = std::make_unique<app::home_screen::TemperatureModel>(app);
            auto alarmModel       = std::make_unique<app::AlarmModel>(app);
            auto presenter        = std::make_unique<app::home_screen::HomeScreenPresenter>(
            homeScreenPresenter   = std::make_shared<app::home_screen::HomeScreenPresenter>(
                app, std::move(alarmModel), std::move(batteryModel), std::move(temperatureModel), std::move(timeModel));
            return std::make_unique<gui::BellHomeScreenWindow>(app, std::move(presenter));
            auto window = std::make_unique<gui::BellHomeScreenWindow>(app, homeScreenPresenter);
            // TODO: To be replaced with settings db read
            setHomeScreenLayout("ClassicWithTemp");
            return window;
        });

        windowsFactory.attach(gui::window::name::bell_main_menu, [](ApplicationCommon *app, const std::string &name) {


@@ 167,4 185,13 @@ namespace app
        }
        return ApplicationCommon::handleSwitchWindow(msgl);
    }

    void ApplicationBellMain::setHomeScreenLayout(std::string layoutName)
    {
        if (gui::homeScreenLayouts.find(layoutName) == gui::homeScreenLayouts.end()) {
            return;
        }
        auto layoutGenerator = gui::homeScreenLayouts.at(layoutName);
        homeScreenPresenter->setLayout(layoutGenerator());
    }
} // namespace app

M products/BellHybrid/apps/application-bell-main/CMakeLists.txt => products/BellHybrid/apps/application-bell-main/CMakeLists.txt +17 -1
@@ 4,9 4,17 @@ add_library(bell::app-main ALIAS application-bell-main)
target_sources(application-bell-main
    PRIVATE
        ApplicationBellMain.cpp

        layouts/HomeScreenLayoutClassic.cpp
        layouts/HomeScreenLayoutClassicWithAmPm.cpp
        layouts/HomeScreenLayoutClassicWithBattery.cpp
        layouts/HomeScreenLayoutClassicWithTemp.cpp

        widgets/BellBattery.cpp
        widgets/DuoHBox.cpp
        widgets/ProgressTimerWithSnoozeTimer.cpp
        widgets/SnoozeTimer.cpp

        windows/BellBatteryShutdownWindow.cpp
        windows/BellHomeScreenWindow.cpp
        windows/BellMainMenuWindow.cpp


@@ 18,7 26,14 @@ target_sources(application-bell-main
        presenters/HomeScreenPresenter.cpp
        presenters/StateController.cpp

        layouts/BaseHomeScreenLayoutProvider.hpp
        layouts/HomeScreenLayoutClassic.hpp
        layouts/HomeScreenLayoutClassicWithAmPm.hpp
        layouts/HomeScreenLayoutClassicWithBattery.hpp
        layouts/HomeScreenLayoutClassicWithTemp.hpp

        widgets/BellBattery.hpp
        widgets/DuoHBox.hpp
        widgets/ProgressTimerWithSnoozeTimer.hpp
        widgets/SnoozeTimer.hpp



@@ 31,12 46,12 @@ target_sources(application-bell-main
        models/BatteryModel.cpp
        models/TemperatureModel.hpp

        presenters/HomeScreenPresenter.hpp
        presenters/StateController.hpp
        presenters/StateControllerLogger.hpp

    PUBLIC
        include/application-bell-main/ApplicationBellMain.hpp
        include/application-bell-main/presenters/HomeScreenPresenter.hpp
)

target_include_directories(application-bell-main


@@ 55,6 70,7 @@ target_link_libraries(application-bell-main
        module-gui
        service-gui
        utils-time
        bell::appmgr
        bell::db
        bell::evtmgr
        bell::app-alarm

M products/BellHybrid/apps/application-bell-main/include/application-bell-main/ApplicationBellMain.hpp => products/BellHybrid/apps/application-bell-main/include/application-bell-main/ApplicationBellMain.hpp +7 -1
@@ 3,6 3,8 @@

#pragma once

#include "presenters/HomeScreenPresenter.hpp"

#include <Application.hpp>
#include <common/models/BedtimeModel.hpp>



@@ 44,6 46,9 @@ namespace app
        auto isHomeScreenFocused() -> bool;
        void onStart() override;
        sys::MessagePointer handleSwitchWindow(sys::Message *msgl) override;
        void setHomeScreenLayout(std::string layoutName);

        std::shared_ptr<app::home_screen::HomeScreenPresenter> homeScreenPresenter{};
    };

    template <> struct ManifestTraits<ApplicationBellMain>


@@ 54,7 59,8 @@ namespace app
                     manager::actions::ShowAlarm,
                     manager::actions::DisplayLogoAtExit,
                     manager::actions::DisplayLowBatteryScreen,
                     manager::actions::SystemBrownout}};
                     manager::actions::SystemBrownout,
                     manager::actions::ChangeHomescreenLayout}};
        }
    };
} // namespace app

R products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.hpp => products/BellHybrid/apps/application-bell-main/include/application-bell-main/presenters/HomeScreenPresenter.hpp +24 -14
@@ 3,9 3,6 @@

#pragma once

#include "models/TemperatureModel.hpp"
#include "widgets/ProgressTimerWithSnoozeTimer.hpp"

#include <apps-common/BasePresenter.hpp>
#include <common/models/AbstractAlarmModel.hpp>
#include <gui/input/InputEvent.hpp>


@@ 22,12 19,15 @@ namespace app
{
    class AbstractTimeModel;
    class ApplicationCommon;
    class TemperatureModel;
    class ProgressTimerWithSnoozeTimer;
} // namespace app

namespace gui
{
    class AppWindow;
}
    class BaseHomeScreenLayoutProvider;
} // namespace gui

namespace db
{


@@ 40,13 40,18 @@ namespace app::home_screen
    class AbstractBatteryModel;
    class AbstractTemperatureModel;

    enum class HeaderViewMode
    enum class ViewState
    {
        Empty,
        AlarmIcon,
        AlarmIconAndTime,
        SnoozeIcon,
        SnoozeIconAndTime
        Deactivated,
        DeactivatedWait,
        WaitForConfirmation,
        AlarmEdit,
        ActivatedWait,
        Activated,
        AlarmRinging,
        AlarmRingingDeactivatedWait,
        AlarmSnoozedWait,
        AlarmSnoozed
    };

    class AbstractView


@@ 58,7 63,7 @@ namespace app::home_screen
        virtual void setAlarmTriggered()                                     = 0;
        virtual void setAlarmActive(bool)                                    = 0;
        virtual void setAlarmEdit(bool)                                      = 0;
        virtual void setHeaderViewMode(HeaderViewMode mode)                  = 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;


@@ 73,12 78,14 @@ 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 setBatteryLevelState(const Store::Battery &batteryContext) = 0;

        /// Various
        virtual void switchToMenu()                  = 0;
        virtual void switchToBatteryStatus()         = 0;
        virtual void setSnoozeTime(std::time_t time) = 0;
        virtual void setLayout(std::unique_ptr<gui::BaseHomeScreenLayoutProvider> layout) = 0;
        virtual void switchToMenu()                                                       = 0;
        virtual void switchToBatteryStatus()                                              = 0;
        virtual void setSnoozeTime(std::time_t time)                                      = 0;
    };

    class AbstractPresenter : public BasePresenter<AbstractView>


@@ 103,6 110,7 @@ namespace app::home_screen
        virtual std::uint32_t getBatteryLvl() const                                              = 0;
        virtual bool isBatteryCharging() const                                                   = 0;
        virtual bool isAlarmActivatedByLatch() const                                             = 0;
        virtual void setLayout(std::unique_ptr<gui::BaseHomeScreenLayoutProvider> layout)        = 0;

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


@@ 143,6 151,8 @@ namespace app::home_screen
        bool isBatteryCharging() const override;
        bool isAlarmActivatedByLatch() const override;

        void setLayout(std::unique_ptr<gui::BaseHomeScreenLayoutProvider> layout) override;

      private:
        ApplicationCommon *app;
        sys::TimerHandle timer;

A products/BellHybrid/apps/application-bell-main/layouts/BaseHomeScreenLayoutProvider.hpp => products/BellHybrid/apps/application-bell-main/layouts/BaseHomeScreenLayoutProvider.hpp +47 -0
@@ 0,0 1,47 @@
// 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 "application-bell-main/presenters/HomeScreenPresenter.hpp"

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

namespace gui
{
    class SnoozeTimer;

    class BaseHomeScreenLayoutProvider
    {
      private:
        std::string name;

      public:
        BaseHomeScreenLayoutProvider(std::string name) : name{std::move(name)} {};
        virtual ~BaseHomeScreenLayoutProvider() noexcept = default;

        std::string getName()
        {
            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 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;
    };
}; // namespace gui

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

#include "layouts/HomeScreenLayoutClassic.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/text/TextFixedSize.hpp>
#include <gui/widgets/Style.hpp>
#include <time/time_constants.hpp>
#include <widgets/AlarmSetSpinner.hpp>
#include <widgets/TimeSetFmtSpinner.hpp>

namespace gui
{
    HomeScreenLayoutClassic::HomeScreenLayoutClassic(std::string name)
        : BaseHomeScreenLayoutProvider(std::move(name)),
          BellBaseLayout(nullptr, 0, 0, style::window_width, style::window_height, false)
    {
        buildInterface();
    }

    void HomeScreenLayoutClassic::buildInterface()
    {
        using namespace bellMainStyle;

        alarm = new AlarmSetSpinner(this->firstBox);
        alarm->setMinimumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
        alarm->setFont(mainWindow::alarmSetSpinner::font);
        alarm->setEditMode(EditMode::Browse);
        alarm->setAlarmStatus(AlarmSetSpinner::Status::DEACTIVATED);
        alarm->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        snoozeTimer = new SnoozeTimer(this->firstBox);
        snoozeTimer->setMinimumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
        snoozeTimer->setVisible(false);
        snoozeTimer->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        time = new TimeSetFmtSpinner(this->centerBox);
        time->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::h);
        time->setFont(bellMainStyle::mainWindow::time::font);
        time->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        time->setEditMode(EditMode::Browse);
        time->setFont(mainWindow::time::font);
        time->activeItem = false;

        statusBox = new DuoHBox(this->lastBox, 0, 0, 0, 0);
        statusBox->setMinimumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
        statusBox->setEdges(RectangleEdge::None);
        statusBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        statusBox->setVisible(true);

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

        statusBox->setItems(battery, nullptr);

        bottomText = new TextFixedSize(this->lastBox, 0, 0, 0, 0);
        bottomText->setMaximumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
        bottomText->setFont(mainWindow::bottomDescription::font_small);
        bottomText->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
        bottomText->setEdges(RectangleEdge::None);
        bottomText->activeItem = false;
        bottomText->drawUnderline(false);
        bottomText->setVisible(false);

        resizeItems();
    }

    SnoozeTimer *HomeScreenLayoutClassic::getSnoozeTimer()
    {
        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);
            setHeaderViewMode(HeaderViewMode::Empty);
            break;
        case app::home_screen::ViewState::DeactivatedWait:
            setAlarmActive(false);
            setHeaderViewMode(HeaderViewMode::AlarmIcon);
            break;
        case app::home_screen::ViewState::WaitForConfirmation:
            setBottomDescription(utils::translate("app_bellmain_home_screen_bottom_desc_dp"));
            break;
        case app::home_screen::ViewState::AlarmEdit:
            setAlarmEdit(true);
            setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
            break;
        case app::home_screen::ViewState::ActivatedWait:
            setAlarmActive(true);
            setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
            break;
        case app::home_screen::ViewState::Activated:
            setAlarmActive(true);
            setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
            break;
        case app::home_screen::ViewState::AlarmRinging:
            setAlarmTriggered();
            setHeaderViewMode(HeaderViewMode::AlarmIcon);
            break;
        case app::home_screen::ViewState::AlarmRingingDeactivatedWait:
            setAlarmActive(false);
            setHeaderViewMode(HeaderViewMode::AlarmIcon);
            break;
        case app::home_screen::ViewState::AlarmSnoozedWait:
            setHeaderViewMode(HeaderViewMode::SnoozeIcon);
            break;
        case app::home_screen::ViewState::AlarmSnoozed:
            setHeaderViewMode(HeaderViewMode::SnoozeIconAndTime);
            break;
        }
    }

    void HomeScreenLayoutClassic::setHeaderViewMode(HeaderViewMode mode)
    {
        switch (mode) {
        case HeaderViewMode::Empty:
            alarm->setVisible(false);
            alarm->setAlarmTimeVisible(false);
            snoozeTimer->setVisible(false);
            alarm->informContentChanged();
            break;
        case HeaderViewMode::AlarmIconAndTime:
            alarm->setVisible(true);
            alarm->setAlarmTimeVisible(true);
            snoozeTimer->setVisible(false);
            alarm->informContentChanged();
            break;
        case HeaderViewMode::AlarmIcon:
            alarm->setVisible(true);
            alarm->setAlarmTimeVisible(false);
            snoozeTimer->setVisible(false);
            alarm->informContentChanged();
            break;
        case HeaderViewMode::SnoozeIconAndTime:
            alarm->setVisible(false);
            alarm->setAlarmTimeVisible(false);
            snoozeTimer->setVisible(true);
            snoozeTimer->setTimerVisible(true);
            snoozeTimer->informContentChanged();
            break;
        case HeaderViewMode::SnoozeIcon:
            alarm->setVisible(false);
            alarm->setAlarmTimeVisible(false);
            snoozeTimer->setVisible(true);
            snoozeTimer->informContentChanged();
            snoozeTimer->setTimerVisible(false);
            break;
        }
    }

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

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

    void HomeScreenLayoutClassic::removeBottomDescription()
    {
        bottomText->setText("");
        statusBox->setVisible(true);
        bottomText->setVisible(false);
        statusBox->resizeItems();
        statusBox->informContentChanged();
    }

    bool HomeScreenLayoutClassic::isBatteryVisibilityAllowed(const Store::Battery &batteryContext)
    {
        // TODO fix magic values
        return (batteryContext.level < battery::dischargingLevelShowTop) ||
               (batteryContext.state == Store::Battery::State::Charging &&
                batteryContext.level != battery::chargingLevelHideBot);
    }

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

    void HomeScreenLayoutClassic::setTime(std::time_t newTime)
    {
        time->setTime(newTime);
        time->setTimeFormatSpinnerVisibility(false);
    }

    void HomeScreenLayoutClassic::setTimeFormat(utils::time::Locale::TimeFormat fmt)
    {
        time->setTimeFormat(fmt);
    }

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

    void HomeScreenLayoutClassic::setSnoozeFormat(utils::time::Locale::TimeFormat fmt)
    {
        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());
        auto alarmTime = alarm->getTime();
        if (alarmTime < now) {
            alarmTime += utils::time::secondsInDay;
        }
        return alarmTime;
    }

    void HomeScreenLayoutClassic::setAlarmTime(std::time_t newTime)
    {
        alarm->setTime(newTime);
    }

    void HomeScreenLayoutClassic::setSnoozeTime(std::time_t newTime)
    {
        snoozeTimer->setTime(newTime);
    }

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

A products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassic.hpp => products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassic.hpp +82 -0
@@ 0,0 1,82 @@
// 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"

namespace style::homescreen_classic
{
    constexpr inline auto bottom_box_w = 390U;
    constexpr inline auto bottom_box_h = 102U;
} // namespace style::homescreen_classic
namespace gui
{

    class BellBaseLayout;
    class TextFixedSize;
    class AlarmSetSpinner;
    class TimeSetFmtSpinner;
    class SnoozeTimer;
    class BellBattery;
    class DuoHBox;

    enum class LayoutClassicVersion
    {
        Temperature,
        AmPm,
        Battery
    };

    enum class HeaderViewMode
    {
        Empty,
        AlarmIcon,
        AlarmIconAndTime,
        SnoozeIcon,
        SnoozeIconAndTime,
    };

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

    class HomeScreenLayoutClassic : public BaseHomeScreenLayoutProvider, BellBaseLayout
    {
      public:
        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 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;

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

      protected:
        auto setHeaderViewMode(HeaderViewMode mode) -> void;
        virtual auto buildInterface() -> void;
        virtual bool isBatteryVisibilityAllowed(const Store::Battery &batteryContext);

        TimeSetFmtSpinner *time{};
        DuoHBox *statusBox{};
        BellBattery *battery{};
        TextFixedSize *bottomText{};
        AlarmSetSpinner *alarm{};
        SnoozeTimer *snoozeTimer{};
    };
}; // namespace gui

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

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

#include <date/date.h>
#include <gui/widgets/text/TextFixedSize.hpp>

namespace gui
{
    HomeScreenLayoutClassicWithAmPm::HomeScreenLayoutClassicWithAmPm(std::string name)
        : HomeScreenLayoutClassic(std::move(name))
    {
        buildInterface();
    }

    auto HomeScreenLayoutClassicWithAmPm::buildInterface() -> void
    {
        using namespace bellMainStyle;

        fmt = new TextFixedSize(nullptr, 0, 0, 0, 0);
        fmt->setMaximumSize(style::homescreen_classic::bottom_box_w, style::homescreen_classic::bottom_box_h);
        fmt->setFont(mainWindow::bottomDescription::font_small);
        fmt->setEdges(RectangleEdge::None);
        fmt->activeItem = false;
        fmt->drawUnderline(false);
        fmt->setText("");

        statusBox->setItems(battery, fmt);
    }

    auto HomeScreenLayoutClassicWithAmPm::setTime(std::time_t newTime) -> void
    {
        HomeScreenLayoutClassic::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

A products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithAmPm.hpp => products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithAmPm.hpp +22 -0
@@ 0,0 1,22 @@
// 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/HomeScreenLayoutClassic.hpp"

namespace gui
{
    class HomeScreenLayoutClassicWithAmPm : public HomeScreenLayoutClassic
    {
      public:
        HomeScreenLayoutClassicWithAmPm(std::string name);

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

      protected:
        auto buildInterface() -> void override;

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

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

#include "layouts/HomeScreenLayoutClassicWithBattery.hpp"
#include "widgets/BellBattery.hpp"

namespace gui
{
    HomeScreenLayoutClassicWithBattery::HomeScreenLayoutClassicWithBattery(std::string name)
        : HomeScreenLayoutClassic(std::move(name))
    {}

    bool HomeScreenLayoutClassicWithBattery::isBatteryVisibilityAllowed(const Store::Battery &batteryContext)
    {
        return true;
    }
}; // namespace gui

A products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithBattery.hpp => products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithBattery.hpp +18 -0
@@ 0,0 1,18 @@
// 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/HomeScreenLayoutClassic.hpp"

namespace gui
{
    class HomeScreenLayoutClassicWithBattery : public HomeScreenLayoutClassic
    {
      public:
        HomeScreenLayoutClassicWithBattery(std::string name);

      protected:
        bool isBatteryVisibilityAllowed(const Store::Battery &batteryContext) override;
    };
}; // namespace gui

A products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithTemp.cpp => products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithTemp.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/HomeScreenLayoutClassicWithTemp.hpp"
#include "data/BellMainStyle.hpp"
#include "widgets/BellBattery.hpp"
#include "widgets/DuoHBox.hpp"

#include <gui/widgets/text/TextFixedSize.hpp>

namespace gui
{
    HomeScreenLayoutClassicWithTemp::HomeScreenLayoutClassicWithTemp(std::string name)
        : HomeScreenLayoutClassic(std::move(name))
    {
        buildInterface();
    }

    auto HomeScreenLayoutClassicWithTemp::buildInterface() -> void
    {
        using namespace bellMainStyle;

        tempText = new TextFixedSize(nullptr, 0, 0, 0, 0);
        tempText->setMaximumSize(style::homescreen_classic::temperature_w, style::homescreen_classic::temperature_h);
        tempText->setFont(mainWindow::bottomDescription::font_normal);
        tempText->setEdges(RectangleEdge::None);
        tempText->activeItem = false;
        tempText->drawUnderline(false);

        statusBox->setItems(battery, tempText);
    }

    auto HomeScreenLayoutClassicWithTemp::setTemperature(utils::temperature::Temperature newTemp) -> void
    {
        tempText->setText(utils::temperature::tempToStrDec(newTemp));
        statusBox->resizeItems();
    }
}; // namespace gui

A products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithTemp.hpp => products/BellHybrid/apps/application-bell-main/layouts/HomeScreenLayoutClassicWithTemp.hpp +29 -0
@@ 0,0 1,29 @@
// 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/HomeScreenLayoutClassic.hpp"

namespace style::homescreen_classic
{
    constexpr inline auto temperature_w = 170U;
    constexpr inline auto temperature_h = 102U;
} // namespace style::homescreen_classic

namespace gui
{

    class HomeScreenLayoutClassicWithTemp : public HomeScreenLayoutClassic
    {
      public:
        HomeScreenLayoutClassicWithTemp(std::string name);

        auto setTemperature(utils::temperature::Temperature newTemp) -> void override;

      protected:
        auto buildInterface() -> void override;

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

M products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.cpp => products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.cpp +8 -1
@@ 1,10 1,12 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "HomeScreenPresenter.hpp"
#include "application-bell-main/presenters/HomeScreenPresenter.hpp"
#include "StateController.hpp"
#include "layouts/BaseHomeScreenLayoutProvider.hpp"
#include "models/BatteryModel.hpp"
#include "models/TemperatureModel.hpp"
#include "widgets/ProgressTimerWithSnoozeTimer.hpp"

#include <apps-common/ApplicationCommon.hpp>
#include <common/models/TimeModel.hpp>


@@ 161,4 163,9 @@ namespace app::home_screen
    {
        stateController->handleBatteryStatus();
    }

    void HomeScreenPresenter::setLayout(std::unique_ptr<gui::BaseHomeScreenLayoutProvider> layout)
    {
        getView()->setLayout(std::move(layout));
    }
} // namespace app::home_screen

M products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp => products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp +29 -15
@@ 1,8 1,9 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "application-bell-main/presenters/HomeScreenPresenter.hpp"
#include "models/TemperatureModel.hpp"
#include "StateController.hpp"
#include "HomeScreenPresenter.hpp"

#include <common/TimeUtils.hpp>
#include <common/models/TimeModel.hpp>


@@ 142,7 143,6 @@ namespace app::home_screen
                alarmModel.update([&]() { presenter.handleAlarmModelReady(); });
                view.setAlarmEdit(false);
                view.setAlarmActive(false);
                view.setHeaderViewMode(HeaderViewMode::Empty);
                view.setTemperature(temperatureModel.getTemperature());
                view.setBatteryLevelState(batteryModel.getLevelState());
            };


@@ 157,7 157,7 @@ namespace app::home_screen
                controller.snooze(false);
                view.setAlarmEdit(false);
                view.setAlarmActive(false);
                view.setHeaderViewMode(HeaderViewMode::Empty);
                view.setViewState(ViewState::Deactivated);
                view.setTemperature(temperatureModel.getTemperature());
                view.setBatteryLevelState(batteryModel.getLevelState());
            };


@@ 170,9 170,12 @@ namespace app::home_screen
                presenter.spawnTimer();
                view.setBottomDescription(utils::translate("app_bell_alarm_deactivated"));
                view.setAlarmActive(false);
                view.setHeaderViewMode(HeaderViewMode::AlarmIcon);
                view.setViewState(ViewState::DeactivatedWait);
            };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) {
                presenter.detachTimer();
                view.removeBottomDescription();
            };
            auto exit = [](AbstractPresenter &presenter) { presenter.detachTimer(); };
        } // namespace DeactivatedWait

        namespace AlarmEdit


@@ 180,7 183,7 @@ namespace app::home_screen
            auto entry =
                [](AbstractView &view, AbstractPresenter &presenter, AbstractTemperatureModel &temperatureModel) {
                    view.setAlarmEdit(true);
                    view.setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
                    view.setViewState(ViewState::AlarmEdit);
                    view.setTemperature(temperatureModel.getTemperature());
                };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) {


@@ 204,12 207,14 @@ namespace app::home_screen
            auto entry = [](AbstractView &view, AbstractPresenter &presenter) {
                presenter.spawnTimer();
                view.setBottomDescription(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();
            };
        } // namespace WaitForConfirmation



@@ 224,9 229,12 @@ namespace app::home_screen
                view.setBottomDescription(utils::time::getBottomDescription(
                    utils::time::calculateMinutesDifference(view.getAlarmTime(), timeModel.getCurrentTime())));
                view.setAlarmActive(true);
                view.setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
                view.setViewState(ViewState::ActivatedWait);
            };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) {
                presenter.detachTimer();
                view.removeBottomDescription();
            };
            auto exit = [](AbstractPresenter &presenter) { presenter.detachTimer(); };
        } // namespace ActivatedWait

        namespace Activated


@@ 239,7 247,7 @@ namespace app::home_screen
                controller.snooze(false);
                view.setTemperature(temperatureModel.getTemperature());
                view.setAlarmActive(true);
                view.setHeaderViewMode(HeaderViewMode::AlarmIconAndTime);
                view.setViewState(ViewState::Activated);
                view.setAlarmTime(alarmModel.getAlarmTime());
                view.setBatteryLevelState(batteryModel.getLevelState());
            };


@@ 250,7 258,7 @@ namespace app::home_screen
            auto entry =
                [](AbstractView &view, AbstractTemperatureModel &temperatureModel, AbstractPresenter &presenter) {
                    presenter.spawnTimer(defaultAlarmRingingTime);
                    view.setHeaderViewMode(HeaderViewMode::AlarmIcon);
                    view.setViewState(ViewState::AlarmRinging);
                    view.setAlarmTriggered();
                    view.setTemperature(temperatureModel.getTemperature());
                };


@@ 263,11 271,14 @@ namespace app::home_screen
                presenter.spawnTimer();
                alarmModel.turnOff();
                alarmModel.activate(false);
                view.setHeaderViewMode(HeaderViewMode::AlarmIcon);
                view.setViewState(ViewState::AlarmRingingDeactivatedWait);
                view.setBottomDescription(Helpers::getGreeting());
                view.setAlarmActive(false);
            };
            auto exit = [](AbstractPresenter &presenter) { presenter.detachTimer(); };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) {
                presenter.detachTimer();
                view.removeBottomDescription();
            };
        } // namespace AlarmRingingDeactivatedWait

        namespace AlarmSnoozedWait


@@ 275,12 286,15 @@ namespace app::home_screen
            auto entry = [](AbstractView &view, AbstractAlarmModel &alarmModel, AbstractPresenter &presenter) {
                presenter.spawnTimer();
                alarmModel.snooze();
                view.setHeaderViewMode(HeaderViewMode::SnoozeIcon);
                view.setViewState(ViewState::AlarmSnoozedWait);
                const auto bottomDescription =
                    utils::time::getBottomDescription(alarmModel.getSnoozeDuration().count());
                view.setBottomDescription(bottomDescription);
            };
            auto exit = [](AbstractPresenter &presenter) { presenter.detachTimer(); };
            auto exit = [](AbstractView &view, AbstractPresenter &presenter) {
                presenter.detachTimer();
                view.removeBottomDescription();
            };
        } // namespace AlarmSnoozedWait

        namespace AlarmSnoozed


@@ 289,7 303,7 @@ namespace app::home_screen
                            AbstractAlarmModel &alarmModel,
                            AbstractTemperatureModel &temperatureModel,
                            AbstractBatteryModel &batteryModel) {
                view.setHeaderViewMode(HeaderViewMode::SnoozeIconAndTime);
                view.setViewState(ViewState::AlarmSnoozed);
                view.setSnoozeTime(Clock::to_time_t(alarmModel.getTimeOfNextSnooze()));
                view.setTemperature(temperatureModel.getTemperature());
                view.setBatteryLevelState(batteryModel.getLevelState());

M products/BellHybrid/apps/application-bell-main/widgets/BellBattery.cpp => products/BellHybrid/apps/application-bell-main/widgets/BellBattery.cpp +34 -16
@@ 13,7 13,11 @@ namespace
                                                                              {{40, 69}, "bell_battery_lvl3"},
                                                                              {{70, 95}, "bell_battery_lvl4"},
                                                                              {{96, 100}, "bell_battery_lvl5"}}};
}

    constexpr auto betteryFullLevel = 100;
    constexpr auto lowBatteryLimit  = 20;
    constexpr auto singleDigitLimit = 10;
} // namespace

namespace gui
{


@@ 40,14 44,15 @@ namespace gui
        }

        const auto level = batteryContext.level;

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

            if (level == 100) {
            if (level == betteryFullLevel) {
                img->setMargins(gui::Margins(0, 0, battery::image_right_margin, 0));
                img->informContentChanged();
            }
            else if (level < 10) {
            else if (level < singleDigitLimit) {
                img->setMargins(gui::Margins(battery::image_left_margin_big, 0, battery::image_right_margin, 0));
                img->informContentChanged();
            }


@@ 55,27 60,40 @@ namespace gui
                img->setMargins(gui::Margins(battery::image_left_margin, 0, battery::image_right_margin, 0));
                img->informContentChanged();
            }

            percentText->setText(std::to_string(level) + "%");
            setVisible(true);
        }
        else {
            if (level >= 20) {
                setVisible(false);
            }
            else {
                if (level < 10) {
            if (level <= lowBatteryLimit) {
                if (level < singleDigitLimit) {
                    img->setMargins(gui::Margins(battery::image_left_margin_big, 0, battery::image_right_margin, 0));
                    img->informContentChanged();
                }
                else {
                    img->setMargins(gui::Margins(battery::image_left_margin, 0, battery::image_right_margin, 0));
                    img->informContentChanged();
                }
                img->set(image->data(), gui::ImageTypeSpecifier::W_M);
                percentText->setText(std::to_string(level) + "%");
                setVisible(true);
            }
            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) + "%");
            percentText->setVisible(true);
        }
        else {
            percentText->setVisible(false);
        }
        percentText->informContentChanged();
    }

    void BellBattery::setBatteryPercentMode(BatteryPercentMode mode)
    {
        batteryPercentMode = mode;
    }

    std::uint32_t BellBattery::getLevel()
    {
        auto percentTextStr  = std::string(percentText->getText().c_str());
        auto batteryLevelStr = percentTextStr.substr(0, percentTextStr.size() - 1);
        return std::stoi(batteryLevelStr);
    }
} // namespace gui

M products/BellHybrid/apps/application-bell-main/widgets/BellBattery.hpp => products/BellHybrid/apps/application-bell-main/widgets/BellBattery.hpp +9 -0
@@ 29,13 29,22 @@ namespace gui

    } // namespace battery

    enum class BatteryPercentMode
    {
        Dynamic,
        Static,
    };

    class BellBattery : public gui::HBox
    {
      public:
        BellBattery(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
        void update(const Store::Battery &batteryContext);
        void setBatteryPercentMode(BatteryPercentMode mode);
        std::uint32_t getLevel();

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

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

#include "DuoHBox.hpp"

namespace gui
{
    void DuoHBox::setItems(Item *leftItem, Item *rightItem)
    {
        removeWidget(this->leftItem);
        removeWidget(this->rightItem);
        this->leftItem  = leftItem;
        this->rightItem = rightItem;
        addWidget(this->leftItem);
        addWidget(this->rightItem);
    }

    void DuoHBox::resizeItems()
    {
        setAlignements();
        HBox::resizeItems();
    }
    auto DuoHBox::handleRequestResize(const Item *child, Length request_w, Length request_h) -> Size
    {
        setAlignements();
        return HBox::handleRequestResize(child, request_w, request_h);
    }

    void DuoHBox::setAlignements()
    {
        auto left  = (leftItem && leftItem->visible);
        auto right = (rightItem && rightItem->visible);

        if (left ^ right) {
            auto soloItem = left ? leftItem : rightItem;
            soloItem->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        }
        else if (left && right) {
            leftItem->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
            rightItem->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Center));
        }
    }
} // namespace gui

A products/BellHybrid/apps/application-bell-main/widgets/DuoHBox.hpp => products/BellHybrid/apps/application-bell-main/widgets/DuoHBox.hpp +25 -0
@@ 0,0 1,25 @@
// 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 "BoxLayout.hpp"

namespace gui
{

    class DuoHBox : public HBox
    {
      public:
        DuoHBox(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h) : HBox(parent, x, y, w, h){};
        void setItems(Item *leftItem, Item *rightItem);
        void resizeItems() override;
        auto handleRequestResize(const Item *, Length request_w, Length request_h) -> Size override;

      private:
        void setAlignements();

        Item *leftItem{};
        Item *rightItem{};
    };
} // namespace gui

M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp => products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp +118 -174
@@ 4,12 4,13 @@
#include "BellHomeScreenWindow.hpp"
#include "data/BellMainStyle.hpp"
#include "widgets/SnoozeTimer.hpp"
#include "widgets/ProgressTimerWithSnoozeTimer.hpp"
#include "BellBatteryStatusWindow.hpp"
#include "ProductConfig.hpp"

#include <application-bell-main/ApplicationBellMain.hpp>
#include <apps-common/widgets/BellBaseLayout.hpp>
#include <apps-common/actions/AlarmRingingData.hpp>
#include <apps-common/widgets/BellBaseLayout.hpp>
#include <gui/input/InputEvent.hpp>
#include <gui/widgets/text/TextFixedSize.hpp>
#include <gui/widgets/Style.hpp>


@@ 21,7 22,6 @@
#include <widgets/TimeSetFmtSpinner.hpp>

#include <chrono>

namespace
{
    using utils::time::Locale;


@@ 75,14 75,21 @@ namespace
namespace gui
{
    BellHomeScreenWindow::BellHomeScreenWindow(app::ApplicationCommon *app,
                                               std::unique_ptr<app::home_screen::AbstractPresenter> presenter)
        : AppWindow(app, name::window::main_window), presenter{std::move(presenter)}
                                               std::shared_ptr<app::home_screen::AbstractPresenter> presenter)
        : AppWindow(app, name::window::main_window), presenter{presenter}
    {
        buildInterface();
        this->presenter->attach(this);
        this->presenter->createData();
    }

    BellHomeScreenWindow::~BellHomeScreenWindow()
    {
        if (currentLayout) {
            removeWidget(currentLayout->getLayout());
        }
    }

    void BellHomeScreenWindow::buildInterface()
    {
        using namespace bellMainStyle;


@@ 91,180 98,151 @@ namespace gui
        statusBar->setVisible(false);
        header->setTitleVisibility(false);
        navBar->setVisible(false);
    }

        body = new BellBaseLayout(this, 0, 0, style::window_width, style::window_height, false);

        alarm = new AlarmSetSpinner(body->firstBox);
        alarm->setMinimumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
        alarm->setFont(mainWindow::alarmSetSpinner::font);
        alarm->setEditMode(EditMode::Browse);
        alarm->setAlarmStatus(AlarmSetSpinner::Status::DEACTIVATED);
        alarm->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        snoozeTimer = new SnoozeTimer(body->firstBox);
        snoozeTimer->setMinimumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
        snoozeTimer->setVisible(false);
        snoozeTimer->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        time = new TimeSetFmtSpinner(body->centerBox);
        time->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::h);
        time->setFont(bellMainStyle::mainWindow::time::font);
        time->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        time->setEditMode(EditMode::Browse);
        time->setFont(mainWindow::time::font);
        time->activeItem = false;

        bottomBox = new HBox(body->lastBox, 0, 0, 0, 0);
        bottomBox->setMinimumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
        bottomBox->setEdges(RectangleEdge::None);
        bottomBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        battery = new BellBattery(bottomBox, 0, 0, 0, 0);
        battery->setMinimumSize(battery::battery_widget_w, battery::battery_widget_h);
        battery->setEdges(RectangleEdge::None);
        battery->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        battery->setVisible(false);

        bottomText = new TextFixedSize(bottomBox, 0, 0, 0, 0);
        bottomText->setMaximumSize(style::bell_home_screen::bottom_desc_w, style::bell_home_screen::bottom_desc_h);
        bottomText->setFont(mainWindow::bottomDescription::font_small);
        bottomText->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Top));
        bottomText->setEdges(RectangleEdge::None);
        bottomText->activeItem = false;
        bottomText->drawUnderline(false);

        body->resize();

        auto timer = std::make_unique<app::ProgressTimerWithSnoozeTimer>(
            application, *this, snoozeTimerName, timerTick, app::ProgressCountdownMode::Increasing);
        timer->attach(snoozeTimer);
        presenter->setSnoozeTimer(std::move(timer));
    void BellHomeScreenWindow::setLayout(std::unique_ptr<BaseHomeScreenLayoutProvider> layout)
    {
        if (currentLayout) {
            removeWidget(currentLayout->getLayout());
        }
        currentLayout = std::move(layout);
        addWidget(static_cast<BellBaseLayout *>(currentLayout->getLayout()));
        presenter->onBeforeShow();

        if (auto snoozeTimer = currentLayout->getSnoozeTimer()) {
            auto timer = std::make_unique<app::ProgressTimerWithSnoozeTimer>(
                application, *this, snoozeTimerName, timerTick, app::ProgressCountdownMode::Increasing);
            timer->attach(snoozeTimer);
            presenter->setSnoozeTimer(std::move(timer));
        }
    }

    void BellHomeScreenWindow::setAlarmTriggered()
    {
        alarm->setAlarmStatus(AlarmSetSpinner::Status::RINGING);
        if (currentLayout) {
            currentLayout->setAlarmTriggered();
        }
    }

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

    void BellHomeScreenWindow::setHeaderViewMode(app::home_screen::HeaderViewMode mode)
    {
        switch (mode) {
        case app::home_screen::HeaderViewMode::Empty:
            alarm->setVisible(false);
            alarm->setAlarmTimeVisible(false);
            snoozeTimer->setVisible(false);
            alarm->informContentChanged();
            break;
        case app::home_screen::HeaderViewMode::AlarmIconAndTime:
            alarm->setVisible(true);
            alarm->setAlarmTimeVisible(true);
            snoozeTimer->setVisible(false);
            alarm->informContentChanged();
            break;
        case app::home_screen::HeaderViewMode::AlarmIcon:
            alarm->setVisible(true);
            alarm->setAlarmTimeVisible(false);
            snoozeTimer->setVisible(false);
            alarm->informContentChanged();
            break;
        case app::home_screen::HeaderViewMode::SnoozeIconAndTime:
            alarm->setVisible(false);
            alarm->setAlarmTimeVisible(false);
            snoozeTimer->setVisible(true);
            snoozeTimer->setTimerVisible(true);
            snoozeTimer->informContentChanged();
            break;
        case app::home_screen::HeaderViewMode::SnoozeIcon:
            alarm->setVisible(false);
            alarm->setAlarmTimeVisible(false);
            snoozeTimer->setVisible(true);
            snoozeTimer->informContentChanged();
            snoozeTimer->setTimerVisible(false);
            break;
    }

    void BellHomeScreenWindow::setViewState(app::home_screen::ViewState state)
    {
        if (currentLayout) {
            currentLayout->setViewState(state);
        }
    }

    void BellHomeScreenWindow::setTemperature(utils::temperature::Temperature newTemp)
    {
#if CONFIG_ENABLE_TEMP == 1
        bottomText->setVisible(true);
        bottomText->setFont(bellMainStyle::mainWindow::bottomDescription::font_normal);
        bottomText->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        bottomText->setText(utils::temperature::tempToStrDec(newTemp));
        bottomBox->resizeItems();
#else
        bottomText->setVisible(false);
        bottomBox->resizeItems();
#endif
        if (currentLayout) {
            currentLayout->setTemperature(newTemp);
        }
    }

    void BellHomeScreenWindow::setBottomDescription(const UTF8 &desc)
    {
        battery->setVisible(false);
        battery->informContentChanged();
        bottomText->setVisible(true);
        bottomText->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        bottomText->setFont(bellMainStyle::mainWindow::bottomDescription::font_small);
        bottomText->setRichText(desc);
        bottomBox->resizeItems();
        if (currentLayout) {
            currentLayout->setBottomDescription(desc);
        }
    }

    void BellHomeScreenWindow::setBatteryLevelState(const Store::Battery &batteryContext)
    void BellHomeScreenWindow::removeBottomDescription()
    {
        battery->update(batteryContext);
        if (!battery->visible) {
            bottomText->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        if (currentLayout) {
            currentLayout->removeBottomDescription();
        }
        else {
#if CONFIG_ENABLE_TEMP == 1
            bottomText->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Center));
            battery->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
#else
            battery->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
#endif
    }

    void BellHomeScreenWindow::setBatteryLevelState(const Store::Battery &batteryContext)
    {
        if (currentLayout) {
            currentLayout->setBatteryLevelState(batteryContext);
        }
        bottomBox->resizeItems();
    }

    void BellHomeScreenWindow::setTime(std::time_t newTime)
    {
        time->setTime(newTime);
        time->setTimeFormatSpinnerVisibility(false);
        if (currentLayout) {
            currentLayout->setTime(newTime);
        }
    }

    void BellHomeScreenWindow::setTimeFormat(utils::time::Locale::TimeFormat fmt)
    {
        time->setTimeFormat(fmt);
        if (currentLayout) {
            currentLayout->setTimeFormat(fmt);
        }
    }

    void BellHomeScreenWindow::setAlarmTimeFormat(utils::time::Locale::TimeFormat fmt)
    {
        alarm->setTimeFormat(fmt);
        if (currentLayout) {
            currentLayout->setAlarmTimeFormat(fmt);
        }
    }

    void BellHomeScreenWindow::setSnoozeFormat(utils::time::Locale::TimeFormat fmt)
    {
        snoozeTimer->setTimeFormat(fmt);
        if (currentLayout) {
            currentLayout->setSnoozeFormat(fmt);
        }
    }

    void BellHomeScreenWindow::setAlarmEdit(bool val)
    {
        if (not val) {
            alarm->setEditMode(EditMode::Browse);
        if (currentLayout) {
            currentLayout->setAlarmEdit(val);
        }
    }

    std::time_t BellHomeScreenWindow::getAlarmTime() const
    {
        if (currentLayout) {
            return currentLayout->getAlarmTime();
        }
        else {
            alarm->setEditMode(EditMode::Edit);
        };
            return {};
        }
    }

    void BellHomeScreenWindow::setAlarmTime(std::time_t newTime)
    {
        if (currentLayout) {
            currentLayout->setAlarmTime(newTime);
        }
    }

    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) {
            currentLayout->setSnoozeTime(newTime);
        }
    }

    void BellHomeScreenWindow::switchToMenu()


@@ 290,22 268,6 @@ namespace gui
            presenter->onBeforeShow();
        }
    }

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

    void BellHomeScreenWindow::setAlarmTime(std::time_t newTime)
    {
        alarm->setTime(newTime);
    }

    bool BellHomeScreenWindow::updateTime()
    {
        if (presenter) {


@@ 313,22 275,19 @@ namespace gui
        }
        return true;
    }

    void BellHomeScreenWindow::incAlarmMinute()
    void BellHomeScreenWindow::switchToBatteryStatus()
    {
        const auto alarmTime = alarm->getTime();
        auto newTime         = std::localtime(&alarmTime);
        handleMinuteIncrease(*newTime);
        alarm->setTime(std::mktime(newTime));
        application->switchWindow(gui::BellBatteryStatusWindow::name,
                                  std::make_unique<gui::BellBatteryStatusWindow::Data>(presenter->getBatteryLvl(),
                                                                                       presenter->isBatteryCharging()));
    }

    void BellHomeScreenWindow::decAlarmMinute()
    bool BellHomeScreenWindow::updateBatteryStatus()
    {
        const auto alarmTime = alarm->getTime();
        auto newTime         = std::localtime(&alarmTime);
        handleMinuteDecrease(*newTime);
        alarm->setTime(std::mktime(newTime));
        presenter->handleBatteryStatus();
        return true;
    }

    bool BellHomeScreenWindow::onDatabaseMessage(sys::Message *msg)
    {
        auto *msgNotification = dynamic_cast<db::NotificationMessage *>(msg);


@@ 338,20 297,5 @@ namespace gui
        }
        return false;
    }
    void BellHomeScreenWindow::switchToBatteryStatus()
    {
        application->switchWindow(gui::BellBatteryStatusWindow::name,
                                  std::make_unique<gui::BellBatteryStatusWindow::Data>(presenter->getBatteryLvl(),
                                                                                       presenter->isBatteryCharging()));
    }
    void BellHomeScreenWindow::setSnoozeTime(std::time_t newTime)
    {
        snoozeTimer->setTime(newTime);
    }
    bool BellHomeScreenWindow::updateBatteryStatus()
    {
        presenter->handleBatteryStatus();
        return true;
    }

} // namespace gui

M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.hpp => products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.hpp +10 -33
@@ 3,44 3,27 @@

#pragma once

#include "application-bell-main/presenters/HomeScreenPresenter.hpp"
#include "layouts/BaseHomeScreenLayoutProvider.hpp"
#include "models/TemperatureModel.hpp"
#include "presenters/HomeScreenPresenter.hpp"
#include "widgets/BellBattery.hpp"

#include <apps-common/GuiTimer.hpp>
#include <apps-common/windows/AppWindow.hpp>

namespace style::bell_home_screen
{
    constexpr inline auto temperature_w = 85U;
    constexpr inline auto temperature_h = 102U;
    constexpr inline auto bottom_desc_w = 390U;
    constexpr inline auto bottom_desc_h = 102U;

    enum class ParentType
    {
        SideListView,
        Window
    };

} // namespace style::bell_home_screen

namespace gui
{
    class BellBaseLayout;
    class TextFixedSize;
    class AlarmSetSpinner;
    class TimeSetFmtSpinner;
    class SnoozeTimer;

    class BellHomeScreenWindow : public AppWindow, public app::home_screen::AbstractView
    {
      public:
        BellHomeScreenWindow(app::ApplicationCommon *app,
                             std::unique_ptr<app::home_screen::AbstractPresenter> presenter);
                             std::shared_ptr<app::home_screen::AbstractPresenter> presenter);

        ~BellHomeScreenWindow();

      private:
        void buildInterface() override;
        void setLayout(std::unique_ptr<BaseHomeScreenLayoutProvider> layout) override;
        bool updateTime() override;
        bool onInput(const InputEvent &inputEvent) override;
        void onBeforeShow(ShowMode mode, SwitchData *data) override;


@@ 49,7 32,7 @@ namespace gui
        void setAlarmTriggered() override;
        void setAlarmActive(bool val) override;
        void setAlarmEdit(bool val) override;
        void setHeaderViewMode(app::home_screen::HeaderViewMode mode) 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;


@@ 58,6 41,7 @@ namespace gui

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


@@ 68,16 52,9 @@ namespace gui

        bool updateBatteryStatus() override;

        BellBaseLayout *body{};

        TimeSetFmtSpinner *time{};
        HBox *bottomBox{};
        BellBattery *battery{};
        TextFixedSize *bottomText{};
        AlarmSetSpinner *alarm{};
        SnoozeTimer *snoozeTimer{};
        std::shared_ptr<app::home_screen::AbstractPresenter> presenter;

        std::unique_ptr<app::home_screen::AbstractPresenter> presenter;
        std::unique_ptr<BaseHomeScreenLayoutProvider> currentLayout;

        static constexpr auto timerName = "HS_timer";
    };

A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayouts.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayouts.hpp +24 -0
@@ 0,0 1,24 @@
// 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/HomeScreenLayoutClassicWithAmPm.hpp"
#include "layouts/HomeScreenLayoutClassicWithBattery.hpp"
#include "layouts/HomeScreenLayoutClassicWithTemp.hpp"

#include <map>
#include <string>
#include <typeindex>

namespace gui
{
    using LayoutGenerator = std::function<std::unique_ptr<gui::BaseHomeScreenLayoutProvider>()>;

    std::map<std::string, LayoutGenerator> homeScreenLayouts = {
        {"ClassicWithTemp", []() { return std::make_unique<gui::HomeScreenLayoutClassicWithTemp>("ClassicWithTemp"); }},
        {"ClassicWithAmPm", []() { return std::make_unique<gui::HomeScreenLayoutClassicWithAmPm>("ClassicWithAmPm"); }},
        {"ClassicWithBattery",
         []() { return std::make_unique<gui::HomeScreenLayoutClassicWithBattery>("ClassicWithBattery"); }},
    };
}; // namespace gui

M products/BellHybrid/services/appmgr/ApplicationManager.cpp => products/BellHybrid/services/appmgr/ApplicationManager.cpp +2 -0
@@ 5,6 5,7 @@
#include <appmgr/messages/AlarmMessage.hpp>
#include <appmgr/messages/BatteryShutdown.hpp>
#include <appmgr/messages/IdleTimerMessage.hpp>
#include <appmgr/messages/ChangeHomescreenLayoutMessage.hpp>
#include <application-bell-main/ApplicationBellMain.hpp>
#include <application-bell-onboarding/BellOnBoardingNames.hpp>
#include <service-appmgr/Constants.hpp>


@@ 65,5 66,6 @@ namespace app::manager
        connect(typeid(AlarmDeactivated), convertibleToActionHandler);
        connect(typeid(BatteryShutdown), convertibleToActionHandler);
        connect(typeid(BedtimeNotification), convertibleToActionHandler);
        connect(typeid(ChangeHomescreenLayoutMessage), convertibleToActionHandler);
    }
} // namespace app::manager

M products/BellHybrid/services/appmgr/CMakeLists.txt => products/BellHybrid/services/appmgr/CMakeLists.txt +2 -0
@@ 10,6 10,8 @@ target_sources(appmgr
        include/appmgr/ApplicationManager.hpp
        include/appmgr/IdleHandler.hpp
        include/appmgr/messages/BatteryShutdown.hpp
        include/appmgr/messages/ChangeHomescreenLayoutMessage.hpp
        include/appmgr/messages/ChangeHomescreenLayoutParams.hpp
        include/appmgr/messages/PowerOffPopupRequestParams.hpp
        include/appmgr/messages/RebootPopupRequestParams.hpp
)

A products/BellHybrid/services/appmgr/include/appmgr/messages/ChangeHomescreenLayoutMessage.hpp => products/BellHybrid/services/appmgr/include/appmgr/messages/ChangeHomescreenLayoutMessage.hpp +28 -0
@@ 0,0 1,28 @@
// 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 "ChangeHomescreenLayoutParams.hpp"

#include <Service/Message.hpp>
#include <service-appmgr/Actions.hpp>
#include <service-appmgr/messages/ActionRequest.hpp>

class ChangeHomescreenLayoutMessage : public sys::DataMessage, public app::manager::actions::ConvertibleToAction
{
  public:
    ChangeHomescreenLayoutMessage(std::string newHomescreenLayout)
        : sys::DataMessage{MessageType::MessageTypeUninitialized}, newHomescreenLayout{newHomescreenLayout} {};

    [[nodiscard]] auto toAction() const -> std::unique_ptr<app::manager::ActionRequest> override
    {
        return std::make_unique<app::manager::ActionRequest>(
            sender,
            app::manager::actions::ChangeHomescreenLayout,
            std::make_unique<gui::ChangeHomescreenLayoutParams>(newHomescreenLayout));
    }

  private:
    std::string newHomescreenLayout{};
};

A products/BellHybrid/services/appmgr/include/appmgr/messages/ChangeHomescreenLayoutParams.hpp => products/BellHybrid/services/appmgr/include/appmgr/messages/ChangeHomescreenLayoutParams.hpp +24 -0
@@ 0,0 1,24 @@
// 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 <service-appmgr/Actions.hpp>

namespace gui
{
    class ChangeHomescreenLayoutParams : public app::manager::actions::ActionParams
    {
      public:
        ChangeHomescreenLayoutParams(std::string newHomescreenLayout)
            : app::manager::actions::ActionParams{}, newHomescreenLayout{newHomescreenLayout} {};

        std::string getNewHomescreenLayoutName()
        {
            return newHomescreenLayout;
        }

      private:
        std::string newHomescreenLayout{};
    };
} // namespace gui