M changelog.md => changelog.md +1 -0
@@ 15,6 15,7 @@
### Changed
* `[appmgr]` Application manager refactored.
+* `[GUI]` added dark mode switch
### Fixed
M module-apps/application-settings/ApplicationSettings.cpp => module-apps/application-settings/ApplicationSettings.cpp +5 -0
@@ 4,6 4,7 @@
#include "Application.hpp"
#include "MessageType.hpp"
+#include "application-settings/windows/EinkModeWindow.hpp"
#include "windows/BtScanWindow.hpp"
#include "windows/BtWindow.hpp"
#include "windows/DateTimeWindow.hpp"
@@ 148,6 149,10 @@ namespace app
return std::make_unique<gui::FotaWindow>(app);
});
+ windowsFactory.attach(gui::window::name::eink, [](Application *app, const std::string &name) {
+ return std::make_unique<gui::EinkModeWindow>(app);
+ });
+
if (board == bsp::Board::T4) {
windowsFactory.attach(gui::window::cellular_passthrough::window_name,
[](Application *app, const std::string &name) {
M module-apps/application-settings/CMakeLists.txt => module-apps/application-settings/CMakeLists.txt +2 -1
@@ 28,7 28,8 @@ target_sources( ${PROJECT_NAME}
windows/FotaWindow.cpp
windows/Fota.cpp
windows/SettingsChange.cpp
- windows/USSDWindow.cpp
+ windows/USSDWindow.cpp
+ windows/EinkModeWindow.cpp
PUBLIC
ApplicationSettings.hpp
A module-apps/application-settings/windows/EinkModeWindow.cpp => module-apps/application-settings/windows/EinkModeWindow.cpp +50 -0
@@ 0,0 1,50 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <memory>
+#include <functional>
+
+#include "messages/EinkModeMessage.hpp"
+#include "service-appmgr/Controller.hpp"
+
+#include "../ApplicationSettings.hpp"
+
+#include "i18/i18.hpp"
+
+#include "Label.hpp"
+#include "Margins.hpp"
+#include "EinkModeWindow.hpp"
+#include <Style.hpp>
+
+namespace gui
+{
+
+ EinkModeWindow::EinkModeWindow(app::Application *app) : AppWindow(app, window::name::eink)
+ {
+ AppWindow::buildInterface();
+ bottomBar->setActive(BottomBar::Side::CENTER, true);
+ bottomBar->setActive(BottomBar::Side::RIGHT, true);
+ bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
+ bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
+ topBar->setActive(TopBar::Elements::SIGNAL, true);
+ topBar->setActive(TopBar::Elements::BATTERY, true);
+
+ setTitle("Change eink mode");
+ auto label = new Label(this, 100, 200, 300, 50, "Change mode on click");
+ label->activatedCallback = [this](Item &) -> bool {
+ static auto last_mode = seink::EinkModeMessage::Mode::Normal;
+ if (last_mode == seink::EinkModeMessage::Mode::Normal) {
+ last_mode = seink::EinkModeMessage::Mode::Invert;
+ }
+ else {
+ last_mode = seink::EinkModeMessage::Mode::Normal;
+ }
+
+ sys::Bus::SendUnicast(
+ std::make_shared<seink::EinkModeMessage>(last_mode), "ServiceEink", this->application, 5000);
+ return true;
+ };
+ setFocusItem(label);
+ }
+
+} /* namespace gui */
A module-apps/application-settings/windows/EinkModeWindow.hpp => module-apps/application-settings/windows/EinkModeWindow.hpp +27 -0
@@ 0,0 1,27 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+#pragma once
+
+#include <string>
+#include <functional>
+
+#include "AppWindow.hpp"
+#include "gui/widgets/Label.hpp"
+#include "gui/widgets/Image.hpp"
+#include "gui/widgets/Window.hpp"
+#include "gui/widgets/BottomBar.hpp"
+#include "gui/widgets/TopBar.hpp"
+
+namespace gui
+{
+ namespace window::name
+ {
+ inline const std::string eink = "EinkModeWindow";
+ } // namespace window::name
+
+ class EinkModeWindow : public AppWindow
+ {
+ public:
+ explicit EinkModeWindow(app::Application *app);
+ };
+} /* namespace gui */
M module-apps/application-settings/windows/SettingsMainWindow.cpp => module-apps/application-settings/windows/SettingsMainWindow.cpp +2 -0
@@ 9,6 9,7 @@
#include "CellularPassthroughWindow.hpp"
#include "FotaWindow.hpp"
#include "USSDWindow.hpp"
+#include "EinkModeWindow.hpp"
std::list<gui::Option> mainWindowOptions(app::Application *app)
{
@@ 40,6 41,7 @@ std::list<gui::Option> mainWindowOptions(app::Application *app)
}
addMenu(i18("Fota update"), gui::window::name::fota_window);
addMenu(i18("USSD test"), gui::window::name::ussd_window);
+ addMenu("Eink Mode", gui::window::name::eink);
addMenu(i18("app_settings_display"));
addMenu(i18("app_settings_phone_modes"));
addMenu(i18("app_settings_security"));
M module-services/service-eink/ServiceEink.cpp => module-services/service-eink/ServiceEink.cpp +18 -11
@@ 2,6 2,8 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ServiceEink.hpp"
+#include "messages/EinkModeMessage.hpp"
+#include <time/ScopedTime.hpp>
#include <log/log.hpp>
#include <messages/EinkMessage.hpp>
@@ 26,14 28,22 @@ enum class EinkWorkerCommands
};
ServiceEink::ServiceEink(const std::string &name, std::string parent)
- : sys::Service(name, parent, 4096 + 1024), timerID{0}, selfRefereshTriggerCount{0},
- temperatureMeasurementTriggerCount{0}, powerOffTriggerCount{0},
- powerOffTimer("PwrOffTimer", this, 3000, sys::Timer::Type::SingleShot)
+ : sys::Service(name, parent, 4096 + 1024), selfRefereshTriggerCount{0}, temperatureMeasurementTriggerCount{0},
+ powerOffTriggerCount{0}, powerOffTimer("PwrOffTimer", this, 3000, sys::Timer::Type::SingleShot)
{
// initialize initial eink parameters
memset(&waveformSettings, 0, sizeof(EinkWaveFormSettings_t));
waveformSettings.mode = EinkWaveformGC16;
waveformSettings.temperature = -1000;
+
+ connect(typeid(seink::EinkModeMessage),
+ [this](sys::DataMessage *message, sys::ResponseMessage *) -> sys::Message_t {
+ auto msg = static_cast<seink::EinkModeMessage *>(message);
+ this->displayMode = msg->getMode() == seink::EinkModeMessage::Mode::Normal
+ ? EinkDisplayColorMode_e::EinkDisplayColorModeStandard
+ : EinkDisplayColorMode_e::EinkDisplayColorModeInverted;
+ return sys::Message_t();
+ });
}
ServiceEink::~ServiceEink()
@@ 73,9 83,7 @@ sys::Message_t ServiceEink::DataReceivedHandler(sys::DataMessage *msgl, sys::Res
sys::Bus::SendUnicast(msg, this->GetName(), this);
} break;
case MessageType::EinkDMATransfer: {
-
- // LOG_INFO("[%s] EinkDMATransfer", GetName().c_str());
- // uint32_t start_tick = xTaskGetTickCount();
+ utils::time::Scoped scopedtimming("EinkDMATransfer");
if (suspended) {
if (suspendInProgress) {
@@ 101,7 109,7 @@ sys::Message_t ServiceEink::DataReceivedHandler(sys::DataMessage *msgl, sys::Res
changeWaveform(EinkWaveforms_e::EinkWaveformDU2, temperature);
}
- ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, EinkDisplayColorModeStandard);
+ ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, displayMode);
if (ret != EinkOK)
LOG_FATAL("Failed to update frame");
@@ 116,7 124,6 @@ sys::Message_t ServiceEink::DataReceivedHandler(sys::DataMessage *msgl, sys::Res
if (ret != EinkOK)
LOG_FATAL("Failed to refresh frame");
- // uint32_t end_tick = xTaskGetTickCount();
powerOffTimer.reload();
@@ 359,7 366,7 @@ bool ServiceEink::deepClearScreen(int8_t temperature)
EinkStatus_e ret;
memset(einkRenderBuffer, 15, 480 * 600);
- ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, EinkDisplayColorModeStandard);
+ ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, displayMode);
if (ret != EinkOK)
LOG_FATAL("Failed to update frame");
ret = EinkRefreshImage(0, 0, 480, 600, EinkDisplayTimingsFastRefreshMode);
@@ 368,7 375,7 @@ bool ServiceEink::deepClearScreen(int8_t temperature)
for (uint32_t i = 0; i < 2; i++) {
memset(einkRenderBuffer, 0, 480 * 600);
- ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, EinkDisplayColorModeStandard);
+ ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, displayMode);
if (ret != EinkOK)
LOG_FATAL("Failed to update frame");
ret = EinkRefreshImage(0, 0, 480, 600, EinkDisplayTimingsFastRefreshMode);
@@ 376,7 383,7 @@ bool ServiceEink::deepClearScreen(int8_t temperature)
LOG_FATAL("Failed to refresh frame");
memset(einkRenderBuffer, 15, 480 * 600);
- ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, EinkDisplayColorModeStandard);
+ ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, displayMode);
if (ret != EinkOK)
LOG_FATAL("Failed to update frame");
ret = EinkRefreshImage(0, 0, 480, 600, EinkDisplayTimingsFastRefreshMode);
M module-services/service-eink/ServiceEink.hpp => module-services/service-eink/ServiceEink.hpp +2 -3
@@ 15,9 15,6 @@
class ServiceEink : public sys::Service
{
protected:
- // this is timer that triggers 3 handlers - self refresh, temperature measurement and power off
- uint32_t timerID = 0;
-
// counts timer triggers from last self refresh
uint32_t selfRefereshTriggerCount;
// counts timer events from last temperature measurement
@@ 35,6 32,8 @@ class ServiceEink : public sys::Service
// structure with recently loaded waveformdata
EinkWaveFormSettings_t waveformSettings;
+ EinkDisplayColorMode_e displayMode = EinkDisplayColorMode_e::EinkDisplayColorModeStandard;
+
bool suspended = false;
bool suspendInProgress = false;
M module-services/service-eink/messages/EinkMessage.hpp => module-services/service-eink/messages/EinkMessage.hpp +0 -4
@@ 9,14 9,10 @@
namespace seink
{
- /*
- * @brief Template for all messages that go to gui service
- */
class EinkMessage : public sys::DataMessage
{
public:
EinkMessage(MessageType messageType) : sys::DataMessage(messageType){};
- virtual ~EinkMessage(){};
};
} /* namespace seink */
A module-services/service-eink/messages/EinkModeMessage.hpp => module-services/service-eink/messages/EinkModeMessage.hpp +29 -0
@@ 0,0 1,29 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "EinkMessage.hpp"
+
+namespace seink
+{
+ class EinkModeMessage : public EinkMessage
+ {
+ public:
+ enum class Mode
+ {
+ Normal,
+ Invert
+ };
+ EinkModeMessage(Mode mode) : EinkMessage(MessageType::EinkMessage), mode(mode)
+ {}
+
+ [[nodiscard]] auto getMode() const noexcept
+ {
+ return mode;
+ }
+
+ private:
+ Mode mode = Mode::Normal;
+ };
+} // namespace seink
M source/MessageType.hpp => source/MessageType.hpp +1 -0
@@ 9,6 9,7 @@ enum class MessageType
MessageTypeUninitialized = 0,
// eink messages
+ EinkMessage,
EinkStateRequest, ///< message is used to pull status of the eink. If eink is ready to display image
EinkImageData, ///< message with pointer to the image data for displaying
EinkDMATransfer, ///< this message is internally sent from wink service to eink service. This will trigger DMA