~aleteoryx/muditaos

44701130581e5e3452d03e1a066091742c3f5f48 — Maciej Gibowicz 1 year, 10 months ago e37e40e
[BH-1905] Add Focus timer application to the menu list

Creating a new application "Focus Timer" and adding it to the main menu
list
24 files changed, 644 insertions(+), 0 deletions(-)

M image/system_a/data/lang/Deutsch.json
M image/system_a/data/lang/English.json
M image/system_a/data/lang/Espanol.json
M image/system_a/data/lang/Francais.json
M image/system_a/data/lang/Polski.json
M products/BellHybrid/BellHybridMain.cpp
M products/BellHybrid/CMakeLists.txt
M products/BellHybrid/apps/CMakeLists.txt
A products/BellHybrid/apps/application-bell-focus-timer/ApplicationFocusTimer.cpp
A products/BellHybrid/apps/application-bell-focus-timer/CMakeLists.txt
A products/BellHybrid/apps/application-bell-focus-timer/data/FocusCommon.hpp
A products/BellHybrid/apps/application-bell-focus-timer/include/application-bell-focus-timer/ApplicationFocusTimer.hpp
A products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusSettingsPresenter.cpp
A products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusSettingsPresenter.hpp
A products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusTimerPresenter.cpp
A products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusTimerPresenter.hpp
A products/BellHybrid/apps/application-bell-focus-timer/windows/FocusMainWindow.cpp
A products/BellHybrid/apps/application-bell-focus-timer/windows/FocusMainWindow.hpp
A products/BellHybrid/apps/application-bell-focus-timer/windows/FocusSettingsWindow.cpp
A products/BellHybrid/apps/application-bell-focus-timer/windows/FocusSettingsWindow.hpp
A products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.cpp
A products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.hpp
M products/BellHybrid/apps/application-bell-main/CMakeLists.txt
M products/BellHybrid/apps/application-bell-main/windows/BellMainMenuWindow.cpp
M image/system_a/data/lang/Deutsch.json => image/system_a/data/lang/Deutsch.json +3 -0
@@ 28,6 28,8 @@
    "app_bell_bedtime_notification": "Schlafenszeit",
    "app_bell_charging_done_notification": "Vollst\u00e4ndig aufgeladen",
    "app_bell_charging_notification": "Wird aufgeladen",
    "app_bell_focus_settings": "Einstellungen",
    "app_bell_focus_start": "-",
    "app_bell_goodbye": "Auf Wiedersehen",
    "app_bell_greeting_msg": [
        "Guten Morgen! Stehen Sie auf"


@@ 121,6 123,7 @@
    "app_bell_welcome_message": "<text>Mudita Harmony<br/>ist ausgeschaltet</text>",
    "app_bellmain_alarm": "Alarm",
    "app_bellmain_bedtime": "Schlafenszeit",
    "app_bellmain_focus_timer": "-",
    "app_bellmain_home_screen_bottom_desc": "Der n\u00e4chste Alarm klingelt",
    "app_bellmain_home_screen_bottom_desc_and": "&",
    "app_bellmain_home_screen_bottom_desc_dp": "Tief dr\u00fccken, um zu aktivieren",

M image/system_a/data/lang/English.json => image/system_a/data/lang/English.json +3 -0
@@ 29,6 29,8 @@
    "app_bell_bedtime_notification": "It is your bedtime",
    "app_bell_charging_done_notification": "Fully charged",
    "app_bell_charging_notification": "Charging",
    "app_bell_focus_settings": "Settings",
    "app_bell_focus_start": "Focus now",
    "app_bell_goodbye": "Goodbye",
    "app_bell_greeting_msg": [
        "<text>Good Morning!<br />It's a Beautiful Day!</text>",


@@ 155,6 157,7 @@
    "app_bell_welcome_message": "<text>Mudita Harmony<br/>is switched OFF</text>",
    "app_bellmain_alarm": "Alarm",
    "app_bellmain_bedtime": "Bedtime",
    "app_bellmain_focus_timer": "Focus timer",
    "app_bellmain_home_screen_bottom_desc": "Next alarm will ring",
    "app_bellmain_home_screen_bottom_desc_and": "&",
    "app_bellmain_home_screen_bottom_desc_dp": "Deep press to activate",

M image/system_a/data/lang/Espanol.json => image/system_a/data/lang/Espanol.json +3 -0
@@ 27,6 27,8 @@
    "app_bell_bedtime_notification": "Es tu hora de dormir",
    "app_bell_charging_done_notification": "Completamente cargado",
    "app_bell_charging_notification": "Cargando",
    "app_bell_focus_settings": "Ajustes",
    "app_bell_focus_start": "-",
    "app_bell_goodbye": "Adi\u00f3s",
    "app_bell_greeting_msg": [
        "\u00a1Hola! Lev\u00e1ntate y brilla"


@@ 120,6 122,7 @@
    "app_bell_welcome_message": "<text>Mudita Harmony<br/>est\u00e1 apagado</text>",
    "app_bellmain_alarm": "Alarma",
    "app_bellmain_bedtime": "Hora de dormir",
    "app_bellmain_focus_timer": "-",
    "app_bellmain_home_screen_bottom_desc": "La siguiente alarma sonar\u00e1",
    "app_bellmain_home_screen_bottom_desc_and": "&",
    "app_bellmain_home_screen_bottom_desc_dp": "Presionar a fondo para activar",

M image/system_a/data/lang/Francais.json => image/system_a/data/lang/Francais.json +3 -0
@@ 29,6 29,8 @@
    "app_bell_bedtime_notification": "C'est l'heure du coucher",
    "app_bell_charging_done_notification": "Compl\u00e8tement charg\u00e9",
    "app_bell_charging_notification": "En charge",
    "app_bell_focus_settings": "Param\u00e8tres",
    "app_bell_focus_start": "-",
    "app_bell_goodbye": "Au revoir",
    "app_bell_greeting_msg": [
        "Re-bonjour!"


@@ 122,6 124,7 @@
    "app_bell_welcome_message": "<text>Mudita Harmony<br/>est d\u00e9sactiv\u00e9</text>",
    "app_bellmain_alarm": "Alarme",
    "app_bellmain_bedtime": "Heure du coucher",
    "app_bellmain_focus_timer": "-",
    "app_bellmain_home_screen_bottom_desc": "La prochaine alarme sonnera",
    "app_bellmain_home_screen_bottom_desc_and": "&",
    "app_bellmain_home_screen_bottom_desc_dp": "Appuyer fort pour activer",

M image/system_a/data/lang/Polski.json => image/system_a/data/lang/Polski.json +3 -0
@@ 28,6 28,8 @@
    "app_bell_bedtime_notification": "Pora na sen",
    "app_bell_charging_done_notification": "W pe\u0142ni na\u0142adowany",
    "app_bell_charging_notification": "\u0141adowanie",
    "app_bell_focus_settings": "Ustawienia",
    "app_bell_focus_start": "-",
    "app_bell_goodbye": "Do widzenia",
    "app_bell_greeting_msg": [
        "<text>Dzie\u0144 dobry!<br />Pobudka</text>"


@@ 121,6 123,7 @@
    "app_bell_welcome_message": "<text>Mudita Harmony<br/>jest wy\u0142\u0105czony</text>",
    "app_bellmain_alarm": "Alarm",
    "app_bellmain_bedtime": "Pora snu",
    "app_bellmain_focus_timer": "-",
    "app_bellmain_home_screen_bottom_desc": "Alarm zadzwoni",
    "app_bellmain_home_screen_bottom_desc_and": "i",
    "app_bellmain_home_screen_bottom_desc_dp": "Naci\u015bnij g\u0142\u0119boko, aby aktywowa\u0107",

M products/BellHybrid/BellHybridMain.cpp => products/BellHybrid/BellHybridMain.cpp +2 -0
@@ 13,6 13,7 @@
#include <application-bell-meditation-timer/MeditationTimer.hpp>
#include <application-bell-settings/ApplicationBellSettings.hpp>
#include <application-bell-powernap/ApplicationBellPowerNap.hpp>
#include <application-bell-focus-timer/ApplicationFocusTimer.hpp>

// modules
#include <module-db/databases/MultimediaFilesDB.hpp>


@@ 111,6 112,7 @@ int main()
            applications.push_back(
                app::CreateLauncher<app::ApplicationBellRelaxation>(app::applicationBellRelaxationName));
            applications.push_back(app::CreateLauncher<app::MeditationTimer>(app::applicationMeditationTimerName));
            applications.push_back(app::CreateLauncher<app::ApplicationFocusTimer>(app::applicationFocusTimerName));
            // start application manager
            return sysmgr->RunSystemService(
                std::make_shared<app::manager::ApplicationManager>(

M products/BellHybrid/CMakeLists.txt => products/BellHybrid/CMakeLists.txt +1 -0
@@ 53,6 53,7 @@ target_link_libraries(BellHybrid
        bell::app-common
        bell::app-main
        bell::app-meditation-timer
        bell::app-focus-timer
        bell::app-powernap
        bell::app-settings
        bell::db

M products/BellHybrid/apps/CMakeLists.txt => products/BellHybrid/apps/CMakeLists.txt +1 -0
@@ 30,4 30,5 @@ add_subdirectory(application-bell-bedtime)
add_subdirectory(application-bell-meditation-timer)
add_subdirectory(application-bell-settings)
add_subdirectory(application-bell-powernap)
add_subdirectory(application-bell-focus-timer)
add_subdirectory(common)

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

#include "ApplicationFocusTimer.hpp"
#include "FocusCommon.hpp"

#include "windows/FocusMainWindow.hpp"
#include "windows/FocusSettingsWindow.hpp"
#include "windows/FocusTimerWindow.hpp"

#include "presenter/FocusSettingsPresenter.hpp"
#include "presenter/FocusTimerPresenter.hpp"

#include <common/models/AudioModel.hpp>
#include <system/messages/SentinelRegistrationMessage.hpp>

namespace app
{
    ApplicationFocusTimer::ApplicationFocusTimer(std::string name,
                                                 std::string parent,
                                                 StatusIndicators statusIndicators,
                                                 StartInBackground startInBackground,
                                                 std::uint32_t stackDepth)
        : Application(std::move(name), std::move(parent), statusIndicators, startInBackground, stackDepth),
          audioModel{std::make_unique<AudioModel>(this)}
    {
        bus.channels.push_back(sys::BusChannel::ServiceAudioNotifications);
    }

    ApplicationFocusTimer::~ApplicationFocusTimer()
    {
        cpuSentinel->BlockWfiMode(false);
    }

    sys::ReturnCodes ApplicationFocusTimer::InitHandler()
    {
        auto ret = Application::InitHandler();
        if (ret != sys::ReturnCodes::Success) {
            return ret;
        }

        batteryModel                 = std::make_unique<app::BatteryModel>(this);
        lowBatteryInfoModel          = std::make_unique<app::LowBatteryInfoModel>();
        cpuSentinel                  = std::make_shared<sys::CpuSentinel>(applicationFocusTimerName, this);
        auto sentinelRegistrationMsg = std::make_shared<sys::SentinelRegistrationMessage>(cpuSentinel);
        bus.sendUnicast(std::move(sentinelRegistrationMsg), service::name::system_manager);
        cpuSentinel->BlockWfiMode(true);

        createUserInterface();

        return sys::ReturnCodes::Success;
    }

    void ApplicationFocusTimer::createUserInterface()
    {
        windowsFactory.attach(focus::window::name::main, [this](ApplicationCommon *app, const std::string &name) {
            return std::make_unique<focus::FocusMainWindow>(app);
        });

        windowsFactory.attach(focus::window::name::settings, [this](ApplicationCommon *app, const std::string &name) {
            auto presenter = std::make_unique<app::focus::SettingsPresenter>();
            return std::make_unique<focus::SettingsWindow>(app, std::move(presenter));
        });

        windowsFactory.attach(focus::window::name::timer, [this](ApplicationCommon *app, const std::string &name) {
            auto presenter = std::make_unique<app::focus::FocusTimerPresenter>(
                app, settings.get(), *batteryModel, *lowBatteryInfoModel);
            return std::make_unique<focus::FocusTimerWindow>(app, std::move(presenter));
        });

        attachPopups({gui::popup::ID::AlarmActivated,
                      gui::popup::ID::AlarmDeactivated,
                      gui::popup::ID::PowerOff,
                      gui::popup::ID::Reboot,
                      gui::popup::ID::BedtimeNotification,
                      gui::popup::ID::ChargingNotification,
                      gui::popup::ID::ChargingDoneNotification});
    }

    sys::MessagePointer ApplicationFocusTimer::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)
    {
        auto retMsg = Application::DataReceivedHandler(msgl);
        if (auto response = dynamic_cast<sys::ResponseMessage *>(retMsg.get());
            response != nullptr && response->retCode == sys::ReturnCodes::Success) {
            return retMsg;
        }

        return handleAsyncResponse(resp);
    }
} // namespace app

A products/BellHybrid/apps/application-bell-focus-timer/CMakeLists.txt => products/BellHybrid/apps/application-bell-focus-timer/CMakeLists.txt +45 -0
@@ 0,0 1,45 @@
# Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

add_library(application-bell-focus-timer STATIC)
add_library(bell::app-focus-timer ALIAS application-bell-focus-timer)

target_include_directories(application-bell-focus-timer
    PRIVATE
        $<BUILD_INTERFACE:
            ${CMAKE_CURRENT_SOURCE_DIR}
            include/application-bell-focus-timer
            data
            models
            presenter
            windows
        >
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

target_sources(application-bell-focus-timer
    PRIVATE
        ApplicationFocusTimer.cpp
        windows/FocusMainWindow.cpp
        windows/FocusSettingsWindow.cpp
        windows/FocusTimerWindow.cpp
        presenter/FocusSettingsPresenter.cpp
        presenter/FocusTimerPresenter.cpp

    PUBLIC
        include/application-bell-focus-timer/ApplicationFocusTimer.hpp
)

target_link_libraries(application-bell-focus-timer
    PRIVATE
        app
        bell::app-common
        bell::app-main
        bell::keymap
        bell::paths
        bell::db

    PUBLIC
        module-gui
)

A products/BellHybrid/apps/application-bell-focus-timer/data/FocusCommon.hpp => products/BellHybrid/apps/application-bell-focus-timer/data/FocusCommon.hpp +18 -0
@@ 0,0 1,18 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <AppWindowConstants.hpp>

namespace app::focus
{
    inline constexpr auto focusDBRecordName = "FocusTimer";

    namespace window::name
    {
        inline constexpr auto main     = gui::name::window::main_window;
        inline constexpr auto settings = "FocusTimerSettingsWindow";
        inline constexpr auto timer    = "FocusTimerSessionWindow";
    } // namespace window::name
} // namespace app::focus

A products/BellHybrid/apps/application-bell-focus-timer/include/application-bell-focus-timer/ApplicationFocusTimer.hpp => products/BellHybrid/apps/application-bell-focus-timer/include/application-bell-focus-timer/ApplicationFocusTimer.hpp +53 -0
@@ 0,0 1,53 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <Application.hpp>
#include <common/models/AbstractAudioModel.hpp>
#include <common/models/BatteryModel.hpp>
#include <common/models/LowBatteryInfoModel.hpp>

namespace app
{
    inline constexpr auto applicationFocusTimerName      = "ApplicationFocusTimer";
    inline constexpr auto applicationFocusTimerStackSize = 1024 * 8;

    class ApplicationFocusTimer : public Application
    {
      public:
        ApplicationFocusTimer(std::string name                    = applicationFocusTimerName,
                              std::string parent                  = "",
                              StatusIndicators statusIndicators   = StatusIndicators{},
                              StartInBackground startInBackground = {false},
                              std::uint32_t stackDepth            = applicationFocusTimerStackSize);
        ~ApplicationFocusTimer();
        sys::ReturnCodes InitHandler() override;

        void createUserInterface() override;
        void destroyUserInterface() override
        {}

        sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override;

        sys::ReturnCodes SwitchPowerModeHandler([[maybe_unused]] const sys::ServicePowerMode mode) override final
        {
            return sys::ReturnCodes::Success;
        }

      private:
        std::unique_ptr<AbstractAudioModel> audioModel;
        std::unique_ptr<AbstractBatteryModel> batteryModel;
        std::unique_ptr<AbstractLowBatteryInfoModel> lowBatteryInfoModel;
        std::shared_ptr<sys::CpuSentinel> cpuSentinel;
    };

    template <>
    struct ManifestTraits<ApplicationFocusTimer>
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch}};
        }
    };
} // namespace app

A products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusSettingsPresenter.cpp => products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusSettingsPresenter.cpp +55 -0
@@ 0,0 1,55 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "FocusSettingsPresenter.hpp"

#include <ApplicationCommon.hpp>
#include <apps-common/InternalModel.hpp>

namespace app::focus
{
    using namespace gui;
    SettingsPresenter::SettingsPresenter()
    {
        listItemsProvider = std::make_shared<BellListItemProvider>(BellListItemProvider::Items{});

        for (auto &item : listItemsProvider->getListItems()) {
            item->setValue();
        }
    }

    void SettingsPresenter::loadData()
    {
        for (auto &item : listItemsProvider->getListItems()) {
            item->setValue();
        }
    }

    void SettingsPresenter::saveData()
    {
        for (auto &item : listItemsProvider->getListItems()) {
            item->getValue();
        }
    }

    auto SettingsPresenter::getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider>
    {
        return listItemsProvider;
    }

    void SettingsPresenter::eraseProviderData()
    {
        listItemsProvider->clearData();
    }

    void SettingsPresenter::exitWithSave()
    {
        saveData();
        eraseProviderData();
    }

    void SettingsPresenter::exitWithoutSave()
    {
        eraseProviderData();
    }
} // namespace app::focus

A products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusSettingsPresenter.hpp => products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusSettingsPresenter.hpp +54 -0
@@ 0,0 1,54 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <apps-common/BasePresenter.hpp>
#include <common/BellListItemProvider.hpp>
#include <memory>

namespace app
{
    class ApplicationCommon;
}

namespace app::focus
{
    class SettingsContract
    {
      public:
        class View
        {
          public:
            virtual ~View() noexcept = default;
        };

        class Presenter : public BasePresenter<View>
        {
          public:
            virtual ~Presenter() noexcept                                                   = default;
            virtual auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> = 0;
            virtual void loadData()                                                         = 0;
            virtual void saveData()                                                         = 0;
            virtual void eraseProviderData()                                                = 0;
            virtual void exitWithSave()                                                     = 0;
            virtual void exitWithoutSave()                                                  = 0;
        };
    };

    class SettingsPresenter : public SettingsContract::Presenter
    {
      public:
        SettingsPresenter();

        void loadData() override;
        void saveData() override;
        auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
        void eraseProviderData() override;
        void exitWithSave() override;
        void exitWithoutSave() override;

      private:
        std::shared_ptr<BellListItemProvider> listItemsProvider;
    };
} // namespace app::focus

A products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusTimerPresenter.cpp => products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusTimerPresenter.cpp +15 -0
@@ 0,0 1,15 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "FocusTimerPresenter.hpp"

namespace app::focus
{
    FocusTimerPresenter::FocusTimerPresenter(app::ApplicationCommon *app,
                                             settings::Settings *settings,
                                             AbstractBatteryModel &batteryModel,
                                             AbstractLowBatteryInfoModel &lowBatteryInfoModel)
        : app{app}, settings{settings}, batteryModel{batteryModel}, lowBatteryInfoModel{lowBatteryInfoModel}
    {}

} // namespace app::focus

A products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusTimerPresenter.hpp => products/BellHybrid/apps/application-bell-focus-timer/presenter/FocusTimerPresenter.hpp +43 -0
@@ 0,0 1,43 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <apps-common/BasePresenter.hpp>
#include <apps-common/ApplicationCommon.hpp>
#include <common/models/BatteryModel.hpp>
#include <common/models/LowBatteryInfoModel.hpp>

namespace app::focus
{
    class FocusTimerContract
    {
      public:
        class View
        {
          public:
            virtual ~View() noexcept = default;
        };

        class Presenter : public BasePresenter<View>
        {
          public:
            virtual ~Presenter() noexcept = default;
        };
    };

    class FocusTimerPresenter : public FocusTimerContract::Presenter
    {
      public:
        FocusTimerPresenter(app::ApplicationCommon *app,
                            settings::Settings *settings,
                            AbstractBatteryModel &batteryModel,
                            AbstractLowBatteryInfoModel &lowBatteryInfoModel);

      private:
        app::ApplicationCommon *app{nullptr};
        settings::Settings *settings{nullptr};
        AbstractBatteryModel &batteryModel;
        AbstractLowBatteryInfoModel &lowBatteryInfoModel;
    };
} // namespace app::focus

A products/BellHybrid/apps/application-bell-focus-timer/windows/FocusMainWindow.cpp => products/BellHybrid/apps/application-bell-focus-timer/windows/FocusMainWindow.cpp +53 -0
@@ 0,0 1,53 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "FocusMainWindow.hpp"

#include "FocusSettingsWindow.hpp"
#include "FocusTimerWindow.hpp"

#include <common/options/OptionBellMenu.hpp>

namespace app::focus
{
    using namespace gui;
    FocusMainWindow::FocusMainWindow(app::ApplicationCommon *app, const std::string name)
        : BellOptionWindow(app, std::move(name))
    {
        addOptions(settingsOptionsList());
        setListTitle(utils::translate("app_bellmain_focus_timer"));
    }

    std::list<Option> FocusMainWindow::settingsOptionsList()
    {
        using ActivatedCallback = std::function<bool(gui::Item &)>;
        using Callback          = std::function<ActivatedCallback(const std::string &window)>;

        auto defaultCallback = [this](const std::string &window) {
            return [window, this](gui::Item &) {
                if (window.empty()) {
                    return false;
                }
                application->switchWindow(window);
                return true;
            };
        };

        std::list<gui::Option> settingsOptionList;
        auto addWinSettings = [&](const UTF8 &name, const std::string &window, Callback &&callback) {
            settingsOptionList.emplace_back(std::make_unique<gui::option::OptionBellMenu>(
                name,
                callback(window),
                [=](gui::Item &item) {
                    // put focus change callback here
                    return true;
                },
                this));
        };

        addWinSettings(utils::translate("app_bell_focus_start"), window::name::timer, defaultCallback);
        addWinSettings(utils::translate("app_bell_focus_settings"), window::name::settings, defaultCallback);

        return settingsOptionList;
    }
} // namespace app::focus

A products/BellHybrid/apps/application-bell-focus-timer/windows/FocusMainWindow.hpp => products/BellHybrid/apps/application-bell-focus-timer/windows/FocusMainWindow.hpp +20 -0
@@ 0,0 1,20 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "FocusCommon.hpp"
#include <common/options/BellOptionWindow.hpp>

namespace app::focus
{
    class FocusMainWindow : public gui::BellOptionWindow
    {
      public:
        explicit FocusMainWindow(app::ApplicationCommon *app, const std::string name = window::name::main);

      private:
        std::list<gui::Option> settingsOptionsList();
    };

} // namespace app::focus

A products/BellHybrid/apps/application-bell-focus-timer/windows/FocusSettingsWindow.cpp => products/BellHybrid/apps/application-bell-focus-timer/windows/FocusSettingsWindow.cpp +83 -0
@@ 0,0 1,83 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "FocusSettingsWindow.hpp"

#include <common/data/StyleCommon.hpp>
#include <apps-common/ApplicationCommon.hpp>
#include <module-gui/gui/input/InputEvent.hpp>
#include <module-gui/gui/widgets/SideListView.hpp>

namespace app::focus
{
    using namespace gui;
    SettingsWindow::SettingsWindow(app::ApplicationCommon *app,
                                   std::unique_ptr<SettingsContract::Presenter> presenter,
                                   const std::string &name)
        : AppWindow(app, name), presenter{std::move(presenter)}
    {
        this->presenter->attach(this);
        buildInterface();
    }

    void SettingsWindow::rebuild()
    {
        erase();
        buildInterface();
        isSaveNeeded = false;
    }

    void SettingsWindow::buildInterface()
    {
        AppWindow::buildInterface();
        statusBar->setVisible(false);
        header->setTitleVisibility(false);
        navBar->setVisible(false);

        sideListView = new gui::SideListView(
            this, 0U, 0U, this->getWidth(), this->getHeight(), presenter->getPagesProvider(), PageBarType::None);
        sideListView->setEdges(RectangleEdge::None);

        sideListView->rebuildList(listview::RebuildType::Full);

        presenter->loadData();
    }

    void SettingsWindow::onBeforeShow(gui::ShowMode mode, gui::SwitchData *data)
    {
        AppWindow::onBeforeShow(mode, data);
        setFocusItem(sideListView);
    }

    bool SettingsWindow::onInput(const gui::InputEvent &inputEvent)
    {
        if (sideListView->onInput(inputEvent)) {
            return true;
        }
        if (inputEvent.isShortRelease(KeyCode::KEY_ENTER)) {
            isSaveNeeded = true;
            switchToExitWindow();
            return true;
        }
        if (inputEvent.isShortRelease(KeyCode::KEY_RF)) {
            presenter->exitWithoutSave();
        }

        return AppWindow::onInput(inputEvent);
    }

    void SettingsWindow::switchToExitWindow()
    {}

    void SettingsWindow::onClose(const CloseReason reason)
    {
        if (reason != CloseReason::Popup) {
            if (isSaveNeeded) {
                presenter->exitWithSave();
            }
            else {
                presenter->exitWithoutSave();
            }
        }
    }
} // namespace app::focus

A products/BellHybrid/apps/application-bell-focus-timer/windows/FocusSettingsWindow.hpp => products/BellHybrid/apps/application-bell-focus-timer/windows/FocusSettingsWindow.hpp +38 -0
@@ 0,0 1,38 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "data/FocusCommon.hpp"
#include "presenter/FocusSettingsPresenter.hpp"

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

namespace gui
{
    class SideListView;
}

namespace app::focus
{
    class SettingsWindow : public gui::AppWindow, public SettingsContract::View
    {
      public:
        SettingsWindow(app::ApplicationCommon *app,
                       std::unique_ptr<SettingsContract::Presenter> presenter,
                       const std::string &name = window::name::settings);

        void buildInterface() override;
        void onBeforeShow(gui::ShowMode mode, gui::SwitchData *data) override;
        void onClose(CloseReason reason) override;
        bool onInput(const gui::InputEvent &inputEvent) override;
        void rebuild() override;

      private:
        void switchToExitWindow();

        gui::SideListView *sideListView{};
        std::unique_ptr<SettingsContract::Presenter> presenter;
        bool isSaveNeeded{false};
    };
} // namespace app::focus

A products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.cpp => products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.cpp +29 -0
@@ 0,0 1,29 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "FocusTimerWindow.hpp"

#include <apps-common/ApplicationCommon.hpp>
#include <module-gui/gui/input/InputEvent.hpp>

namespace app::focus
{
    FocusTimerWindow::FocusTimerWindow(app::ApplicationCommon *app,
                                       std::unique_ptr<FocusTimerContract::Presenter> &&windowPresenter,
                                       const std::string &name)
        : AppWindow(app, name), presenter{std::move(windowPresenter)}
    {
        presenter->attach(this);
        buildInterface();
    }

    void FocusTimerWindow::buildInterface()
    {
        AppWindow::buildInterface();
    }

    bool FocusTimerWindow::onInput(const gui::InputEvent &inputEvent)
    {
        return AppWindow::onInput(inputEvent);
    }
} // namespace app::focus

A products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.hpp => products/BellHybrid/apps/application-bell-focus-timer/windows/FocusTimerWindow.hpp +26 -0
@@ 0,0 1,26 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "data/FocusCommon.hpp"
#include "presenter/FocusTimerPresenter.hpp"

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

namespace app::focus
{
    class FocusTimerWindow : public gui::AppWindow, public FocusTimerContract::View
    {
      public:
        FocusTimerWindow(app::ApplicationCommon *app,
                         std::unique_ptr<FocusTimerContract::Presenter> &&windowPresenter,
                         const std::string &name = window::name::timer);

        void buildInterface() override;
        bool onInput(const gui::InputEvent &inputEvent) override;

      private:
        std::unique_ptr<FocusTimerContract::Presenter> presenter;
    };
} // namespace app::focus

M products/BellHybrid/apps/application-bell-main/CMakeLists.txt => products/BellHybrid/apps/application-bell-main/CMakeLists.txt +1 -0
@@ 53,6 53,7 @@ target_link_libraries(application-bell-main
        bell::app-relaxation
        bell::app-bedtime
        bell::app-meditation-timer
        bell::app-focus-timer
        bell::app-settings
        bell::app-powernap
        bell::keymap

M products/BellHybrid/apps/application-bell-main/windows/BellMainMenuWindow.cpp => products/BellHybrid/apps/application-bell-main/windows/BellMainMenuWindow.cpp +2 -0
@@ 10,6 10,7 @@
#include <application-bell-meditation-timer/MeditationTimer.hpp>
#include <application-bell-settings/ApplicationBellSettings.hpp>
#include <application-bell-powernap/ApplicationBellPowerNap.hpp>
#include <application-bell-focus-timer/ApplicationFocusTimer.hpp>

#include <Dialog.hpp>
#include <DialogMetadataMessage.hpp>


@@ 52,6 53,7 @@ namespace gui
        addAppMenu(utils::translate("app_bellmain_relaxation"), app::applicationBellRelaxationName);
        addAppMenu(utils::translate("app_bellmain_meditation_timer"), app::applicationMeditationTimerName);
        addAppMenu(utils::translate("app_bellmain_bedtime"), app::applicationBellBedtimeName);
        addAppMenu(utils::translate("app_bellmain_focus_timer"), app::applicationFocusTimerName);
        addAppMenu(utils::translate("app_bellmain_settings"), app::applicationBellSettingsName);

        return menuOptionList;