From bb59805a8edfcd2c89aa369bf34c519dc840e4c3 Mon Sep 17 00:00:00 2001 From: Maciej Janicki Date: Fri, 8 Jan 2021 15:36:31 +0100 Subject: [PATCH] [EGD-4822] Add color test window to settings app Add new window to allow convenient display and globally change used color intensities for design and testing purposes. Changes were introduced to Renderer as well as GUI service to allow global change of used color scheme. When using list, screen is deep refreshed each time the color is changed. Known issues: Item focus borders (top,bottom) with changed black intensity may not render properly, however it doesn't obscure the target functionality. --- image/assets/lang/English.json | 2 + .../ApplicationSettings.cpp | 5 +- .../application-settings/CMakeLists.txt | 4 + .../models/ColorTestModel.cpp | 60 +++++++++++++ .../models/ColorTestModel.hpp | 30 +++++++ .../widgets/ColorTestListItem.cpp | 72 +++++++++++++++ .../widgets/ColorTestListItem.hpp | 31 +++++++ .../widgets/ColorTestListStyle.hpp | 36 ++++++++ .../widgets/ColorTestListView.cpp | 38 ++++++++ .../widgets/ColorTestListView.hpp | 26 ++++++ .../windows/ColorTestWindow.cpp | 90 +++++++++++++++++++ .../windows/ColorTestWindow.hpp | 40 +++++++++ .../windows/SettingsMainWindow.cpp | 2 + module-gui/gui/core/Color.hpp | 24 +++++ module-gui/gui/core/Renderer.cpp | 8 ++ module-gui/gui/core/Renderer.hpp | 1 + .../gui/core/renderers/PixelRenderer.cpp | 15 +++- .../gui/core/renderers/PixelRenderer.hpp | 7 ++ .../gui/core/renderers/RectangleRenderer.cpp | 5 +- module-services/service-gui/ServiceGUI.cpp | 18 ++++ module-services/service-gui/ServiceGUI.hpp | 3 + module-services/service-gui/WorkerGUI.cpp | 18 +++- module-services/service-gui/WorkerGUI.hpp | 6 +- .../messages/ChangeColorScheme.hpp | 26 ++++++ 24 files changed, 559 insertions(+), 8 deletions(-) create mode 100644 module-apps/application-settings/models/ColorTestModel.cpp create mode 100644 module-apps/application-settings/models/ColorTestModel.hpp create mode 100644 module-apps/application-settings/widgets/ColorTestListItem.cpp create mode 100644 module-apps/application-settings/widgets/ColorTestListItem.hpp create mode 100644 module-apps/application-settings/widgets/ColorTestListStyle.hpp create mode 100644 module-apps/application-settings/widgets/ColorTestListView.cpp create mode 100644 module-apps/application-settings/widgets/ColorTestListView.hpp create mode 100644 module-apps/application-settings/windows/ColorTestWindow.cpp create mode 100644 module-apps/application-settings/windows/ColorTestWindow.hpp create mode 100644 module-services/service-gui/messages/ChangeColorScheme.hpp diff --git a/image/assets/lang/English.json b/image/assets/lang/English.json index ecf9eaff8a9a36d8dcd2fd5bc34ba3bac3bb1534..c2d209859a7059c83a7515308364721141ad7a44 100644 --- a/image/assets/lang/English.json +++ b/image/assets/lang/English.json @@ -414,6 +414,8 @@ "app_settings_apn_authtype": "Authentication type", "app_settings_apn_apntype": "APN Type", "app_settings_apn_apnprotocol" : "APN Protocol", + "app_settings_title_color_test": "Display available colors", + "app_settings_toolbar_reset": "RESET", "app_phonebook_title_main": "Contacts", "app_phonebook_search_win_contacts": "Contacts", "common_search_uc": "Search", diff --git a/module-apps/application-settings/ApplicationSettings.cpp b/module-apps/application-settings/ApplicationSettings.cpp index c149bd1ba6d458bb34cb19d5d15dadb51ed33bc3..5e339b02075804ff8f15461f14b24afdca6959b5 100644 --- a/module-apps/application-settings/ApplicationSettings.cpp +++ b/module-apps/application-settings/ApplicationSettings.cpp @@ -12,6 +12,7 @@ #include "windows/Info.hpp" #include "windows/LanguageWindow.hpp" #include "windows/SettingsMainWindow.hpp" +#include "windows/ColorTestWindow.hpp" #include "windows/UITestWindow.hpp" @@ -149,10 +150,12 @@ namespace app windowsFactory.attach(gui::window::name::fota_window, [](Application *app, const std::string &name) { return std::make_unique(app); }); - windowsFactory.attach(gui::window::name::eink, [](Application *app, const std::string &name) { return std::make_unique(app); }); + windowsFactory.attach(gui::window::name::color_test_window, [](Application *app, const std::string &name) { + return std::make_unique(app); + }); if (board == bsp::Board::T4) { windowsFactory.attach(gui::window::cellular_passthrough::window_name, diff --git a/module-apps/application-settings/CMakeLists.txt b/module-apps/application-settings/CMakeLists.txt index a35baa9145d8a61a9b4c012825348c463806f802..664ea09bacbde836900dfcc8c19aa3854628482c 100644 --- a/module-apps/application-settings/CMakeLists.txt +++ b/module-apps/application-settings/CMakeLists.txt @@ -27,6 +27,10 @@ target_sources( ${PROJECT_NAME} windows/FotaWindow.cpp windows/Fota.cpp windows/EinkModeWindow.cpp + windows/ColorTestWindow.cpp + widgets/ColorTestListItem.cpp + widgets/ColorTestListView.cpp + models/ColorTestModel.cpp PUBLIC ApplicationSettings.hpp diff --git a/module-apps/application-settings/models/ColorTestModel.cpp b/module-apps/application-settings/models/ColorTestModel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8fbac520d98b1e5f8849ca05c64fb1f402f57fd1 --- /dev/null +++ b/module-apps/application-settings/models/ColorTestModel.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "application-settings/widgets/ColorTestListStyle.hpp" +#include "ColorTestModel.hpp" + +namespace gui +{ + + ColorTestModel::ColorTestModel(app::Application *app) : application{app} + { + createData(); + } + + auto ColorTestModel::requestRecordsCount() -> unsigned int + { + return internalData.size(); + } + + unsigned int ColorTestModel::getMinimalItemHeight() const + { + return style::colorTest::item::color::height; + } + + gui::ListItem *ColorTestModel::getItem(gui::Order order) + { + return getRecord(order); + } + + void ColorTestModel::requestRecords(const uint32_t offset, const uint32_t limit) + { + setupModel(offset, limit); + list->onProviderDataUpdate(); + } + + void ColorTestModel::createData() + { + internalData.clear(); + + for (Color color = gui::ColorFullBlack; color.intensity != (gui::ColorFullWhite.intensity + 1); + ++color.intensity) { + auto newColorListItem = new ColorTestListItem(application, color); + newColorListItem->deleteByList = false; + internalData.push_back(newColorListItem); + } + } + + gui::ColorScheme ColorTestModel::getColorScheme() + { + gui::ColorScheme scheme = gui::Color::defaultColorScheme; + int i = 0; + + for (auto const &item : internalData) { + scheme.intensity[i] = item->getColorIntensity(); + ++i; + } + + return scheme; + } +} // namespace gui diff --git a/module-apps/application-settings/models/ColorTestModel.hpp b/module-apps/application-settings/models/ColorTestModel.hpp new file mode 100644 index 0000000000000000000000000000000000000000..aa0776379471f9b45000cfb23f1285c1c099c1a6 --- /dev/null +++ b/module-apps/application-settings/models/ColorTestModel.hpp @@ -0,0 +1,30 @@ +// 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 "Application.hpp" +#include "InternalModel.hpp" +#include "module-apps/application-settings/widgets/ColorTestListItem.hpp" +#include +#include + +namespace gui +{ + class ColorTestModel : public app::InternalModel, public gui::ListItemProvider + { + private: + app::Application *application = nullptr; + + public: + explicit ColorTestModel(app::Application *app); + + [[nodiscard]] auto requestRecordsCount() -> unsigned int override; + [[nodiscard]] auto getMinimalItemHeight() const -> unsigned int override; + gui::ListItem *getItem(gui::Order order) override; + void requestRecords(const uint32_t offset, const uint32_t limit) override; + void createData(); + + [[nodiscard]] gui::ColorScheme getColorScheme(); + }; +} // namespace gui diff --git a/module-apps/application-settings/widgets/ColorTestListItem.cpp b/module-apps/application-settings/widgets/ColorTestListItem.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f2defc35ea8d445165f6721541c2db7c6b90d8ad --- /dev/null +++ b/module-apps/application-settings/widgets/ColorTestListItem.cpp @@ -0,0 +1,72 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include + +#include "ColorTestListStyle.hpp" +#include "ColorTestListItem.hpp" + +namespace gui +{ + + ColorTestListItem::ColorTestListItem(app::Application *app, const Color color) : app{app} + { + setMinimumSize(style::listview::item_width_with_scroll, style::colorTest::item::color::height); + setMargins(Margins(style::margins::very_big, 0, 0, 0)); + + vBox = new VBox(this, 0, 0, 0, 0); + vBox->setEdges(RectangleEdge::None); + vBox->setMinimumSize(style::colorTest::item::color::width, style::colorTest::listview::height); + vBox->setFillColor(color); + + colorLabel = new Label(vBox, 0, 0, 0, 0); + colorLabel->setEdges(gui::RectangleEdge::None); + colorLabel->setMinimumSize(style::colorTest::item::color::width, style::colorTest::item::color::height); + colorLabel->setAlignment(Alignment{gui::Alignment::Horizontal::Right, gui::Alignment::Vertical::Top}); + colorLabel->setText(std::to_string(color.intensity) + " "); + + if (color.intensity > ColorGrey.intensity) { + colorLabel->setTextColor(ColorFullBlack); + } + else { + colorLabel->setTextColor(ColorFullWhite); + } + } + + bool ColorTestListItem::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) + { + vBox->setPosition(0, 0); + vBox->setSize(newDim.w, newDim.h); + return true; + } + + bool ColorTestListItem::onInput(const InputEvent &inputEvent) + { + bool handled = false; + + if (inputEvent.isShortPress()) { + if (inputEvent.is(KeyCode::KEY_LEFT)) { + if (auto color = vBox->fillColor; color.intensity != ::gui::ColorFullBlack.intensity) { + color.intensity--; + vBox->setFillColor(color); + app->refreshWindow(RefreshModes::GUI_REFRESH_DEEP); + } + handled = true; + } + else if (inputEvent.is(KeyCode::KEY_RIGHT)) { + if (auto color = vBox->fillColor; color.intensity != ::gui::ColorFullWhite.intensity) { + color.intensity++; + vBox->setFillColor(color); + app->refreshWindow(RefreshModes::GUI_REFRESH_DEEP); + } + handled = true; + } + } + return handled; + } + + uint8_t ColorTestListItem::getColorIntensity() + { + return vBox->fillColor.intensity; + } +} // namespace gui diff --git a/module-apps/application-settings/widgets/ColorTestListItem.hpp b/module-apps/application-settings/widgets/ColorTestListItem.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a469d097f4b9fc5240ba928154efbd0e918bbf1c --- /dev/null +++ b/module-apps/application-settings/widgets/ColorTestListItem.hpp @@ -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 + +#include + +#include +#include +#include +#include + +#include "Application.hpp" + +namespace gui +{ + class ColorTestListItem : public ListItem + { + private: + VBox *vBox = nullptr; + Label *colorLabel = nullptr; + app::Application *app; + + public: + explicit ColorTestListItem(app::Application *app, const Color color); + + bool onInput(const InputEvent &inputEvent) override; + bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) override; + [[nodiscard]] uint8_t getColorIntensity(); + }; +} /* namespace gui */ diff --git a/module-apps/application-settings/widgets/ColorTestListStyle.hpp b/module-apps/application-settings/widgets/ColorTestListStyle.hpp new file mode 100644 index 0000000000000000000000000000000000000000..889153e47e2e2fe1cc146ac1e98948fca2931d06 --- /dev/null +++ b/module-apps/application-settings/widgets/ColorTestListStyle.hpp @@ -0,0 +1,36 @@ +// 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 + +namespace style::colorTest +{ + namespace listview + { + inline constexpr auto x = style::window::default_left_margin; + inline constexpr auto y = style::header::height; + inline constexpr auto width = style::listview::body_width_with_scroll; + inline constexpr auto height = style::window_height - y - style::footer::height; + } // namespace listview + + namespace item + { + namespace label + { + inline constexpr auto height = 30; + inline constexpr auto width = style::listview::item_width_with_scroll; + inline constexpr auto bottomMargin = 4; + inline constexpr auto leftMargin = 10; + } // namespace label + + namespace color + { + inline constexpr auto height = listview::height - label::height; + inline constexpr auto width = style::listview::item_width_with_scroll; + inline constexpr auto bottomMargin = 4; + inline constexpr auto leftMargin = 10; + } // namespace color + } // namespace item +} // namespace style::colorTest diff --git a/module-apps/application-settings/widgets/ColorTestListView.cpp b/module-apps/application-settings/widgets/ColorTestListView.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f152c8c1dc2d57022886c7a76d35a08a7140acf0 --- /dev/null +++ b/module-apps/application-settings/widgets/ColorTestListView.cpp @@ -0,0 +1,38 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "ColorTestListView.hpp" +#include "InputEvent.hpp" + +namespace gui +{ + ColorTestListView::ColorTestListView(app::Application *application, + Item *parent, + uint32_t x, + uint32_t y, + uint32_t w, + uint32_t h, + std::shared_ptr prov, + style::listview::ScrollBarType scrollBarType) + : ListView(parent, x, y, w, h, prov, scrollBarType), app{application} + { + body->borderCallback = [this](const InputEvent &inputEvent) -> bool { + if (inputEvent.state != InputEvent::State::keyReleasedShort) { + return false; + } + if (inputEvent.keyCode == KeyCode::KEY_UP && pageLoaded) { + auto result = this->requestPreviousPage(); + app->refreshWindow(RefreshModes::GUI_REFRESH_DEEP); + return result; + } + else if (inputEvent.keyCode == KeyCode::KEY_DOWN && pageLoaded) { + auto result = this->requestNextPage(); + app->refreshWindow(RefreshModes::GUI_REFRESH_DEEP); + return result; + } + else { + return false; + } + }; + } +} // namespace gui diff --git a/module-apps/application-settings/widgets/ColorTestListView.hpp b/module-apps/application-settings/widgets/ColorTestListView.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ee46a1c12b2343bdabc9c110580e8d717366cfe4 --- /dev/null +++ b/module-apps/application-settings/widgets/ColorTestListView.hpp @@ -0,0 +1,26 @@ +// 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 "ListView.hpp" +#include "Application.hpp" + +namespace gui +{ + class ColorTestListView : public ListView + { + private: + app::Application *app; + + public: + ColorTestListView(app::Application *application, + Item *parent, + uint32_t x, + uint32_t y, + uint32_t w, + uint32_t h, + std::shared_ptr prov, + style::listview::ScrollBarType scrollType = style::listview::ScrollBarType::Proportional); + }; +} // namespace gui diff --git a/module-apps/application-settings/windows/ColorTestWindow.cpp b/module-apps/application-settings/windows/ColorTestWindow.cpp new file mode 100644 index 0000000000000000000000000000000000000000..819660583956e0faab5f65eb052a12af54ad4be3 --- /dev/null +++ b/module-apps/application-settings/windows/ColorTestWindow.cpp @@ -0,0 +1,90 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include + +#include +#include +#include +#include + +#include "application-settings/ApplicationSettings.hpp" +#include "application-settings/widgets/ColorTestListStyle.hpp" +#include "ColorTestWindow.hpp" + +namespace gui +{ + static gui::ColorScheme currentColorScheme = gui::Color::defaultColorScheme; + + ColorTestWindow::ColorTestWindow(app::Application *app) + : AppWindow{app, window::name::color_test_window}, colorTestModel{std::make_shared(app)} + { + buildInterface(); + } + + void ColorTestWindow::buildInterface() + { + AppWindow::buildInterface(); + + setTitle(utils::localize.get("app_settings_title_color_test")); + + colorListView = new ColorTestListView(application, + this, + style::colorTest::listview::x, + style::colorTest::listview::y, + style::colorTest::listview::width, + style::colorTest::listview::height, + colorTestModel); + + colorListView->rebuildList(); + + bottomBar->setActive(BottomBar::Side::LEFT, true); + bottomBar->setText(BottomBar::Side::LEFT, utils::localize.get("app_settings_toolbar_reset")); + bottomBar->setActive(BottomBar::Side::CENTER, true); + bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::save)); + bottomBar->setActive(BottomBar::Side::RIGHT, true); + bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back)); + + applyInputCallback(); + + setFocusItem(colorListView); + } + + void ColorTestWindow::applyInputCallback() + { + this->inputCallback = [&](Item &item, const InputEvent &event) -> bool { + if (event.isShortPress()) { + if (event.is(KeyCode::KEY_ENTER)) { + setGlobalColorScheme(colorTestModel->getColorScheme()); + return true; + } + else if (event.is(KeyCode::KEY_LF)) { + resetGlobalColorScheme(); + return true; + } + } + return false; + }; + } + + void ColorTestWindow::resetGlobalColorScheme() + { + colorTestModel->createData(); + colorListView->rebuildList(); + setGlobalColorScheme(gui::Color::defaultColorScheme); + } + + void ColorTestWindow::setGlobalColorScheme(const ColorScheme &scheme) + { + if (scheme != currentColorScheme) { + currentColorScheme = scheme; + sys::Bus::SendUnicast(std::make_shared(std::move(scheme)), + service::name::gui, + this->application, + 100); + LOG_INFO("Updated color scheme"); + + application->refreshWindow(RefreshModes::GUI_REFRESH_DEEP); + } + } +} /* namespace gui */ diff --git a/module-apps/application-settings/windows/ColorTestWindow.hpp b/module-apps/application-settings/windows/ColorTestWindow.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d0f9c58b41965213c767a4be7d823f59e661e1c2 --- /dev/null +++ b/module-apps/application-settings/windows/ColorTestWindow.hpp @@ -0,0 +1,40 @@ +// 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 +#include + +#include "module-apps/application-settings/models/ColorTestModel.hpp" +#include "AppWindow.hpp" +#include "application-settings/widgets/ColorTestListView.hpp" + +#include +#include +#include +#include +#include + +namespace gui +{ + namespace window::name + { + inline constexpr auto color_test_window = "ColorTestWindow"; + } // namespace window::name + + class ColorTestWindow : public AppWindow + { + private: + std::shared_ptr colorTestModel = nullptr; + gui::ColorTestListView *colorListView = nullptr; + + public: + explicit ColorTestWindow(app::Application *app); + + void applyInputCallback(); + void buildInterface() override; + void setGlobalColorScheme(const ColorScheme &scheme); + void resetGlobalColorScheme(); + }; +} /* namespace gui */ diff --git a/module-apps/application-settings/windows/SettingsMainWindow.cpp b/module-apps/application-settings/windows/SettingsMainWindow.cpp index 9b0174f6bb7eb016e9e885952c5aabc5e78117fe..078941833cab24014fe0e5111a17ebf94c39d35c 100644 --- a/module-apps/application-settings/windows/SettingsMainWindow.cpp +++ b/module-apps/application-settings/windows/SettingsMainWindow.cpp @@ -9,6 +9,7 @@ #include "CellularPassthroughWindow.hpp" #include "FotaWindow.hpp" #include "EinkModeWindow.hpp" +#include "ColorTestWindow.hpp" std::list mainWindowOptions(app::Application *app) { @@ -40,6 +41,7 @@ std::list mainWindowOptions(app::Application *app) } addMenu(i18("Fota update"), gui::window::name::fota_window); addMenu("Eink Mode", gui::window::name::eink); + addMenu(i18("Color test"), gui::window::name::color_test_window); addMenu(i18("app_settings_display")); addMenu(i18("app_settings_phone_modes")); addMenu(i18("app_settings_security")); diff --git a/module-gui/gui/core/Color.hpp b/module-gui/gui/core/Color.hpp index 3cb45276153e38385f698c38db966d49b7bb0226..ec27676cd42519d3c4a43aeabdd77d39a2d4c1ff 100644 --- a/module-gui/gui/core/Color.hpp +++ b/module-gui/gui/core/Color.hpp @@ -4,9 +4,16 @@ #pragma once #include +#include namespace gui { + struct ColorScheme + { + static constexpr inline std::uint8_t numberOfColors = 16; + std::array intensity; + }; + struct Color { constexpr Color() noexcept = default; @@ -22,6 +29,8 @@ namespace gui static constexpr inline std::uint8_t Black = 0x0U; static constexpr inline std::uint8_t FullTransparent = 0x0FU; static constexpr inline std::uint8_t Opaque = 0x0U; + + static constexpr inline ColorScheme defaultColorScheme{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; }; inline bool operator==(const Color &r, const Color &l) noexcept @@ -29,11 +38,26 @@ namespace gui return r.intensity == l.intensity && r.alpha == l.alpha; } + inline bool operator==(const ColorScheme &r, const ColorScheme &l) noexcept + { + for (int i = 0; i < ColorScheme::numberOfColors; ++i) { + if (r.intensity[i] != l.intensity[i]) { + return false; + } + } + return true; + } + inline bool operator!=(const Color &r, const Color &l) noexcept { return !operator==(r, l); } + inline bool operator!=(const ColorScheme &r, const ColorScheme &l) noexcept + { + return !operator==(r, l); + } + static inline constexpr Color ColorFullBlack{Color::Black, Color::Opaque}; static inline constexpr Color ColorFullWhite{Color::White, Color::Opaque}; static inline constexpr Color ColorNoColor{Color::White, Color::FullTransparent}; diff --git a/module-gui/gui/core/Renderer.cpp b/module-gui/gui/core/Renderer.cpp index 45f0b6156a07092353696891277c766fdbec2daa..05773a63aba1a91004949467ab6e490467c4f81d 100644 --- a/module-gui/gui/core/Renderer.cpp +++ b/module-gui/gui/core/Renderer.cpp @@ -5,8 +5,16 @@ #include "Renderer.hpp" #include "Context.hpp" +// renderer +#include "renderers/PixelRenderer.hpp" + namespace gui { + void Renderer::changeColorScheme(const std::unique_ptr &scheme) + { + renderer::PixelRenderer::updateColorScheme(scheme); + } + void Renderer::render(Context *ctx, std::list> &commands) { if (ctx == nullptr) { diff --git a/module-gui/gui/core/Renderer.hpp b/module-gui/gui/core/Renderer.hpp index 539ccf9fc56e97dbe3d9ead79929687045324993..e5d70f7c90a7f61c5c5c6113ce6b28a39bd206c9 100644 --- a/module-gui/gui/core/Renderer.hpp +++ b/module-gui/gui/core/Renderer.hpp @@ -37,6 +37,7 @@ namespace gui virtual ~Renderer() = default; void render(Context *ctx, std::list> &commands); + void changeColorScheme(const std::unique_ptr &scheme); }; } /* namespace gui */ diff --git a/module-gui/gui/core/renderers/PixelRenderer.cpp b/module-gui/gui/core/renderers/PixelRenderer.cpp index 47cd8511c5e8bd7b5f92be71135624f4dcbfa147..6be85f67b7bfeca4367fb5a2e07af2bfcdcbe09f 100644 --- a/module-gui/gui/core/renderers/PixelRenderer.cpp +++ b/module-gui/gui/core/renderers/PixelRenderer.cpp @@ -8,10 +8,23 @@ namespace gui::renderer { + static ColorScheme colorScheme = ::gui::Color::defaultColorScheme; + void PixelRenderer::draw(Context *ctx, Point point, Color color) { const auto contextWidth = ctx->getW(); const auto position = point.y * contextWidth + point.x; - std::memset(ctx->getData() + position, color.intensity, 1); + + std::memset(ctx->getData() + position, colorScheme.intensity[color.intensity], 1); + } + + void PixelRenderer::updateColorScheme(const std::unique_ptr &scheme) + { + colorScheme = *scheme; + } + + auto PixelRenderer::getColor(const uint8_t intensity) -> uint8_t + { + return colorScheme.intensity[intensity]; } } // namespace gui::renderer diff --git a/module-gui/gui/core/renderers/PixelRenderer.hpp b/module-gui/gui/core/renderers/PixelRenderer.hpp index ea685e033b55dd44389f11d8ca9626bce225be62..37f818cb2faf82ab0ea0651ea6151d48960b6c31 100644 --- a/module-gui/gui/core/renderers/PixelRenderer.hpp +++ b/module-gui/gui/core/renderers/PixelRenderer.hpp @@ -6,6 +6,8 @@ #include "Color.hpp" #include "Common.hpp" +#include + namespace gui { class Context; @@ -15,7 +17,12 @@ namespace gui::renderer { class PixelRenderer { + public: + PixelRenderer() = delete; + static void draw(Context *ctx, Point point, Color color); + static void updateColorScheme(const std::unique_ptr &scheme); + [[nodiscard]] static auto getColor(const uint8_t intensity) -> uint8_t; }; } // namespace gui::renderer diff --git a/module-gui/gui/core/renderers/RectangleRenderer.cpp b/module-gui/gui/core/renderers/RectangleRenderer.cpp index 8cc761571712c9508b2448b3211f123f8f405d3a..6cd739856ffd3728e5ad79482e452854a0779ecb 100644 --- a/module-gui/gui/core/renderers/RectangleRenderer.cpp +++ b/module-gui/gui/core/renderers/RectangleRenderer.cpp @@ -183,8 +183,9 @@ namespace gui::renderer while (!q.empty()) { const auto currPoint = q.front(); q.pop(); - if (const auto color = getPixelColor(ctx, currPoint, borderColor.intensity); - color == borderColor.intensity || color == fillColor.intensity) { + if (const auto color = getPixelColor(ctx, currPoint, PixelRenderer::getColor(borderColor.intensity)); + color == PixelRenderer::getColor(borderColor.intensity) || + color == PixelRenderer::getColor(fillColor.intensity)) { continue; } diff --git a/module-services/service-gui/ServiceGUI.cpp b/module-services/service-gui/ServiceGUI.cpp index 0f6980f60a5af116d116b7a7295f1b5eab826721..b3d8dee17cd75a7d8a2c896b0953d9cf36ac85fd 100644 --- a/module-services/service-gui/ServiceGUI.cpp +++ b/module-services/service-gui/ServiceGUI.cpp @@ -5,7 +5,9 @@ #include "WorkerGUI.hpp" #include "messages/DrawMessage.hpp" + #include "messages/EinkInitialized.hpp" +#include "messages/ChangeColorScheme.hpp" #include #include @@ -63,6 +65,9 @@ namespace service::gui connect(typeid(RenderingFinished), [this](sys::Message *request) -> sys::MessagePointer { return handleGUIRenderingFinished(request); }); + connect(typeid(ChangeColorScheme), + [this](sys::Message *request) -> sys::MessagePointer { return handleChangeColorScheme(request); }); + connect(typeid(eink::ImageDisplayedNotification), [this](sys::Message *request) -> sys::MessagePointer { return handleImageDisplayedNotification(request); }); @@ -129,6 +134,13 @@ namespace service::gui return sys::MessageNone{}; } + sys::MessagePointer ServiceGUI::handleChangeColorScheme(sys::Message *message) + { + const auto msg = static_cast(message); + notifyRenderColorSchemeChange(msg->getColorScheme()); + return sys::MessageNone{}; + } + void ServiceGUI::prepareDisplayEarly(::gui::RefreshModes refreshMode) { auto msg = std::make_shared(refreshMode); @@ -142,6 +154,12 @@ namespace service::gui worker->notify(WorkerGUI::Signal::Render); } + void ServiceGUI::notifyRenderColorSchemeChange(::gui::ColorScheme &&scheme) + { + colorSchemeUpdate = std::make_unique<::gui::ColorScheme>(scheme); + worker->notify(WorkerGUI::Signal::ChangeColorScheme); + } + void ServiceGUI::enqueueDrawCommands(DrawCommandsQueue::QueueItem &&item) { // Clear all queue elements for now to keep only the latest command in the queue. diff --git a/module-services/service-gui/ServiceGUI.hpp b/module-services/service-gui/ServiceGUI.hpp index 2e58ad64ee8c2855128b1e2b70ed4f3e182b6a93..9ae45645534235d401ff198c56df4410571c6506 100644 --- a/module-services/service-gui/ServiceGUI.hpp +++ b/module-services/service-gui/ServiceGUI.hpp @@ -63,6 +63,7 @@ namespace service::gui void prepareDisplayEarly(::gui::RefreshModes refreshMode); void notifyRenderer(std::list> &&commands, ::gui::RefreshModes refreshMode); + void notifyRenderColorSchemeChange(::gui::ColorScheme &&scheme); void enqueueDrawCommands(DrawCommandsQueue::QueueItem &&item); void sendOnDisplay(::gui::Context *context, int contextId, ::gui::RefreshModes refreshMode); void scheduleContextRelease(int contextId); @@ -76,10 +77,12 @@ namespace service::gui sys::MessagePointer handleGUIRenderingFinished(sys::Message *message); sys::MessagePointer handleEinkInitialized(sys::Message *message); sys::MessagePointer handleImageDisplayedNotification(sys::Message *message); + sys::MessagePointer handleChangeColorScheme(sys::Message *message); std::unique_ptr contextPool; std::unique_ptr worker; std::unique_ptr commandsQueue; + std::unique_ptr<::gui::ColorScheme> colorSchemeUpdate; std::optional cachedRender; std::unique_ptr contextReleaseTimer; State currentState; diff --git a/module-services/service-gui/WorkerGUI.cpp b/module-services/service-gui/WorkerGUI.cpp index 170c27b905c76a757962d7c1a57f20a54becc942..f33d5312aeabe416c9ef2c1edd0dc6d5bbc56b6d 100644 --- a/module-services/service-gui/WorkerGUI.cpp +++ b/module-services/service-gui/WorkerGUI.cpp @@ -38,19 +38,33 @@ namespace service::gui void WorkerGUI::handleCommand(Signal command) { - if (command == Signal::Render) { + switch (command) { + case Signal::Render: { auto item = guiService->commandsQueue->dequeue(); render(item.commands, item.refreshMode); + break; + } + case Signal::ChangeColorScheme: { + changeColorScheme(guiService->colorSchemeUpdate); + break; + } + default: + LOG_ERROR("Command not valid."); } } - void WorkerGUI::render(std::list> &commands, ::gui::RefreshModes refreshMode) + void WorkerGUI::render(DrawCommandsQueue::CommandList &commands, ::gui::RefreshModes refreshMode) { const auto [contextId, context] = guiService->contextPool->borrowContext(); // Waits for the context. renderer.render(context, commands); onRenderingFinished(contextId, refreshMode); } + void WorkerGUI::changeColorScheme(const std::unique_ptr<::gui::ColorScheme> &scheme) + { + renderer.changeColorScheme(scheme); + } + void WorkerGUI::onRenderingFinished(int contextId, ::gui::RefreshModes refreshMode) { auto msg = std::make_shared(contextId, refreshMode); diff --git a/module-services/service-gui/WorkerGUI.hpp b/module-services/service-gui/WorkerGUI.hpp index 32aff1c7118fc4b083838cd647411e94ad589d6d..90dcd48bc576f826728b4d7f8acbca7ad3e54d41 100644 --- a/module-services/service-gui/WorkerGUI.hpp +++ b/module-services/service-gui/WorkerGUI.hpp @@ -21,7 +21,8 @@ namespace service::gui public: enum class Signal { - Render + Render, + ChangeColorScheme, }; static constexpr auto SignallingQueueName = "SignallingQueue"; static constexpr auto SignallingQueueCapacity = 1; @@ -34,7 +35,8 @@ namespace service::gui private: void handleCommand(Signal command); - void render(std::list> &commands, ::gui::RefreshModes refreshMode); + void render(DrawCommandsQueue::CommandList &commands, ::gui::RefreshModes refreshMode); + void changeColorScheme(const std::unique_ptr<::gui::ColorScheme> &scheme); void onRenderingFinished(int contextId, ::gui::RefreshModes refreshMode); ServiceGUI *guiService; diff --git a/module-services/service-gui/messages/ChangeColorScheme.hpp b/module-services/service-gui/messages/ChangeColorScheme.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b86ff555f1be8e52e026a48d621e8cedee5ec45c --- /dev/null +++ b/module-services/service-gui/messages/ChangeColorScheme.hpp @@ -0,0 +1,26 @@ +// 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 "GUIMessage.hpp" + +#include + +namespace service::gui +{ + class ChangeColorScheme : public GUIMessage + { + public: + explicit ChangeColorScheme(::gui::ColorScheme colorScheme) : scheme{colorScheme} + {} + + [[nodiscard]] auto getColorScheme() const noexcept -> ::gui::ColorScheme + { + return scheme; + } + + private: + ::gui::ColorScheme scheme; + }; +} // namespace service::gui