From 1f85954e988ebdff993dc60f943de0730b3ed83c Mon Sep 17 00:00:00 2001 From: jmsgrogan Date: Tue, 17 Jan 2023 13:01:59 +0000 Subject: [PATCH] Add initial token theming. --- .../notes_tk/audio_editor/AudioEditorView.cpp | 2 +- .../canvas/CanvasCommandSelectorView.cpp | 8 +- apps/notes_tk/canvas/CanvasView.cpp | 16 +- .../notes_tk/image_editor/ImageEditorView.cpp | 2 +- .../notes_tk/image_editor/ImageViewWidget.cpp | 7 +- apps/notes_tk/mesh_viewer/MeshViewerView.cpp | 9 +- apps/notes_tk/text_editor/TextEditorView.cpp | 8 +- apps/notes_tk/web_client/WebClientView.cpp | 2 +- src/base/core/Color.cpp | 20 +++ src/base/core/Color.h | 4 + src/ui/client/StatusBar.cpp | 4 +- src/ui/client/TabbedPanelWidget.cpp | 4 +- src/ui/client/TopBar.cpp | 6 +- src/ui/ui_controls/Button.cpp | 14 +- src/ui/ui_controls/Button.h | 4 +- src/ui/ui_controls/Label.cpp | 5 +- src/ui/ui_controls/TextBox.cpp | 7 +- src/ui/ui_elements/CMakeLists.txt | 9 +- src/ui/ui_elements/style/ColorPalette.cpp | 55 ++++++ src/ui/ui_elements/style/ColorPalette.h | 60 +++++++ src/ui/ui_elements/style/ITheme.h | 46 +++++ src/ui/ui_elements/style/LightTheme.cpp | 48 +++++ src/ui/ui_elements/style/LightTheme.h | 15 ++ src/ui/ui_elements/style/Theme.cpp | 26 --- src/ui/ui_elements/style/Theme.h | 169 +----------------- src/ui/ui_elements/style/ThemeManager.cpp | 17 ++ src/ui/ui_elements/style/ThemeManager.h | 12 ++ src/ui/ui_elements/ui_events/PaintEvent.cpp | 20 ++- src/ui/ui_elements/ui_events/PaintEvent.h | 14 +- src/ui/ui_elements/widgets/Widget.cpp | 15 +- src/ui/ui_elements/widgets/Widget.h | 9 +- src/ui/windows/managers/DesktopManager.cpp | 8 +- src/ui/windows/managers/DesktopManager.h | 12 +- .../ui_interfaces/win32/Win32Window.cpp | 2 +- 34 files changed, 406 insertions(+), 253 deletions(-) create mode 100644 src/ui/ui_elements/style/ColorPalette.cpp create mode 100644 src/ui/ui_elements/style/ColorPalette.h create mode 100644 src/ui/ui_elements/style/ITheme.h create mode 100644 src/ui/ui_elements/style/LightTheme.cpp create mode 100644 src/ui/ui_elements/style/LightTheme.h delete mode 100644 src/ui/ui_elements/style/Theme.cpp create mode 100644 src/ui/ui_elements/style/ThemeManager.cpp create mode 100644 src/ui/ui_elements/style/ThemeManager.h diff --git a/apps/notes_tk/audio_editor/AudioEditorView.cpp b/apps/notes_tk/audio_editor/AudioEditorView.cpp index ca3a964..1bd2cba 100644 --- a/apps/notes_tk/audio_editor/AudioEditorView.cpp +++ b/apps/notes_tk/audio_editor/AudioEditorView.cpp @@ -8,7 +8,7 @@ AudioEditorView::AudioEditorView() { auto label = Label::Create(); label->setLabel("audio Editor"); - label->setBackgroundColor(Theme::getBackgroundPrimary()); + label->setBackground(ThemeToken::SystemToken::Primary); label->setMargin(1); addWidget(std::move(label)); } diff --git a/apps/notes_tk/canvas/CanvasCommandSelectorView.cpp b/apps/notes_tk/canvas/CanvasCommandSelectorView.cpp index 78e1ca8..7f4b599 100644 --- a/apps/notes_tk/canvas/CanvasCommandSelectorView.cpp +++ b/apps/notes_tk/canvas/CanvasCommandSelectorView.cpp @@ -2,7 +2,9 @@ #include "HorizontalSpacer.h" #include "Button.h" -#include "Theme.h" + +#include "ThemeManager.h" +#include "PaintEvent.h" CanvasCommandSelectorView::CanvasCommandSelectorView() : Widget() @@ -13,7 +15,7 @@ CanvasCommandSelectorView::CanvasCommandSelectorView() onCommandSelected(CanvasDrawCommand::CIRCLE); }; circle_button->setLabel("Circle"); - circle_button->setBackgroundColor(Theme::getButtonPrimaryBackground()); + circle_button->setBackground(ThemeToken::SystemToken::Primary); circle_button->setMargin(2); circle_button->setOnClickFunction(on_circle_click); @@ -22,7 +24,7 @@ CanvasCommandSelectorView::CanvasCommandSelectorView() }; auto line_button = Button::Create(); line_button->setLabel("Line"); - line_button->setBackgroundColor(Theme::getButtonPrimaryBackground()); + line_button->setBackground(ThemeToken::SystemToken::Primary); line_button->setMargin(2); line_button->setOnClickFunction(on_line_click); diff --git a/apps/notes_tk/canvas/CanvasView.cpp b/apps/notes_tk/canvas/CanvasView.cpp index 47aa5ca..6ef3e0d 100644 --- a/apps/notes_tk/canvas/CanvasView.cpp +++ b/apps/notes_tk/canvas/CanvasView.cpp @@ -7,13 +7,15 @@ #include "CanvasDrawingArea.h" #include "CanvasCommandSelectorView.h" -#include "Theme.h" #include "TextNode.h" #include "GeometryNode.h" #include "Label.h" #include "Button.h" +#include "ThemeManager.h" +#include "PaintEvent.h" + CanvasView::CanvasView() : mController(CanvasController::Create()) { @@ -34,11 +36,11 @@ void CanvasView::initialize() { auto label = Label::Create(); label->setLabel("Canvas"); - label->setBackgroundColor(Theme::getBannerBackground()); + label->setBackground(ThemeToken::SystemToken::Secondary); label->setMargin(1); auto controls = std::make_unique(); - controls->setBackgroundColor(Theme::getBannerBackground()); + controls->setBackground(ThemeToken::SystemToken::Background); controls->setMargin(1); auto on_draw_command_changed = [this](CanvasDrawCommand command){ @@ -47,7 +49,7 @@ void CanvasView::initialize() controls->setCommandSelectedCallback(on_draw_command_changed); auto drawing_area = std::make_unique(); - drawing_area->setBackgroundColor(Theme::getBackgroundPrimary()); + drawing_area->setBackground(ThemeToken::SystemToken::Background); drawing_area->setMargin(1); mDrawingArea = drawing_area.get(); @@ -75,17 +77,17 @@ std::unique_ptr CanvasView::initializeCacheButtons() { auto saveButton = Button::Create(); saveButton->setLabel("Save"); - saveButton->setBackgroundColor(Theme::getButtonPrimaryBackground()); + saveButton->setBackground(ThemeToken::SystemToken::Primary); saveButton->setMargin(2); auto clearButton = Button::Create(); clearButton->setLabel("Clear"); - clearButton->setBackgroundColor(Theme::getButtonPrimaryBackground()); + clearButton->setBackground(ThemeToken::SystemToken::Primary); clearButton->setMargin(2); auto loadButton = Button::Create(); loadButton->setLabel("Load"); - loadButton->setBackgroundColor(Theme::getButtonPrimaryBackground()); + loadButton->setBackground(ThemeToken::SystemToken::Primary); loadButton->setMargin(2); auto buttonSpacer = VerticalSpacer::Create(); diff --git a/apps/notes_tk/image_editor/ImageEditorView.cpp b/apps/notes_tk/image_editor/ImageEditorView.cpp index 821c3f9..e97e026 100644 --- a/apps/notes_tk/image_editor/ImageEditorView.cpp +++ b/apps/notes_tk/image_editor/ImageEditorView.cpp @@ -12,7 +12,7 @@ ImageEditorView::ImageEditorView() { auto label = Label::Create(); label->setLabel("Image Editor"); - label->setBackgroundColor(Theme::getBackgroundPrimary()); + label->setBackground(ThemeToken::SystemToken::Primary); label->setMargin(1); auto image_widget = std::make_unique(); diff --git a/apps/notes_tk/image_editor/ImageViewWidget.cpp b/apps/notes_tk/image_editor/ImageViewWidget.cpp index 1bc24c8..e93b575 100644 --- a/apps/notes_tk/image_editor/ImageViewWidget.cpp +++ b/apps/notes_tk/image_editor/ImageViewWidget.cpp @@ -3,7 +3,8 @@ #include "GridNode.h" #include "TransformNode.h" -#include +#include "ThemeManager.h" +#include "PaintEvent.h" ImageViewWidget::ImageViewWidget() { @@ -27,7 +28,7 @@ void ImageViewWidget::doPaint(const PaintEvent* event) mGridNode->setWidth(mSize.mWidth); mGridNode->setHeight(mSize.mHeight); - mGridNode->setStrokeColor(mBorderColor); + mGridNode->setStrokeColor(event->getThemesManager()->getColor(mBorder)); mRootNode->addChild(mGridNode.get()); } @@ -41,6 +42,6 @@ void ImageViewWidget::doPaint(const PaintEvent* event) if (mMaterialDirty) { - mGridNode->setFillColor(mBorderColor); + mGridNode->setFillColor(event->getThemesManager()->getColor(mBorder)); } } diff --git a/apps/notes_tk/mesh_viewer/MeshViewerView.cpp b/apps/notes_tk/mesh_viewer/MeshViewerView.cpp index b82a70a..c466b62 100644 --- a/apps/notes_tk/mesh_viewer/MeshViewerView.cpp +++ b/apps/notes_tk/mesh_viewer/MeshViewerView.cpp @@ -5,6 +5,9 @@ #include "AbstractMesh.h" #include "MeshPrimitives.h" +#include "ThemeManager.h" +#include "PaintEvent.h" + #include std::unique_ptr MeshViewerView::Create() @@ -20,7 +23,7 @@ MeshViewerView::~MeshViewerView() MeshViewerView::MeshViewerView() { mName = "MeshViewerView"; - mBackgroundColor = {204, 204, 255}; + mBackground = ThemeToken::SystemToken::Background; } void MeshViewerView::doPaint(const PaintEvent* event) @@ -38,7 +41,7 @@ void MeshViewerView::doPaint(const PaintEvent* event) mMeshNode->setWidth(mSize.mWidth); mMeshNode->setHeight(mSize.mHeight); - mMeshNode->setFillColor(mBackgroundColor); + mMeshNode->setFillColor(event->getThemesManager()->getColor(mBackground)); mRootNode->addChild(mMeshNode.get()); } @@ -52,7 +55,7 @@ void MeshViewerView::doPaint(const PaintEvent* event) if (mMaterialDirty) { - mMeshNode->setFillColor(mBackgroundColor); + mMeshNode->setFillColor(event->getThemesManager()->getColor(mBackground)); } if (!mMesh) diff --git a/apps/notes_tk/text_editor/TextEditorView.cpp b/apps/notes_tk/text_editor/TextEditorView.cpp index c8aa141..d8d0465 100644 --- a/apps/notes_tk/text_editor/TextEditorView.cpp +++ b/apps/notes_tk/text_editor/TextEditorView.cpp @@ -25,7 +25,7 @@ void TextEditorView::initialize() { auto label = Label::Create(); label->setLabel("Text Editor"); - label->setBackgroundColor(Theme::getBannerBackground()); + label->setBackground(ThemeToken::SystemToken::Secondary); label->setMargin(1); auto textBox = TextBox::Create(); @@ -34,7 +34,7 @@ void TextEditorView::initialize() auto saveButton = Button::Create(); saveButton->setLabel("Save"); - saveButton->setBackgroundColor(Theme::getButtonPrimaryBackground()); + saveButton->setBackground(ThemeToken::SystemToken::Primary); saveButton->setMargin(2); auto onSave = [this](Widget* self){ if(this && mController && mTextBox) @@ -47,7 +47,7 @@ void TextEditorView::initialize() auto clearButton = Button::Create(); clearButton->setLabel("Clear"); - clearButton->setBackgroundColor(Theme::getButtonPrimaryBackground()); + clearButton->setBackground(ThemeToken::SystemToken::Primary); clearButton->setMargin(2); auto onClear = [this](Widget* self){ if(this && mController && mTextBox) @@ -60,7 +60,7 @@ void TextEditorView::initialize() auto loadButton = Button::Create(); loadButton->setLabel("Load"); - loadButton->setBackgroundColor(Theme::getButtonPrimaryBackground()); + loadButton->setBackground(ThemeToken::SystemToken::Primary); loadButton->setMargin(2); auto onLoad = [this](Widget* self){ if(this && mController && mTextBox) diff --git a/apps/notes_tk/web_client/WebClientView.cpp b/apps/notes_tk/web_client/WebClientView.cpp index 9dd6fea..58123bd 100644 --- a/apps/notes_tk/web_client/WebClientView.cpp +++ b/apps/notes_tk/web_client/WebClientView.cpp @@ -10,7 +10,7 @@ WebClientView::WebClientView() { auto label = Label::Create(); label->setLabel("Web Client"); - label->setBackgroundColor(Theme::getBackgroundPrimary()); + label->setBackground(ThemeToken::SystemToken::Secondary); label->setMargin(1); addWidget(std::move(label)); } diff --git a/src/base/core/Color.cpp b/src/base/core/Color.cpp index 244aafc..2fd35da 100644 --- a/src/base/core/Color.cpp +++ b/src/base/core/Color.cpp @@ -9,6 +9,26 @@ Color::Color(unsigned char r, unsigned char g, unsigned char b, double a) } +Color::Color(const std::string& hexString) +{ + if (hexString.size() < 7) + { + return; + } + if (hexString[0] != '#') + { + return; + } + mR = toDecimal(hexString.substr(1, 2)); + mG = toDecimal(hexString.substr(3, 2)); + mB = toDecimal(hexString.substr(5, 2)); +} + +unsigned char Color::toDecimal(const std::string& hex) const +{ + return static_cast(std::stoul("0x" + hex, nullptr, 16)); +} + std::unique_ptr Color::Create(unsigned char r, unsigned char g, unsigned char b, double a ) { return std::make_unique(r, g, b, a); diff --git a/src/base/core/Color.h b/src/base/core/Color.h index 411c048..1b6c8ef 100644 --- a/src/base/core/Color.h +++ b/src/base/core/Color.h @@ -7,6 +7,8 @@ class Color { public: + + Color(const std::string& hexString); Color(unsigned char r = 0, unsigned char g = 0, unsigned char b = 0, double a = 1.0); static std::unique_ptr Create(unsigned char r, unsigned char g, unsigned char b, double a = 1.0); @@ -37,6 +39,8 @@ public: } private: + unsigned char toDecimal(const std::string& hex) const; + unsigned char mR{0}; unsigned char mG{0}; unsigned char mB{0}; diff --git a/src/ui/client/StatusBar.cpp b/src/ui/client/StatusBar.cpp index eb3c625..1cb0e93 100644 --- a/src/ui/client/StatusBar.cpp +++ b/src/ui/client/StatusBar.cpp @@ -1,10 +1,10 @@ #include "StatusBar.h" -#include "Color.h" +#include "ITheme.h" StatusBar::StatusBar() { - setBackgroundColor(Color(200, 200, 200)); + setBackground(ThemeToken::SystemToken::Secondary); } std::unique_ptr StatusBar::Create() diff --git a/src/ui/client/TabbedPanelWidget.cpp b/src/ui/client/TabbedPanelWidget.cpp index 3a312cd..36d93df 100644 --- a/src/ui/client/TabbedPanelWidget.cpp +++ b/src/ui/client/TabbedPanelWidget.cpp @@ -5,6 +5,8 @@ #include "TextNode.h" #include "Button.h" +#include "Theme.h" + TabbedPanelWidget::TabbedPanelWidget() : mNavPanel(), mStack() @@ -36,7 +38,7 @@ void TabbedPanelWidget::addPanel(WidgetUPtr panel, const std::string& label) { auto button = Button::Create(); button->setLabel(label); - button->setBackgroundColor(Color(156, 156, 156)); + button->setBackground(ThemeToken::SystemToken::Primary); button->setMargin({1, 0, 0, 1}); auto rawPanel = panel.get(); diff --git a/src/ui/client/TopBar.cpp b/src/ui/client/TopBar.cpp index b746951..ce6b812 100644 --- a/src/ui/client/TopBar.cpp +++ b/src/ui/client/TopBar.cpp @@ -1,18 +1,18 @@ #include "TopBar.h" #include "Color.h" -#include "Theme.h" +#include "ITheme.h" #include "Button.h" #include "TopBarMenu.h" TopBar::TopBar() { - setBackgroundColor(Theme::getBackgroundPrimary()); + setBackground(ThemeToken::SystemToken::Secondary); auto fileButton = Button::Create(); fileButton->setLabel("File"); - fileButton->setBackgroundColor(Theme::getBackgroundPrimary()); + fileButton->setBackground(ThemeToken::SystemToken::Primary); fileButton->setMargin(2); fileButton->setMaxWidth(60); diff --git a/src/ui/ui_controls/Button.cpp b/src/ui/ui_controls/Button.cpp index 12923fd..c24ef07 100644 --- a/src/ui/ui_controls/Button.cpp +++ b/src/ui/ui_controls/Button.cpp @@ -3,6 +3,8 @@ #include "TextNode.h" #include "GeometryNode.h" #include "TransformNode.h" +#include "ThemeManager.h" +#include "PaintEvent.h" #include "MouseEvent.h" #include "FileLogger.h" @@ -10,8 +12,8 @@ Button::Button() : Widget(), mLabel(), - mCachedColor(255, 255, 255), - mClickedColor(Color(180, 180, 180)), + mCachedColor(ThemeToken::SystemToken::Primary), + mClickedColor(ThemeToken::SystemToken::Secondary), mClickFunc() { mName = "Button"; @@ -46,8 +48,8 @@ void Button::onMyMouseEvent(const MouseEvent* event) MLOG_INFO("Widget mouse event"); if(event->getAction() == MouseEvent::Action::Pressed) { - mCachedColor = mBackgroundColor; - setBackgroundColor(mClickedColor); + mCachedColor = mBackground; + setBackground(mClickedColor); if(mClickFunc) { mClickFunc(this); @@ -55,7 +57,7 @@ void Button::onMyMouseEvent(const MouseEvent* event) } else if(event->getAction() == MouseEvent::Action::Released) { - setBackgroundColor(mCachedColor); + setBackground(mCachedColor); } } @@ -94,7 +96,7 @@ void Button::updateLabel(const PaintEvent* event) if (mMaterialDirty) { - mTextNode->setFillColor(mBackgroundColor); + mTextNode->setFillColor(event->getThemesManager()->getColor(mBackground)); } if (mContentDirty) diff --git a/src/ui/ui_controls/Button.h b/src/ui/ui_controls/Button.h index 171746b..f8997bb 100644 --- a/src/ui/ui_controls/Button.h +++ b/src/ui/ui_controls/Button.h @@ -36,8 +36,8 @@ protected: private: std::string mLabel; clickFunc mClickFunc; - Color mCachedColor; - Color mClickedColor; + ThemeToken::SystemToken mCachedColor; + ThemeToken::SystemToken mClickedColor; std::unique_ptr mTextNode; bool mContentDirty{true}; diff --git a/src/ui/ui_controls/Label.cpp b/src/ui/ui_controls/Label.cpp index 6b41141..bc1886b 100644 --- a/src/ui/ui_controls/Label.cpp +++ b/src/ui/ui_controls/Label.cpp @@ -4,6 +4,9 @@ #include "TransformNode.h" #include "GeometryNode.h" +#include "ThemeManager.h" +#include "PaintEvent.h" + Label::Label() : Widget(), mLabel() @@ -51,7 +54,7 @@ void Label::updateLabel(const PaintEvent* event) if (mMaterialDirty) { - mTextNode->setFillColor(mBackgroundColor); + mTextNode->setFillColor(event->getThemesManager()->getColor(mBackground)); } if (mTransformDirty) diff --git a/src/ui/ui_controls/TextBox.cpp b/src/ui/ui_controls/TextBox.cpp index f05f206..dfaa8b4 100644 --- a/src/ui/ui_controls/TextBox.cpp +++ b/src/ui/ui_controls/TextBox.cpp @@ -5,6 +5,9 @@ #include "KeyboardEvent.h" #include "TransformNode.h" +#include "ThemeManager.h" +#include "PaintEvent.h" + #include TextBox::TextBox() @@ -12,7 +15,7 @@ TextBox::TextBox() mContent(), mCaps(false) { - mBackgroundColor = Color(250, 250, 250); + mBackground = ThemeToken::SystemToken::Background; mPadding = {20, 0, 20, 0}; } @@ -95,7 +98,7 @@ void TextBox::updateLabel(const PaintEvent* event) if (mMaterialDirty) { - mTextNode->setFillColor(mBackgroundColor); + mTextNode->setFillColor(event->getThemesManager()->getColor(mBackground)); } if (mTransformDirty) diff --git a/src/ui/ui_elements/CMakeLists.txt b/src/ui/ui_elements/CMakeLists.txt index 65c690b..d19f2a5 100644 --- a/src/ui/ui_elements/CMakeLists.txt +++ b/src/ui/ui_elements/CMakeLists.txt @@ -25,8 +25,13 @@ list(APPEND LIB_INCLUDES widgets/BoxGeometry.cpp widgets/WidgetState.h widgets/WidgetState.cpp - style/Theme.h - style/Theme.cpp + style/ThemeManager.h + style/ThemeManager.cpp + style/ITheme.h + style/LightTheme.h + style/LightTheme.cpp + style/ColorPalette.h + style/ColorPalette.cpp ) add_library(${MODULE_NAME} SHARED ${LIB_INCLUDES}) diff --git a/src/ui/ui_elements/style/ColorPalette.cpp b/src/ui/ui_elements/style/ColorPalette.cpp new file mode 100644 index 0000000..b4a1677 --- /dev/null +++ b/src/ui/ui_elements/style/ColorPalette.cpp @@ -0,0 +1,55 @@ +#include "ColorPalette.h" + +const std::unordered_map ColorPalette::mPaletteColors = { + {ColorPaletteToken::Primary_10, "#21005E"}, + {ColorPaletteToken::Primary_20, "#371E73"}, + {ColorPaletteToken::Primary_30, "#4F378B"}, + {ColorPaletteToken::Primary_40, "#6750A4"}, + {ColorPaletteToken::Primary_80, "#D0BCFF"}, + {ColorPaletteToken::Primary_90, "#EADDFF"}, + {ColorPaletteToken::Primary_100, "#FFFFFF"}, + {ColorPaletteToken::Secondary_10, "#1E192B"}, + {ColorPaletteToken::Secondary_20, "#332D41"}, + {ColorPaletteToken::Secondary_30, "#4A4458"}, + {ColorPaletteToken::Secondary_40, "#625B71"}, + {ColorPaletteToken::Secondary_80, "#CCC2DC"}, + {ColorPaletteToken::Secondary_90, "#E8DEF8"}, + {ColorPaletteToken::Secondary_100, "#FFFFFF"}, + {ColorPaletteToken::Tertiary_10, "#370B1E"}, + {ColorPaletteToken::Tertiary_20, "#492532"}, + {ColorPaletteToken::Tertiary_30, "#633B48"}, + {ColorPaletteToken::Tertiary_40, "#7D5260"}, + {ColorPaletteToken::Tertiary_80, "#EFB8C8"}, + {ColorPaletteToken::Tertiary_90, "#FFD8E4"}, + {ColorPaletteToken::Tertiary_100, "#FFFFFF"}, + {ColorPaletteToken::Neutral_0, "#000000"}, + {ColorPaletteToken::Neutral_10, "#1C1B1F"}, + {ColorPaletteToken::Neutral_20, "#313033"}, + {ColorPaletteToken::Neutral_90, "#E6E1E5"}, + {ColorPaletteToken::Neutral_95, "#F4EFF4"}, + {ColorPaletteToken::Neutral_99, "#FFFBFE"}, + {ColorPaletteToken::Neutral_Variant_30, "#49454F"}, + {ColorPaletteToken::Neutral_Variant_50, "#79747E"}, + {ColorPaletteToken::Neutral_Variant_60, "#938F99"}, + {ColorPaletteToken::Neutral_Variant_80, "#CAC4D0"}, + {ColorPaletteToken::Neutral_Variant_90, "#E7E0EC"}, + {ColorPaletteToken::Error_10, "#410E0B"}, + {ColorPaletteToken::Error_20, "#601410"}, + {ColorPaletteToken::Error_30, "#8C1D18"}, + {ColorPaletteToken::Error_40, "#B3261E"}, + {ColorPaletteToken::Error_80, "#F2B8B5"}, + {ColorPaletteToken::Error_90, "#F9DEDC"}, + {ColorPaletteToken::Error_100, "#FFFFFF"}, +}; + +Color ColorPalette::getColor(ColorPaletteToken token) +{ + if (auto iter = mPaletteColors.find(token); iter != mPaletteColors.end()) + { + return Color(iter->second); + } + else + { + return Color(); + } +} \ No newline at end of file diff --git a/src/ui/ui_elements/style/ColorPalette.h b/src/ui/ui_elements/style/ColorPalette.h new file mode 100644 index 0000000..c014158 --- /dev/null +++ b/src/ui/ui_elements/style/ColorPalette.h @@ -0,0 +1,60 @@ +#pragma once + +#include "Color.h" + +#include +#include + +enum class ColorPaletteToken +{ + Primary_10, + Primary_20, + Primary_30, + Primary_40, + Primary_80, + Primary_90, + Primary_100, + Secondary_10, + Secondary_20, + Secondary_30, + Secondary_40, + Secondary_80, + Secondary_90, + Secondary_100, + Tertiary_10, + Tertiary_20, + Tertiary_30, + Tertiary_40, + Tertiary_80, + Tertiary_90, + Tertiary_100, + Neutral_0, + Neutral_10, + Neutral_20, + Neutral_30, + Neutral_80, + Neutral_90, + Neutral_95, + Neutral_99, + Neutral_Variant_30, + Neutral_Variant_50, + Neutral_Variant_60, + Neutral_Variant_80, + Neutral_Variant_90, + Error_10, + Error_20, + Error_30, + Error_40, + Error_80, + Error_90, + Error_100 +}; + +class ColorPalette +{ +public: + static Color getColor(ColorPaletteToken token); + +private: + static const std::unordered_map mPaletteColors; +}; \ No newline at end of file diff --git a/src/ui/ui_elements/style/ITheme.h b/src/ui/ui_elements/style/ITheme.h new file mode 100644 index 0000000..1535b3e --- /dev/null +++ b/src/ui/ui_elements/style/ITheme.h @@ -0,0 +1,46 @@ +#pragma once + +#include "ColorPalette.h" + +namespace ThemeToken +{ + enum class SystemToken + { + Primary, + Primary_Container, + Secondary, + Secondary_Container, + Tertiary, + Tertiary_Container, + Surface, + Surface_Variant, + Background, + Error, + Error_Container, + On_Primary, + On_Primary_Container, + On_Secondary, + On_Secondary_Container, + On_Tertiary, + On_Tertiary_Container, + On_Surface, + On_Surface_Variant, + On_Error, + On_Error_Container, + On_Background, + Outline, + Ouline_Variant, + Shadow, + Surface_Tint_Color, + Inverse_Surface, + Inverse_On_Surface, + Inverse_Primary, + Scrim + }; +} + +class ITheme +{ +public: + virtual Color getColor(ThemeToken::SystemToken token) const = 0; +}; diff --git a/src/ui/ui_elements/style/LightTheme.cpp b/src/ui/ui_elements/style/LightTheme.cpp new file mode 100644 index 0000000..ee7fdc2 --- /dev/null +++ b/src/ui/ui_elements/style/LightTheme.cpp @@ -0,0 +1,48 @@ +#include "LightTheme.h" + +#include "ColorPalette.h" + +const std::unordered_map LightTheme::mPalette = { + {ThemeToken::SystemToken::Primary, ColorPaletteToken::Primary_40}, + {ThemeToken::SystemToken::Primary_Container, ColorPaletteToken::Primary_90}, + {ThemeToken::SystemToken::Secondary, ColorPaletteToken::Secondary_40}, + {ThemeToken::SystemToken::Secondary_Container, ColorPaletteToken::Secondary_90}, + {ThemeToken::SystemToken::Tertiary, ColorPaletteToken::Tertiary_40}, + {ThemeToken::SystemToken::Tertiary_Container, ColorPaletteToken::Tertiary_90}, + {ThemeToken::SystemToken::Surface, ColorPaletteToken::Neutral_99}, + {ThemeToken::SystemToken::Surface_Variant, ColorPaletteToken::Neutral_Variant_90}, + {ThemeToken::SystemToken::Background, ColorPaletteToken::Neutral_99}, + {ThemeToken::SystemToken::Error, ColorPaletteToken::Error_40}, + {ThemeToken::SystemToken::Error_Container, ColorPaletteToken::Error_90}, + {ThemeToken::SystemToken::On_Primary, ColorPaletteToken::Primary_100}, + {ThemeToken::SystemToken::On_Primary_Container, ColorPaletteToken::Primary_10}, + {ThemeToken::SystemToken::On_Secondary, ColorPaletteToken::Secondary_100}, + {ThemeToken::SystemToken::On_Secondary_Container, ColorPaletteToken::Secondary_10}, + {ThemeToken::SystemToken::On_Tertiary, ColorPaletteToken::Tertiary_100}, + {ThemeToken::SystemToken::On_Tertiary_Container, ColorPaletteToken::Tertiary_10}, + {ThemeToken::SystemToken::On_Surface, ColorPaletteToken::Neutral_10}, + {ThemeToken::SystemToken::On_Surface_Variant, ColorPaletteToken::Neutral_Variant_30}, + {ThemeToken::SystemToken::On_Error, ColorPaletteToken::Error_100}, + {ThemeToken::SystemToken::On_Error_Container, ColorPaletteToken::Error_10}, + {ThemeToken::SystemToken::On_Background, ColorPaletteToken::Neutral_10}, + {ThemeToken::SystemToken::Outline, ColorPaletteToken::Neutral_Variant_50}, + {ThemeToken::SystemToken::Ouline_Variant, ColorPaletteToken::Neutral_Variant_80}, + {ThemeToken::SystemToken::Shadow, ColorPaletteToken::Neutral_0}, + {ThemeToken::SystemToken::Surface_Tint_Color, ColorPaletteToken::Primary_40}, + {ThemeToken::SystemToken::Inverse_Surface, ColorPaletteToken::Neutral_20}, + {ThemeToken::SystemToken::Inverse_On_Surface, ColorPaletteToken::Neutral_95}, + {ThemeToken::SystemToken::Inverse_Primary, ColorPaletteToken::Primary_80}, + {ThemeToken::SystemToken::Scrim, ColorPaletteToken::Neutral_0}, +}; + +Color LightTheme::getColor(ThemeToken::SystemToken token) const +{ + if (auto iter = mPalette.find(token); iter != mPalette.end()) + { + return ColorPalette::getColor(iter->second); + } + else + { + return Color(); + } +} \ No newline at end of file diff --git a/src/ui/ui_elements/style/LightTheme.h b/src/ui/ui_elements/style/LightTheme.h new file mode 100644 index 0000000..422c000 --- /dev/null +++ b/src/ui/ui_elements/style/LightTheme.h @@ -0,0 +1,15 @@ +#pragma once + +#include "ITheme.h" +#include "Color.h" + +#include + +class LightTheme : public ITheme +{ +public: + Color getColor(ThemeToken::SystemToken token) const override; + +private: + static const std::unordered_map mPalette; +}; \ No newline at end of file diff --git a/src/ui/ui_elements/style/Theme.cpp b/src/ui/ui_elements/style/Theme.cpp deleted file mode 100644 index b28f214..0000000 --- a/src/ui/ui_elements/style/Theme.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "Theme.h" - -Color Theme::getBackgroundPrimary() -{ - return {245, 245, 245}; -} - -Color Theme::getBannerBackground() -{ - return {181, 189, 200}; -} - -Color Theme::getButtonPrimaryBackground() -{ - return {200, 200, 200}; -} - -Color Theme::getButtonPrimaryPressed() -{ - return {}; -} - -Color Theme::getTextPrimary() -{ - return {}; -} diff --git a/src/ui/ui_elements/style/Theme.h b/src/ui/ui_elements/style/Theme.h index d830265..652b7eb 100644 --- a/src/ui/ui_elements/style/Theme.h +++ b/src/ui/ui_elements/style/Theme.h @@ -1,173 +1,14 @@ -#include "Color.h" +#include "ITheme.h" #include // Ref https://m3.material.io/styles/color/the-color-system/tokens -enum class ColorPaletteToken -{ - Primary_10, - Primary_20, - Primary_30, - Primary_40, - Primary_80, - Primary_90, - Primary_100, - Secondary_10, - Secondary_20, - Secondary_30, - Secondary_40, - Secondary_80, - Secondary_90, - Secondary_100, - Tertiary_10, - Tertiary_20, - Tertiary_30, - Tertiary_40, - Tertiary_80, - Tertiary_90, - Tertiary_100, - Neutral_0, - Neutral_10, - Neutral_20, - Neutral_30, - Neutral_80, - Neutral_90, - Neutral_95, - Neutral_99, - Neutral_Variant_30, - Neutral_Variant_50, - Neutral_Variant_60, - Neutral_Variant_80, - Neutral_Variant_90, - Error_10, - Error_20, - Error_30, - Error_40, - Error_80, - Error_90, - Error_100 -}; - -std::unordered_map mPaletteColors = { - {ColorPaletteToken::Primary_10, "#21005E"}, - {ColorPaletteToken::Primary_20, "#371E73"}, - {ColorPaletteToken::Primary_30, "#4F378B"}, - {ColorPaletteToken::Primary_40, "#6750A4"}, - {ColorPaletteToken::Primary_80, "#D0BCFF"}, - {ColorPaletteToken::Primary_90, "#EADDFF"}, - {ColorPaletteToken::Primary_100, "#FFFFFF"}, - {ColorPaletteToken::Secondary_10, "#1E192B"}, - {ColorPaletteToken::Secondary_20, "#332D41"}, - {ColorPaletteToken::Secondary_30, "#4A4458"}, - {ColorPaletteToken::Secondary_40, "#625B71"}, - {ColorPaletteToken::Secondary_80, "#CCC2DC"}, - {ColorPaletteToken::Secondary_90, "#E8DEF8"}, - {ColorPaletteToken::Secondary_100, "#FFFFFF"}, - {ColorPaletteToken::Tertiary_10, "#370B1E"}, - {ColorPaletteToken::Tertiary_20, "#492532"}, - {ColorPaletteToken::Tertiary_30, "#633B48"}, - {ColorPaletteToken::Tertiary_40, "#7D5260"}, - {ColorPaletteToken::Tertiary_80, "#EFB8C8"}, - {ColorPaletteToken::Tertiary_90, "#FFD8E4"}, - {ColorPaletteToken::Tertiary_100, "#FFFFFF"}, - {ColorPaletteToken::Neutral_0, "#000000"}, - {ColorPaletteToken::Neutral_10, "#1C1B1F"}, - {ColorPaletteToken::Neutral_20, "#313033"}, - {ColorPaletteToken::Neutral_90, "#E6E1E5"}, - {ColorPaletteToken::Neutral_95, "#F4EFF4"}, - {ColorPaletteToken::Neutral_99, "#FFFBFE"}, - {ColorPaletteToken::Neutral_Variant_30, "#49454F"}, - {ColorPaletteToken::Neutral_Variant_50, "#79747E"}, - {ColorPaletteToken::Neutral_Variant_60, "#938F99"}, - {ColorPaletteToken::Neutral_Variant_80, "#CAC4D0"}, - {ColorPaletteToken::Neutral_Variant_90, "#E7E0EC"}, - {ColorPaletteToken::Error_10, "#410E0B"}, - {ColorPaletteToken::Error_20, "#601410"}, - {ColorPaletteToken::Error_30, "#8C1D18"}, - {ColorPaletteToken::Error_40, "#B3261E"}, - {ColorPaletteToken::Error_80, "#F2B8B5"}, - {ColorPaletteToken::Error_90, "#F9DEDC"}, - {ColorPaletteToken::Error_100, "#FFFFFF"}, -}; - -enum class SystemToken -{ - Primary, - Primary_Container, - Secondary, - Secondary_Container, - Tertiary, - Tertiary_Container, - Surface, - Surface_Variant, - Background, - Error, - Error_Container, - On_Primary, - On_Primary_Container, - On_Secondary, - On_Secondary_Container, - On_Tertiary, - On_Tertiary_Container, - On_Surface, - On_Surface_Variant, - On_Error, - On_Error_Container, - On_Background, - Outline, - Ouline_Variant, - Shadow, - Surface_Tint_Color, - Inverse_Surface, - Inverse_On_Surface, - Inverse_Primary, - Scrim -}; - -std::unordered_map mLightTheme = { - {SystemToken::Primary, ColorPaletteToken::Primary_40}, - {SystemToken::Primary_Container, ColorPaletteToken::Primary_90}, - {SystemToken::Secondary, ColorPaletteToken::Secondary_40}, - {SystemToken::Secondary_Container, ColorPaletteToken::Secondary_90}, - {SystemToken::Tertiary, ColorPaletteToken::Tertiary_40}, - {SystemToken::Tertiary_Container, ColorPaletteToken::Tertiary_90}, - {SystemToken::Surface, ColorPaletteToken::Neutral_99}, - {SystemToken::Surface_Variant, ColorPaletteToken::Neutral_Variant_90}, - {SystemToken::Background, ColorPaletteToken::Neutral_99}, - {SystemToken::Error, ColorPaletteToken::Error_40}, - {SystemToken::Error_Container, ColorPaletteToken::Error_90}, - {SystemToken::On_Primary, ColorPaletteToken::Primary_100}, - {SystemToken::On_Primary_Container, ColorPaletteToken::Primary_10}, - {SystemToken::On_Secondary, ColorPaletteToken::Secondary_100}, - {SystemToken::On_Secondary_Container, ColorPaletteToken::Secondary_10}, - {SystemToken::On_Tertiary, ColorPaletteToken::Tertiary_100}, - {SystemToken::On_Tertiary_Container, ColorPaletteToken::Tertiary_10}, - {SystemToken::On_Surface, ColorPaletteToken::Neutral_10}, - {SystemToken::On_Surface_Variant, ColorPaletteToken::Neutral_Variant_30}, - {SystemToken::On_Error, ColorPaletteToken::Error_100}, - {SystemToken::On_Error_Container, ColorPaletteToken::Error_10}, - {SystemToken::On_Background, ColorPaletteToken::Neutral_10}, - {SystemToken::Outline, ColorPaletteToken::Neutral_Variant_50}, - {SystemToken::Ouline_Variant, ColorPaletteToken::Neutral_Variant_80}, - {SystemToken::Shadow, ColorPaletteToken::Neutral_0}, - {SystemToken::Surface_Tint_Color, ColorPaletteToken::Primary_40}, - {SystemToken::Inverse_Surface, ColorPaletteToken::Neutral_20}, - {SystemToken::Inverse_On_Surface, ColorPaletteToken::Neutral_95}, - {SystemToken::Inverse_Primary, ColorPaletteToken::Primary_80}, - {SystemToken::Scrim, ColorPaletteToken::Neutral_0}, -}; - -class Theme +class ThemeManager { public: - static Color getBackgroundPrimary(); + Color getColor(ThemeToken::SystemToken token) const; - static Color getBannerBackground(); - - static Color getButtonPrimaryBackground(); - - static Color getButtonPrimaryPressed(); - - static Color getTextPrimary(); +private: + std::unique_ptr mActiveTheme; }; diff --git a/src/ui/ui_elements/style/ThemeManager.cpp b/src/ui/ui_elements/style/ThemeManager.cpp new file mode 100644 index 0000000..982d337 --- /dev/null +++ b/src/ui/ui_elements/style/ThemeManager.cpp @@ -0,0 +1,17 @@ +#include "ThemeManager.h" + +#include "LightTheme.h" + +ThemeManager::ThemeManager() +{ + mTheme = std::make_unique(); +} + +Color ThemeManager::getColor(ThemeToken::SystemToken token) const +{ + return mTheme->getColor(token); +} + + + + diff --git a/src/ui/ui_elements/style/ThemeManager.h b/src/ui/ui_elements/style/ThemeManager.h new file mode 100644 index 0000000..00bb967 --- /dev/null +++ b/src/ui/ui_elements/style/ThemeManager.h @@ -0,0 +1,12 @@ +#pragma once + +#include "ITheme.h" + +class ThemeManager +{ +public: + ThemeManager(); + Color getColor(ThemeToken::SystemToken token) const; +private: + std::unique_ptr mTheme; +}; diff --git a/src/ui/ui_elements/ui_events/PaintEvent.cpp b/src/ui/ui_elements/ui_events/PaintEvent.cpp index 99d1fc9..4457a41 100644 --- a/src/ui/ui_elements/ui_events/PaintEvent.cpp +++ b/src/ui/ui_elements/ui_events/PaintEvent.cpp @@ -1,7 +1,9 @@ #include "PaintEvent.h" -PaintEvent::PaintEvent() - : UiEvent() +PaintEvent::PaintEvent(ThemeManager* themesManager, FontsManager* fontsManager) + : UiEvent(), + mThemeManager(themesManager), + mFontsManager(fontsManager) { mType = UiEvent::Type::Paint; } @@ -11,8 +13,18 @@ PaintEvent::~PaintEvent() } -std::unique_ptr PaintEvent::Create() +std::unique_ptr PaintEvent::Create(ThemeManager* themesManager, FontsManager* fontsManager) { - return std::make_unique(); + return std::make_unique(themesManager, fontsManager); +} + +ThemeManager* PaintEvent::getThemesManager() const +{ + return mThemeManager; +} + +FontsManager* PaintEvent::getFontsManager() const +{ + return mFontsManager; } diff --git a/src/ui/ui_elements/ui_events/PaintEvent.h b/src/ui/ui_elements/ui_events/PaintEvent.h index f377b60..61cbc01 100644 --- a/src/ui/ui_elements/ui_events/PaintEvent.h +++ b/src/ui/ui_elements/ui_events/PaintEvent.h @@ -4,13 +4,23 @@ #include "UiEvent.h" +class ThemeManager; +class FontsManager; + class PaintEvent : public UiEvent { public: - PaintEvent(); + PaintEvent(ThemeManager* themesManager, FontsManager* fontsManager); + + static std::unique_ptr Create(ThemeManager* themesManager, FontsManager* fontsManager); ~PaintEvent(); - static std::unique_ptr Create(); + ThemeManager* getThemesManager() const; + FontsManager* getFontsManager() const; + +private: + ThemeManager* mThemeManager{ nullptr }; + FontsManager* mFontsManager{ nullptr }; }; using PaintEventUPtr = std::unique_ptr; diff --git a/src/ui/ui_elements/widgets/Widget.cpp b/src/ui/ui_elements/widgets/Widget.cpp index 3b8adb9..c4cac23 100644 --- a/src/ui/ui_elements/widgets/Widget.cpp +++ b/src/ui/ui_elements/widgets/Widget.cpp @@ -9,6 +9,7 @@ #include "TextNode.h" #include "TransformNode.h" #include "RootNode.h" +#include "ThemeManager.h" #include "Window.h" #include "FileLogger.h" @@ -22,8 +23,8 @@ Widget::Widget() mRootNode(std::make_unique()), mChildren(), mBorderThickness(0), - mBackgroundColor(Color(255, 255, 255)), - mBorderColor(Color(0, 0, 0)), + mBackground(ThemeToken::SystemToken::Primary), + mBorder(ThemeToken::SystemToken::Outline), mVisible(true) { mName = "Widget"; @@ -65,11 +66,11 @@ TransformNode* Widget::getRootNode() const -void Widget::setBackgroundColor(const Color& color) +void Widget::setBackground(ThemeToken::SystemToken token) { - if (mBackgroundColor != color) + if (mBackground != token) { - mBackgroundColor = color; + mBackground = token; mMaterialDirty = true; } } @@ -239,8 +240,8 @@ void Widget::updateBackground(const PaintEvent* event) if (mMaterialDirty) { - mBackgroundNode->setFillColor(mBackgroundColor); - mBackgroundNode->setStrokeColor(mBorderColor); + mBackgroundNode->setFillColor(event->getThemesManager()->getColor(mBackground)); + mBackgroundNode->setStrokeColor(event->getThemesManager()->getColor(mBorder)); mBackgroundNode->setStrokeThickness(mBorderThickness); } diff --git a/src/ui/ui_elements/widgets/Widget.h b/src/ui/ui_elements/widgets/Widget.h index f98ce27..88c6aa0 100644 --- a/src/ui/ui_elements/widgets/Widget.h +++ b/src/ui/ui_elements/widgets/Widget.h @@ -1,7 +1,7 @@ #pragma once #include "FontItem.h" -#include "Color.h" +#include "ITheme.h" #include "WidgetState.h" #include "BoxGeometry.h" @@ -47,7 +47,7 @@ public: virtual bool onKeyboardEvent(const KeyboardEvent* event); - void setBackgroundColor(const Color& color); + void setBackground(ThemeToken::SystemToken token); void setVisible(bool visible); @@ -78,8 +78,9 @@ protected: std::vector > mChildren; unsigned mBorderThickness{0}; - Color mBackgroundColor; - Color mBorderColor; + ThemeToken::SystemToken mBackground; + ThemeToken::SystemToken mBorder; + bool mVisible{true}; std::unique_ptr mBackgroundNode; diff --git a/src/ui/windows/managers/DesktopManager.cpp b/src/ui/windows/managers/DesktopManager.cpp index 4ba3909..d941533 100644 --- a/src/ui/windows/managers/DesktopManager.cpp +++ b/src/ui/windows/managers/DesktopManager.cpp @@ -13,7 +13,8 @@ DesktopManager::DesktopManager(AbstractDesktopApp* application) mKeyboard(Keyboard::Create()), mUiApplication(application), mEventManager(EventManager::Create()), - mFontsManager(FontsManager::Create()) + mFontsManager(FontsManager::Create()), + mThemeManager(std::make_unique()) { mWindowManager = WindowManager::Create(this); } @@ -38,6 +39,11 @@ FontsManager* DesktopManager::getFontsManager() const return mFontsManager.get(); } +ThemeManager* DesktopManager::getThemeManager() const +{ + return mThemeManager.get(); +} + void DesktopManager::onKeyboardEvent(const KeyboardEvent* event) { mWindowManager->onKeyboardEvent(event); diff --git a/src/ui/windows/managers/DesktopManager.h b/src/ui/windows/managers/DesktopManager.h index 8045a3c..b19ca73 100644 --- a/src/ui/windows/managers/DesktopManager.h +++ b/src/ui/windows/managers/DesktopManager.h @@ -5,14 +5,18 @@ #include "Keyboard.h" #include "Screen.h" + #include "KeyboardEvent.h" #include "PaintEvent.h" #include "MouseEvent.h" -#include "WindowManager.h" #include "UiEvent.h" + #include "AbstractApp.h" + #include "EventManager.h" #include "FontsManager.h" +#include "WindowManager.h" +#include "ThemeManager.h" class AbstractDesktopApp; @@ -35,6 +39,8 @@ public: FontsManager* getFontsManager() const; + ThemeManager* getThemeManager() const; + void addScreen(ScreenPtr screen); mt::Screen* getDefaultScreen() const; @@ -57,11 +63,13 @@ public: private: std::vector mScreens; + KeyboardUPtr mKeyboard; FontsManagerPtr mFontsManager; WindowManagerUPtr mWindowManager; - KeyboardUPtr mKeyboard; EventManagerUPtr mEventManager; + std::unique_ptr mThemeManager; + AbstractDesktopApp* mUiApplication; }; diff --git a/src/ui/windows/ui_interfaces/win32/Win32Window.cpp b/src/ui/windows/ui_interfaces/win32/Win32Window.cpp index 029624c..3670de6 100644 --- a/src/ui/windows/ui_interfaces/win32/Win32Window.cpp +++ b/src/ui/windows/ui_interfaces/win32/Win32Window.cpp @@ -86,7 +86,7 @@ void Win32Window::createNative(Win32ApplicationContext* context, DesktopManager* void Win32Window::onPaintMessage() { - mDesktopManager->onUiEvent(PaintEvent::Create()); + mDesktopManager->onUiEvent(PaintEvent::Create(mDesktopManager->getThemeManager(), mDesktopManager->getFontsManager())); mWindow->doPaint(nullptr); }