~aleteoryx/muditaos

bc7dc5b6345c1ca01d98ab8a68bb5af4007c4ae6 — Piotr Tański 4 years ago 7597d38
[EGD-7779] Dark mode implemented

Experimental dark mode feature implemented.
M image/assets/lang/English.json => image/assets/lang/English.json +1 -0
@@ 326,6 326,7 @@
  "app_settings_net": "Network",
  "app_settings_disp_key": "Display and keypad",
  "app_settings_display_display_light": "Display light",
  "app_settings_display_dark_mode": "Dark mode (experimental)",
  "app_settings_display_light_main": "Frontlight",
  "app_settings_display_light_auto": "Automatic",
  "app_settings_display_light_brightness": "Brightness",

M image/user/db/settings_bell_002.sql => image/user/db/settings_bell_002.sql +2 -1
@@ 48,6 48,7 @@ INSERT OR IGNORE INTO settings_tab (path, value) VALUES
    ('bedtime_time','21:00'),
    ('bedtime_tone','Evening Horizon'),
    ('bedtime_duration','5'),
    ('bedtime_volume','1');
    ('bedtime_volume','1'),
    ('\ServiceEink\\display_inverted_mode', '0');



M image/user/db/settings_v2_002-devel.sql => image/user/db/settings_v2_002-devel.sql +2 -1
@@ 41,6 41,7 @@ INSERT OR IGNORE INTO settings_tab (path, value) VALUES
    ('keypad_light_state', '0'),
    ('gs_current_timezone_name', ''),
    ('gs_current_timezone_rules', ''),
    ('\ServiceTime\\gs_automatic_date_and_time_is_on', '1');
    ('\ServiceTime\\gs_automatic_date_and_time_is_on', '1'),
    ('\ServiceEink\\display_inverted_mode', '0');



M image/user/db/settings_v2_002.sql => image/user/db/settings_v2_002.sql +2 -1
@@ 42,7 42,8 @@ INSERT OR IGNORE INTO settings_tab (path, value) VALUES
    ('keypad_light_state', '0'),
    ('gs_current_timezone_name', ''),
    ('gs_current_timezone_rules', ''),
    ('\ServiceTime\\gs_automatic_date_and_time_is_on', '1');
    ('\ServiceTime\\gs_automatic_date_and_time_is_on', '1'),
    ('\ServiceEink\\display_inverted_mode', '0');




M module-apps/application-settings/ApplicationSettings.cpp => module-apps/application-settings/ApplicationSettings.cpp +4 -6
@@ 7,7 7,6 @@
#include <application-settings/windows/advanced/AdvancedOptionsWindow.hpp>
#include <application-settings/windows/advanced/InformationWindow.hpp>
#include <application-settings/windows/advanced/UITestWindow.hpp>
#include <application-settings/windows/advanced/EinkModeWindow.hpp>
#include <application-settings/windows/advanced/ColorTestWindow.hpp>
#include <application-settings/windows/advanced/StatusBarImageTypeWindow.hpp>
#include <application-settings/windows/bluetooth/BluetoothWindow.hpp>


@@ 61,6 60,7 @@
#include <application-settings/data/PINSettingsLockStateData.hpp>
#include <application-settings/data/AutoLockData.hpp>
#include <application-settings/models/apps/SoundsModel.hpp>
#include <application-settings/models/display-keypad/DisplayModeModel.hpp>
#include <service-evtmgr/EventManagerServiceAPI.hpp>
#include <service-audio/AudioServiceAPI.hpp>
#include <service-bluetooth/BluetoothMessage.hpp>


@@ 122,7 122,7 @@ namespace app
    {}

    // Invoked upon receiving data message
    auto ApplicationSettings::DataReceivedHandler(sys::DataMessage *msgl, [[maybe_unused]] sys::ResponseMessage *resp)
    auto ApplicationSettings::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)
        -> sys::MessagePointer
    {
        auto retMsg = Application::DataReceivedHandler(msgl);


@@ 374,9 374,6 @@ namespace app
        windowsFactory.attach(gui::window::name::ui_test, [](ApplicationCommon *app, const std::string &name) {
            return std::make_unique<gui::UiTestWindow>(app);
        });
        windowsFactory.attach(gui::window::name::eink_mode, [](ApplicationCommon *app, const std::string &name) {
            return std::make_unique<gui::EinkModeWindow>(app);
        });
        windowsFactory.attach(gui::window::name::color_test_window,
                              [](ApplicationCommon *app, const std::string &name) {
                                  return std::make_unique<gui::ColorTestWindow>(app);


@@ 434,7 431,8 @@ namespace app
        // Display and keypad
        windowsFactory.attach(gui::window::name::display_and_keypad,
                              [](ApplicationCommon *app, const std::string &name) {
                                  return std::make_unique<gui::DisplayAndKeypadWindow>(app);
                                  auto model = std::make_unique<display_mode::DisplayModeModel>(app);
                                  return std::make_unique<gui::DisplayAndKeypadWindow>(app, std::move(model));
                              });
        windowsFactory.attach(gui::window::name::display_light, [](ApplicationCommon *app, const std::string &name) {
            return std::make_unique<gui::DisplayLightWindow>(app, static_cast<ApplicationSettings *>(app));

M module-apps/application-settings/CMakeLists.txt => module-apps/application-settings/CMakeLists.txt +1 -6
@@ 12,14 12,11 @@ target_sources(application-settings
        ApplicationSettings.cpp
        models/advanced/ColorTestModel.cpp
        models/apps/AudioSettingsModel.cpp
        models/apps/AudioSettingsModel.cpp
        models/apps/SoundsModel.cpp
        models/apps/SoundsModel.cpp
        models/bluetooth/BluetoothSettingsModel.cpp
        models/display-keypad/CategoriesModel.cpp
        models/display-keypad/CategoriesModel.cpp
        models/display-keypad/QuotesModel.cpp
        models/display-keypad/QuotesModel.cpp
        models/display-keypad/DisplayModeModel.cpp
        models/network/ApnSettingsModel.cpp
        models/network/NewApnModel.cpp
        models/network/SimContactsImportModel.cpp


@@ 50,7 47,6 @@ target_sources(application-settings
        windows/SettingsMainWindow.cpp
        windows/advanced/AdvancedOptionsWindow.cpp
        windows/advanced/ColorTestWindow.cpp
        windows/advanced/EinkModeWindow.cpp
        windows/advanced/InformationWindow.cpp
        windows/advanced/UITestWindow.cpp
        windows/advanced/StatusBarImageTypeWindow.cpp


@@ 109,7 105,6 @@ target_sources(application-settings
        windows/WindowNames.hpp
        windows/advanced/AdvancedOptionsWindow.hpp
        windows/advanced/ColorTestWindow.hpp
        windows/advanced/EinkModeWindow.hpp
        windows/advanced/InformationWindow.hpp
        windows/advanced/UITestWindow.hpp
        windows/advanced/StatusBarImageTypeWindow.hpp

A module-apps/application-settings/models/display-keypad/DisplayModeModel.cpp => module-apps/application-settings/models/display-keypad/DisplayModeModel.cpp +53 -0
@@ 0,0 1,53 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "DisplayModeModel.hpp"

#include <AsyncTask.hpp>

#include <service-eink/Common.hpp>
#include <service-eink/api/ServiceEinkApi.hpp>
#include <service-eink/messages/EinkModeMessage.hpp>

namespace display_mode
{
    namespace
    {
        service::eink::EinkModeMessage::Mode toEinkMode(Mode mode) noexcept
        {
            using service::eink::EinkModeMessage;
            if (mode == Mode::Light) {
                return EinkModeMessage::Mode::Normal;
            }
            return EinkModeMessage::Mode::Invert;
        }
    } // namespace

    DisplayModeModel::DisplayModeModel(app::ApplicationCommon *application)
        : app::AsyncCallbackReceiver{application}, application{application}
    {}

    void DisplayModeModel::setMode(Mode mode, std::function<void(Mode)> &&onSuccess)
    {
        using service::eink::EinkModeMessage;
        auto request = app::AsyncRequest::createFromMessage(std::make_unique<EinkModeMessage>(toEinkMode(mode)),
                                                            service::name::eink);
        request->execute(application, this, [mode, onSuccess](auto response) {
            using service::eink::EinkModeResponse;
            if (auto einkModeResponse = static_cast<EinkModeResponse *>(response);
                einkModeResponse->retCode != sys::ReturnCodes::Success) {
                return false;
            }

            if (onSuccess) {
                onSuccess(mode);
            }
            return true;
        });
    }

    auto DisplayModeModel::isDarkModeEnabled() const noexcept -> bool
    {
        return service::eink::api::isInvertedModeEnabled();
    }
} // namespace display_mode

A module-apps/application-settings/models/display-keypad/DisplayModeModel.hpp => module-apps/application-settings/models/display-keypad/DisplayModeModel.hpp +35 -0
@@ 0,0 1,35 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <apps-common/ApplicationCommon.hpp>

#include <functional>

namespace display_mode
{
    enum class Mode
    {
        Light, ///< Regular display mode
        Dark   ///< Colors inverted display mode
    };

    class DisplayModeModel : public app::AsyncCallbackReceiver
    {
      public:
        explicit DisplayModeModel(app::ApplicationCommon *application);

        /**
         * Sets the display mode.
         * @param mode          Desired display mode
         * @param onSuccess     Callback called on success
         */
        void setMode(Mode mode, std::function<void(Mode)> &&onSuccess);

        [[nodiscard]] auto isDarkModeEnabled() const noexcept -> bool;

      private:
        app::ApplicationCommon *application{nullptr};
    };
} // namespace display_mode

M module-apps/application-settings/windows/WindowNames.hpp => module-apps/application-settings/windows/WindowNames.hpp +0 -1
@@ 8,7 8,6 @@ namespace gui::window::name
    inline constexpr auto advanced          = "Advanced";
    inline constexpr auto information       = "Information";
    inline constexpr auto ui_test           = "UI Test";
    inline constexpr auto eink_mode         = "Change Eink Mode";
    inline constexpr auto color_test_window = "Color Test";
    inline constexpr auto status_bar_img_type = "StatusBarImgType";


M module-apps/application-settings/windows/advanced/AdvancedOptionsWindow.cpp => module-apps/application-settings/windows/advanced/AdvancedOptionsWindow.cpp +0 -1
@@ 25,7 25,6 @@ std::list<gui::Option> advancedOptions(app::ApplicationCommon *app)

    addMenu("Information", gui::window::name::information);
    addMenu("UI Test", gui::window::name::ui_test);
    addMenu("Eink Mode", gui::window::name::eink_mode);
    addMenu("Color Test", gui::window::name::color_test_window);
    addMenu("Statusbar Image Test", gui::window::name::status_bar_img_type);


D module-apps/application-settings/windows/advanced/EinkModeWindow.cpp => module-apps/application-settings/windows/advanced/EinkModeWindow.cpp +0 -41
@@ 1,41 0,0 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "EinkModeWindow.hpp"

#include <application-settings/windows/WindowNames.hpp>

#include <Application.hpp>
#include <service-eink/Common.hpp>
#include <service-eink/messages/EinkModeMessage.hpp>

namespace gui
{

    EinkModeWindow::EinkModeWindow(app::ApplicationCommon *app) : AppWindow(app, window::name::eink_mode)
    {
        AppWindow::buildInterface();
        navBar->setActive(nav_bar::Side::Center, true);
        navBar->setActive(nav_bar::Side::Right, true);
        navBar->setText(nav_bar::Side::Center, utils::translate(style::strings::common::select));
        navBar->setText(nav_bar::Side::Right, utils::translate(style::strings::common::back));

        setTitle(window::name::eink_mode);
        auto label               = new Label(this, 100, 200, 300, 50, "Change mode on click");
        label->activatedCallback = [this](Item &) -> bool {
            static auto last_mode = service::eink::EinkModeMessage::Mode::Normal;
            if (last_mode == service::eink::EinkModeMessage::Mode::Normal) {
                last_mode = service::eink::EinkModeMessage::Mode::Invert;
            }
            else {
                last_mode = service::eink::EinkModeMessage::Mode::Normal;
            }

            application->bus.sendUnicastSync(
                std::make_shared<service::eink::EinkModeMessage>(last_mode), service::name::eink, 5000);
            return true;
        };
        setFocusItem(label);
    }

} /* namespace gui */

D module-apps/application-settings/windows/advanced/EinkModeWindow.hpp => module-apps/application-settings/windows/advanced/EinkModeWindow.hpp +0 -14
@@ 1,14 0,0 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once

#include <AppWindow.hpp>

namespace gui
{
    class EinkModeWindow : public AppWindow
    {
      public:
        explicit EinkModeWindow(app::ApplicationCommon *app);
    };
} /* namespace gui */

M module-apps/application-settings/windows/display-keypad/DisplayAndKeypadWindow.cpp => module-apps/application-settings/windows/display-keypad/DisplayAndKeypadWindow.cpp +32 -7
@@ 9,14 9,15 @@

namespace gui
{
    DisplayAndKeypadWindow::DisplayAndKeypadWindow(app::ApplicationCommon *app)
        : OptionWindow(app, gui::window::name::display_and_keypad)
    DisplayAndKeypadWindow::DisplayAndKeypadWindow(app::ApplicationCommon *app,
                                                   std::unique_ptr<display_mode::DisplayModeModel> &&displayMode)
        : OptionWindow(app, gui::window::name::display_and_keypad), displayMode{std::move(displayMode)}
    {
        addOptions(displayAndKeypadOptionsList());
        addOptions(displayAndKeypadOptionsList(this->displayMode->isDarkModeEnabled()));
        setTitle(utils::translate("app_settings_disp_key"));
    }

    std::list<Option> DisplayAndKeypadWindow::displayAndKeypadOptionsList()
    std::list<Option> DisplayAndKeypadWindow::displayAndKeypadOptionsList(bool isDarkModeEnabled)
    {
        std::list<gui::Option> optionList;



@@ 41,16 42,40 @@ namespace gui
                gui::option::SettingRightItem::ArrowWhite));
        };

        addMenu(utils::translate("app_settings_display_display_light"), gui::window::name::display_light);
        auto addOnOffOption = [&](const UTF8 &text, std::function<bool(gui::Item &)> onActivated) {
            optionList.emplace_back(std::make_unique<gui::option::OptionSettings>(
                text,
                [=](gui::Item &item) mutable { return onActivated(item); },
                [=](gui::Item &item) {
                    if (item.focus) {
                        this->setNavBarText(utils::translate(style::strings::common::Switch), nav_bar::Side::Center);
                    }
                    return true;
                },
                this,
                isDarkModeEnabled ? gui::option::SettingRightItem::On : gui::option::SettingRightItem::Off));
        };

        addMenu(utils::translate("app_settings_display_display_light"), gui::window::name::display_light);
#if DISABLED_SETTINGS_OPTIONS == 1
        addMenu(utils::translate("app_settings_display_font_size"), gui::window::name::font_size);
        addMenu(utils::translate("app_settings_display_wallpaper"), gui::window::name::wallpaper);
#endif // DISABLED_SETTINGS_OPTIONS

        addMenu(utils::translate("app_settings_display_keypad_light"), gui::window::name::keypad_light);
        addMenu(utils::translate("app_settings_display_input_language"), gui::window::name::input_language);

        addOnOffOption(utils::translate("app_settings_display_dark_mode"), [this](gui::Item & /*item*/) {
            switchDisplayMode();
            return true;
        });
        return optionList;
    }

    void DisplayAndKeypadWindow::switchDisplayMode()
    {
        auto onSuccess = [this](display_mode::Mode mode) {
            refreshOptions(displayAndKeypadOptionsList(mode == display_mode::Mode::Dark));
        };
        displayMode->setMode(displayMode->isDarkModeEnabled() ? display_mode::Mode::Light : display_mode::Mode::Dark,
                             std::move(onSuccess));
    }
} // namespace gui

M module-apps/application-settings/windows/display-keypad/DisplayAndKeypadWindow.hpp => module-apps/application-settings/windows/display-keypad/DisplayAndKeypadWindow.hpp +10 -2
@@ 5,14 5,22 @@

#include <OptionWindow.hpp>

#include <application-settings/models/display-keypad/DisplayModeModel.hpp>

#include <memory>

namespace gui
{
    class DisplayAndKeypadWindow : public OptionWindow
    {
      public:
        explicit DisplayAndKeypadWindow(app::ApplicationCommon *app);
        DisplayAndKeypadWindow(app::ApplicationCommon *app,
                               std::unique_ptr<display_mode::DisplayModeModel> &&displayMode);

      private:
        std::list<Option> displayAndKeypadOptionsList();
        void switchDisplayMode();
        std::list<Option> displayAndKeypadOptionsList(bool isDarkModeEnabled);

        std::unique_ptr<display_mode::DisplayModeModel> displayMode;
    };
} // namespace gui

M module-apps/apps-common/AsyncTask.hpp => module-apps/apps-common/AsyncTask.hpp +0 -2
@@ 100,8 100,6 @@ namespace app

        AsyncRequest(std::unique_ptr<sys::DataMessage> &&message, std::string serviceName) noexcept;

        void setCallback(std::function<bool> &&callback) noexcept;

      private:
        [[nodiscard]] auto onExecute(ApplicationCommon *application) -> RequestId override;


M module-services/service-db/agents/settings/SystemSettings.hpp => module-services/service-db/agents/settings/SystemSettings.hpp +4 -0
@@ 68,4 68,8 @@ namespace settings
        constexpr inline auto state = "keypad_light_state";
    } // namespace KeypadLight

    namespace Display
    {
        constexpr inline auto invertedMode = "display_inverted_mode";
    } // namespace Display
}; // namespace settings

M module-services/service-eink/CMakeLists.txt => module-services/service-eink/CMakeLists.txt +2 -0
@@ 4,6 4,8 @@ message( "${PROJECT_NAME}  ${CMAKE_CURRENT_LIST_DIR}" )
set(SOURCES
    ServiceEink.cpp
    EinkDisplay.cpp
    api/ServiceEinkApi.cpp
    internal/StaticData.cpp
    messages/ImageMessage.cpp
    messages/PrepareDisplayEarlyRequest.cpp
)

M module-services/service-eink/ServiceEink.cpp => module-services/service-eink/ServiceEink.cpp +43 -8
@@ 3,6 3,7 @@

#include <board.h>
#include "ServiceEink.hpp"
#include "internal/StaticData.hpp"
#include "messages/EinkModeMessage.hpp"
#include "messages/PrepareDisplayEarlyRequest.hpp"
#include <service-gui/messages/EinkInitialized.hpp>


@@ 15,10 16,12 @@
#include <system/messages/DeviceRegistrationMessage.hpp>
#include <system/messages/SentinelRegistrationMessage.hpp>
#include <system/Constants.hpp>
#include <service-db/agents/settings/SystemSettings.hpp>

#include <cstring>
#include <memory>
#include <gsl/util>
#include "Utils.hpp"

namespace service::eink
{


@@ 26,11 29,20 @@ namespace service::eink
    {
        constexpr auto ServceEinkStackDepth = 4096U;
        constexpr std::chrono::milliseconds displayPowerOffTimeout{3800};

        std::string toSettingString(EinkModeMessage::Mode mode)
        {
            if (mode == EinkModeMessage::Mode::Normal) {
                return "0";
            }
            return "1";
        }
    } // namespace

    ServiceEink::ServiceEink(ExitAction exitAction, const std::string &name, std::string parent)
        : sys::Service(name, std::move(parent), ServceEinkStackDepth), exitAction{exitAction},
          display{{BOARD_EINK_DISPLAY_RES_X, BOARD_EINK_DISPLAY_RES_Y}}, currentState{State::Running}
        : sys::Service(name, std::move(parent), ServceEinkStackDepth),
          exitAction{exitAction}, display{{BOARD_EINK_DISPLAY_RES_X, BOARD_EINK_DISPLAY_RES_Y}},
          currentState{State::Running}, settings{std::make_unique<settings::Settings>()}
    {
        displayPowerOffTimer = sys::TimerFactory::createSingleShotTimer(
            this, "einkDisplayPowerOff", displayPowerOffTimeout, [this](sys::Timer &) { display.powerOff(); });


@@ 60,6 72,9 @@ namespace service::eink
            return sys::ReturnCodes::Failure;
        }

        settings->init(service::ServiceProxy(shared_from_this()));
        initStaticData();

        auto deviceRegistrationMsg = std::make_shared<sys::DeviceRegistrationMessage>(display.getDevice());
        bus.sendUnicast(deviceRegistrationMsg, service::name::system_manager);



@@ 73,12 88,21 @@ namespace service::eink
        return sys::ReturnCodes::Success;
    }

    void ServiceEink::initStaticData()
    {
        const auto invertedModeSetting   = settings->getValue(settings::Display::invertedMode);
        const auto isInvertedModeEnabled = utils::toNumeric(invertedModeSetting);
        const auto mode = isInvertedModeEnabled == 0 ? EinkModeMessage::Mode::Normal : EinkModeMessage::Mode::Invert;
        setDisplayMode(mode);
    }

    sys::ReturnCodes ServiceEink::DeinitHandler()
    {
        if (exitAction == ExitAction::WipeOut) {
            display.wipeOut();
        }
        display.shutdown();
        settings->deinit();
        return sys::ReturnCodes::Success;
    }



@@ 122,12 146,23 @@ namespace service::eink

    sys::MessagePointer ServiceEink::handleEinkModeChangedMessage(sys::Message *message)
    {
        const auto msg         = static_cast<service::eink::EinkModeMessage *>(message);
        const auto displayMode = msg->getMode() == service::eink::EinkModeMessage::Mode::Normal
                                     ? EinkDisplayColorMode_e::EinkDisplayColorModeStandard
                                     : EinkDisplayColorMode_e::EinkDisplayColorModeInverted;
        display.setMode(displayMode);
        return sys::MessageNone{};
        const auto msg  = static_cast<EinkModeMessage *>(message);
        const auto mode = msg->getMode();
        setDisplayMode(mode);
        settings->setValue(settings::Display::invertedMode, toSettingString(mode));
        return std::make_shared<EinkModeResponse>();
    }

    void ServiceEink::setDisplayMode(EinkModeMessage::Mode mode)
    {
        auto invertedModeRequested = mode == EinkModeMessage::Mode::Invert;
        if (invertedModeRequested) {
            display.setMode(EinkDisplayColorMode_e::EinkDisplayColorModeInverted);
        }
        else {
            display.setMode(EinkDisplayColorMode_e::EinkDisplayColorModeStandard);
        }
        internal::StaticData::get().setInvertedMode(invertedModeRequested);
    }

    sys::MessagePointer ServiceEink::handleImageMessage(sys::Message *request)

M module-services/service-eink/ServiceEink.hpp => module-services/service-eink/ServiceEink.hpp +6 -0
@@ 12,11 12,13 @@
#include "EinkDisplay.hpp"

#include <service-db/DBServiceName.hpp>
#include <service-db/Settings.hpp>
#include <service-gui/Common.hpp>

#include <chrono>
#include <cstdint>
#include <string>
#include <module-services/service-eink/messages/EinkModeMessage.hpp>

namespace service::eink
{


@@ 63,16 65,20 @@ namespace service::eink
        EinkStatus_e prepareDisplay(::gui::RefreshModes refreshMode, WaveformTemperature behaviour);
        EinkStatus_e refreshDisplay(::gui::RefreshModes refreshMode);
        EinkStatus_e updateDisplay(uint8_t *frameBuffer, ::gui::RefreshModes refreshMode);
        void setDisplayMode(EinkModeMessage::Mode mode);

        sys::MessagePointer handleEinkModeChangedMessage(sys::Message *message);
        sys::MessagePointer handleImageMessage(sys::Message *message);
        sys::MessagePointer handlePrepareEarlyRequest(sys::Message *message);

        void initStaticData();

        ExitAction exitAction;
        EinkDisplay display;
        State currentState;
        sys::TimerHandle displayPowerOffTimer;
        std::shared_ptr<EinkSentinel> eInkSentinel;
        std::unique_ptr<settings::Settings> settings;
    };
} // namespace service::eink


A module-services/service-eink/api/ServiceEinkApi.cpp => module-services/service-eink/api/ServiceEinkApi.cpp +14 -0
@@ 0,0 1,14 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ServiceEinkApi.hpp"

#include "internal/StaticData.hpp"

namespace service::eink::api
{
    [[nodiscard]] auto isInvertedModeEnabled() noexcept -> bool
    {
        return internal::StaticData::get().isInvertedModeEnabled();
    }
} // namespace service::eink::api

A module-services/service-eink/api/ServiceEinkApi.hpp => module-services/service-eink/api/ServiceEinkApi.hpp +9 -0
@@ 0,0 1,9 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

namespace service::eink::api
{
    [[nodiscard]] auto isInvertedModeEnabled() noexcept -> bool;
} // namespace service::eink::api

A module-services/service-eink/internal/StaticData.cpp => module-services/service-eink/internal/StaticData.cpp +23 -0
@@ 0,0 1,23 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "StaticData.hpp"

namespace service::eink::internal
{
    StaticData &StaticData::get()
    {
        static StaticData instance;
        return instance;
    }

    void StaticData::setInvertedMode(bool enabled) noexcept
    {
        invertedEnabled = enabled;
    }

    auto StaticData::isInvertedModeEnabled() const noexcept -> bool
    {
        return invertedEnabled;
    }
} // namespace service::eink::internal

A module-services/service-eink/internal/StaticData.hpp => module-services/service-eink/internal/StaticData.hpp +31 -0
@@ 0,0 1,31 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

namespace service::eink::internal
{
    /**
     * @brief Static settings data
     */
    class StaticData
    {
      public:
        StaticData(const StaticData &) = delete;
        StaticData &operator=(const StaticData &) = delete;

        /**
         * Gets instance of static data object
         * @return instance of data object
         */
        static StaticData &get();

        void setInvertedMode(bool enabled) noexcept;
        [[nodiscard]] auto isInvertedModeEnabled() const noexcept -> bool;

      private:
        bool invertedEnabled{false};

        StaticData() noexcept = default;
    };
} // namespace service::eink::internal

M module-services/service-eink/messages/EinkModeMessage.hpp => module-services/service-eink/messages/EinkModeMessage.hpp +5 -0
@@ 27,4 27,9 @@ namespace service::eink
      private:
        Mode mode = Mode::Normal;
    };

    class EinkModeResponse : public sys::ResponseMessage
    {
        using sys::ResponseMessage::ResponseMessage;
    };
} // namespace seink