Add initial token theming.

This commit is contained in:
jmsgrogan 2023-01-17 13:01:59 +00:00
parent 3d37a7244b
commit 1f85954e98
34 changed files with 406 additions and 253 deletions

View file

@ -8,7 +8,7 @@ AudioEditorView::AudioEditorView()
{ {
auto label = Label::Create(); auto label = Label::Create();
label->setLabel("audio Editor"); label->setLabel("audio Editor");
label->setBackgroundColor(Theme::getBackgroundPrimary()); label->setBackground(ThemeToken::SystemToken::Primary);
label->setMargin(1); label->setMargin(1);
addWidget(std::move(label)); addWidget(std::move(label));
} }

View file

@ -2,7 +2,9 @@
#include "HorizontalSpacer.h" #include "HorizontalSpacer.h"
#include "Button.h" #include "Button.h"
#include "Theme.h"
#include "ThemeManager.h"
#include "PaintEvent.h"
CanvasCommandSelectorView::CanvasCommandSelectorView() CanvasCommandSelectorView::CanvasCommandSelectorView()
: Widget() : Widget()
@ -13,7 +15,7 @@ CanvasCommandSelectorView::CanvasCommandSelectorView()
onCommandSelected(CanvasDrawCommand::CIRCLE); onCommandSelected(CanvasDrawCommand::CIRCLE);
}; };
circle_button->setLabel("Circle"); circle_button->setLabel("Circle");
circle_button->setBackgroundColor(Theme::getButtonPrimaryBackground()); circle_button->setBackground(ThemeToken::SystemToken::Primary);
circle_button->setMargin(2); circle_button->setMargin(2);
circle_button->setOnClickFunction(on_circle_click); circle_button->setOnClickFunction(on_circle_click);
@ -22,7 +24,7 @@ CanvasCommandSelectorView::CanvasCommandSelectorView()
}; };
auto line_button = Button::Create(); auto line_button = Button::Create();
line_button->setLabel("Line"); line_button->setLabel("Line");
line_button->setBackgroundColor(Theme::getButtonPrimaryBackground()); line_button->setBackground(ThemeToken::SystemToken::Primary);
line_button->setMargin(2); line_button->setMargin(2);
line_button->setOnClickFunction(on_line_click); line_button->setOnClickFunction(on_line_click);

View file

@ -7,13 +7,15 @@
#include "CanvasDrawingArea.h" #include "CanvasDrawingArea.h"
#include "CanvasCommandSelectorView.h" #include "CanvasCommandSelectorView.h"
#include "Theme.h"
#include "TextNode.h" #include "TextNode.h"
#include "GeometryNode.h" #include "GeometryNode.h"
#include "Label.h" #include "Label.h"
#include "Button.h" #include "Button.h"
#include "ThemeManager.h"
#include "PaintEvent.h"
CanvasView::CanvasView() CanvasView::CanvasView()
: mController(CanvasController::Create()) : mController(CanvasController::Create())
{ {
@ -34,11 +36,11 @@ void CanvasView::initialize()
{ {
auto label = Label::Create(); auto label = Label::Create();
label->setLabel("Canvas"); label->setLabel("Canvas");
label->setBackgroundColor(Theme::getBannerBackground()); label->setBackground(ThemeToken::SystemToken::Secondary);
label->setMargin(1); label->setMargin(1);
auto controls = std::make_unique<CanvasCommandSelectorView>(); auto controls = std::make_unique<CanvasCommandSelectorView>();
controls->setBackgroundColor(Theme::getBannerBackground()); controls->setBackground(ThemeToken::SystemToken::Background);
controls->setMargin(1); controls->setMargin(1);
auto on_draw_command_changed = [this](CanvasDrawCommand command){ auto on_draw_command_changed = [this](CanvasDrawCommand command){
@ -47,7 +49,7 @@ void CanvasView::initialize()
controls->setCommandSelectedCallback(on_draw_command_changed); controls->setCommandSelectedCallback(on_draw_command_changed);
auto drawing_area = std::make_unique<CanvasDrawingArea>(); auto drawing_area = std::make_unique<CanvasDrawingArea>();
drawing_area->setBackgroundColor(Theme::getBackgroundPrimary()); drawing_area->setBackground(ThemeToken::SystemToken::Background);
drawing_area->setMargin(1); drawing_area->setMargin(1);
mDrawingArea = drawing_area.get(); mDrawingArea = drawing_area.get();
@ -75,17 +77,17 @@ std::unique_ptr<Widget> CanvasView::initializeCacheButtons()
{ {
auto saveButton = Button::Create(); auto saveButton = Button::Create();
saveButton->setLabel("Save"); saveButton->setLabel("Save");
saveButton->setBackgroundColor(Theme::getButtonPrimaryBackground()); saveButton->setBackground(ThemeToken::SystemToken::Primary);
saveButton->setMargin(2); saveButton->setMargin(2);
auto clearButton = Button::Create(); auto clearButton = Button::Create();
clearButton->setLabel("Clear"); clearButton->setLabel("Clear");
clearButton->setBackgroundColor(Theme::getButtonPrimaryBackground()); clearButton->setBackground(ThemeToken::SystemToken::Primary);
clearButton->setMargin(2); clearButton->setMargin(2);
auto loadButton = Button::Create(); auto loadButton = Button::Create();
loadButton->setLabel("Load"); loadButton->setLabel("Load");
loadButton->setBackgroundColor(Theme::getButtonPrimaryBackground()); loadButton->setBackground(ThemeToken::SystemToken::Primary);
loadButton->setMargin(2); loadButton->setMargin(2);
auto buttonSpacer = VerticalSpacer::Create(); auto buttonSpacer = VerticalSpacer::Create();

View file

@ -12,7 +12,7 @@ ImageEditorView::ImageEditorView()
{ {
auto label = Label::Create(); auto label = Label::Create();
label->setLabel("Image Editor"); label->setLabel("Image Editor");
label->setBackgroundColor(Theme::getBackgroundPrimary()); label->setBackground(ThemeToken::SystemToken::Primary);
label->setMargin(1); label->setMargin(1);
auto image_widget = std::make_unique<ImageViewWidget>(); auto image_widget = std::make_unique<ImageViewWidget>();

View file

@ -3,7 +3,8 @@
#include "GridNode.h" #include "GridNode.h"
#include "TransformNode.h" #include "TransformNode.h"
#include <iostream> #include "ThemeManager.h"
#include "PaintEvent.h"
ImageViewWidget::ImageViewWidget() ImageViewWidget::ImageViewWidget()
{ {
@ -27,7 +28,7 @@ void ImageViewWidget::doPaint(const PaintEvent* event)
mGridNode->setWidth(mSize.mWidth); mGridNode->setWidth(mSize.mWidth);
mGridNode->setHeight(mSize.mHeight); mGridNode->setHeight(mSize.mHeight);
mGridNode->setStrokeColor(mBorderColor); mGridNode->setStrokeColor(event->getThemesManager()->getColor(mBorder));
mRootNode->addChild(mGridNode.get()); mRootNode->addChild(mGridNode.get());
} }
@ -41,6 +42,6 @@ void ImageViewWidget::doPaint(const PaintEvent* event)
if (mMaterialDirty) if (mMaterialDirty)
{ {
mGridNode->setFillColor(mBorderColor); mGridNode->setFillColor(event->getThemesManager()->getColor(mBorder));
} }
} }

View file

@ -5,6 +5,9 @@
#include "AbstractMesh.h" #include "AbstractMesh.h"
#include "MeshPrimitives.h" #include "MeshPrimitives.h"
#include "ThemeManager.h"
#include "PaintEvent.h"
#include <iostream> #include <iostream>
std::unique_ptr<MeshViewerView> MeshViewerView::Create() std::unique_ptr<MeshViewerView> MeshViewerView::Create()
@ -20,7 +23,7 @@ MeshViewerView::~MeshViewerView()
MeshViewerView::MeshViewerView() MeshViewerView::MeshViewerView()
{ {
mName = "MeshViewerView"; mName = "MeshViewerView";
mBackgroundColor = {204, 204, 255}; mBackground = ThemeToken::SystemToken::Background;
} }
void MeshViewerView::doPaint(const PaintEvent* event) void MeshViewerView::doPaint(const PaintEvent* event)
@ -38,7 +41,7 @@ void MeshViewerView::doPaint(const PaintEvent* event)
mMeshNode->setWidth(mSize.mWidth); mMeshNode->setWidth(mSize.mWidth);
mMeshNode->setHeight(mSize.mHeight); mMeshNode->setHeight(mSize.mHeight);
mMeshNode->setFillColor(mBackgroundColor); mMeshNode->setFillColor(event->getThemesManager()->getColor(mBackground));
mRootNode->addChild(mMeshNode.get()); mRootNode->addChild(mMeshNode.get());
} }
@ -52,7 +55,7 @@ void MeshViewerView::doPaint(const PaintEvent* event)
if (mMaterialDirty) if (mMaterialDirty)
{ {
mMeshNode->setFillColor(mBackgroundColor); mMeshNode->setFillColor(event->getThemesManager()->getColor(mBackground));
} }
if (!mMesh) if (!mMesh)

View file

@ -25,7 +25,7 @@ void TextEditorView::initialize()
{ {
auto label = Label::Create(); auto label = Label::Create();
label->setLabel("Text Editor"); label->setLabel("Text Editor");
label->setBackgroundColor(Theme::getBannerBackground()); label->setBackground(ThemeToken::SystemToken::Secondary);
label->setMargin(1); label->setMargin(1);
auto textBox = TextBox::Create(); auto textBox = TextBox::Create();
@ -34,7 +34,7 @@ void TextEditorView::initialize()
auto saveButton = Button::Create(); auto saveButton = Button::Create();
saveButton->setLabel("Save"); saveButton->setLabel("Save");
saveButton->setBackgroundColor(Theme::getButtonPrimaryBackground()); saveButton->setBackground(ThemeToken::SystemToken::Primary);
saveButton->setMargin(2); saveButton->setMargin(2);
auto onSave = [this](Widget* self){ auto onSave = [this](Widget* self){
if(this && mController && mTextBox) if(this && mController && mTextBox)
@ -47,7 +47,7 @@ void TextEditorView::initialize()
auto clearButton = Button::Create(); auto clearButton = Button::Create();
clearButton->setLabel("Clear"); clearButton->setLabel("Clear");
clearButton->setBackgroundColor(Theme::getButtonPrimaryBackground()); clearButton->setBackground(ThemeToken::SystemToken::Primary);
clearButton->setMargin(2); clearButton->setMargin(2);
auto onClear = [this](Widget* self){ auto onClear = [this](Widget* self){
if(this && mController && mTextBox) if(this && mController && mTextBox)
@ -60,7 +60,7 @@ void TextEditorView::initialize()
auto loadButton = Button::Create(); auto loadButton = Button::Create();
loadButton->setLabel("Load"); loadButton->setLabel("Load");
loadButton->setBackgroundColor(Theme::getButtonPrimaryBackground()); loadButton->setBackground(ThemeToken::SystemToken::Primary);
loadButton->setMargin(2); loadButton->setMargin(2);
auto onLoad = [this](Widget* self){ auto onLoad = [this](Widget* self){
if(this && mController && mTextBox) if(this && mController && mTextBox)

View file

@ -10,7 +10,7 @@ WebClientView::WebClientView()
{ {
auto label = Label::Create(); auto label = Label::Create();
label->setLabel("Web Client"); label->setLabel("Web Client");
label->setBackgroundColor(Theme::getBackgroundPrimary()); label->setBackground(ThemeToken::SystemToken::Secondary);
label->setMargin(1); label->setMargin(1);
addWidget(std::move(label)); addWidget(std::move(label));
} }

View file

@ -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<unsigned char>(std::stoul("0x" + hex, nullptr, 16));
}
std::unique_ptr<Color> Color::Create(unsigned char r, unsigned char g, unsigned char b, double a ) std::unique_ptr<Color> Color::Create(unsigned char r, unsigned char g, unsigned char b, double a )
{ {
return std::make_unique<Color>(r, g, b, a); return std::make_unique<Color>(r, g, b, a);

View file

@ -7,6 +7,8 @@
class Color class Color
{ {
public: public:
Color(const std::string& hexString);
Color(unsigned char r = 0, unsigned char g = 0, unsigned char b = 0, double a = 1.0); Color(unsigned char r = 0, unsigned char g = 0, unsigned char b = 0, double a = 1.0);
static std::unique_ptr<Color> Create(unsigned char r, unsigned char g, unsigned char b, double a = 1.0); static std::unique_ptr<Color> Create(unsigned char r, unsigned char g, unsigned char b, double a = 1.0);
@ -37,6 +39,8 @@ public:
} }
private: private:
unsigned char toDecimal(const std::string& hex) const;
unsigned char mR{0}; unsigned char mR{0};
unsigned char mG{0}; unsigned char mG{0};
unsigned char mB{0}; unsigned char mB{0};

View file

@ -1,10 +1,10 @@
#include "StatusBar.h" #include "StatusBar.h"
#include "Color.h" #include "ITheme.h"
StatusBar::StatusBar() StatusBar::StatusBar()
{ {
setBackgroundColor(Color(200, 200, 200)); setBackground(ThemeToken::SystemToken::Secondary);
} }
std::unique_ptr<StatusBar> StatusBar::Create() std::unique_ptr<StatusBar> StatusBar::Create()

View file

@ -5,6 +5,8 @@
#include "TextNode.h" #include "TextNode.h"
#include "Button.h" #include "Button.h"
#include "Theme.h"
TabbedPanelWidget::TabbedPanelWidget() TabbedPanelWidget::TabbedPanelWidget()
: mNavPanel(), : mNavPanel(),
mStack() mStack()
@ -36,7 +38,7 @@ void TabbedPanelWidget::addPanel(WidgetUPtr panel, const std::string& label)
{ {
auto button = Button::Create(); auto button = Button::Create();
button->setLabel(label); button->setLabel(label);
button->setBackgroundColor(Color(156, 156, 156)); button->setBackground(ThemeToken::SystemToken::Primary);
button->setMargin({1, 0, 0, 1}); button->setMargin({1, 0, 0, 1});
auto rawPanel = panel.get(); auto rawPanel = panel.get();

View file

@ -1,18 +1,18 @@
#include "TopBar.h" #include "TopBar.h"
#include "Color.h" #include "Color.h"
#include "Theme.h" #include "ITheme.h"
#include "Button.h" #include "Button.h"
#include "TopBarMenu.h" #include "TopBarMenu.h"
TopBar::TopBar() TopBar::TopBar()
{ {
setBackgroundColor(Theme::getBackgroundPrimary()); setBackground(ThemeToken::SystemToken::Secondary);
auto fileButton = Button::Create(); auto fileButton = Button::Create();
fileButton->setLabel("File"); fileButton->setLabel("File");
fileButton->setBackgroundColor(Theme::getBackgroundPrimary()); fileButton->setBackground(ThemeToken::SystemToken::Primary);
fileButton->setMargin(2); fileButton->setMargin(2);
fileButton->setMaxWidth(60); fileButton->setMaxWidth(60);

View file

@ -3,6 +3,8 @@
#include "TextNode.h" #include "TextNode.h"
#include "GeometryNode.h" #include "GeometryNode.h"
#include "TransformNode.h" #include "TransformNode.h"
#include "ThemeManager.h"
#include "PaintEvent.h"
#include "MouseEvent.h" #include "MouseEvent.h"
#include "FileLogger.h" #include "FileLogger.h"
@ -10,8 +12,8 @@
Button::Button() Button::Button()
: Widget(), : Widget(),
mLabel(), mLabel(),
mCachedColor(255, 255, 255), mCachedColor(ThemeToken::SystemToken::Primary),
mClickedColor(Color(180, 180, 180)), mClickedColor(ThemeToken::SystemToken::Secondary),
mClickFunc() mClickFunc()
{ {
mName = "Button"; mName = "Button";
@ -46,8 +48,8 @@ void Button::onMyMouseEvent(const MouseEvent* event)
MLOG_INFO("Widget mouse event"); MLOG_INFO("Widget mouse event");
if(event->getAction() == MouseEvent::Action::Pressed) if(event->getAction() == MouseEvent::Action::Pressed)
{ {
mCachedColor = mBackgroundColor; mCachedColor = mBackground;
setBackgroundColor(mClickedColor); setBackground(mClickedColor);
if(mClickFunc) if(mClickFunc)
{ {
mClickFunc(this); mClickFunc(this);
@ -55,7 +57,7 @@ void Button::onMyMouseEvent(const MouseEvent* event)
} }
else if(event->getAction() == MouseEvent::Action::Released) else if(event->getAction() == MouseEvent::Action::Released)
{ {
setBackgroundColor(mCachedColor); setBackground(mCachedColor);
} }
} }
@ -94,7 +96,7 @@ void Button::updateLabel(const PaintEvent* event)
if (mMaterialDirty) if (mMaterialDirty)
{ {
mTextNode->setFillColor(mBackgroundColor); mTextNode->setFillColor(event->getThemesManager()->getColor(mBackground));
} }
if (mContentDirty) if (mContentDirty)

View file

@ -36,8 +36,8 @@ protected:
private: private:
std::string mLabel; std::string mLabel;
clickFunc mClickFunc; clickFunc mClickFunc;
Color mCachedColor; ThemeToken::SystemToken mCachedColor;
Color mClickedColor; ThemeToken::SystemToken mClickedColor;
std::unique_ptr<TextNode> mTextNode; std::unique_ptr<TextNode> mTextNode;
bool mContentDirty{true}; bool mContentDirty{true};

View file

@ -4,6 +4,9 @@
#include "TransformNode.h" #include "TransformNode.h"
#include "GeometryNode.h" #include "GeometryNode.h"
#include "ThemeManager.h"
#include "PaintEvent.h"
Label::Label() Label::Label()
: Widget(), : Widget(),
mLabel() mLabel()
@ -51,7 +54,7 @@ void Label::updateLabel(const PaintEvent* event)
if (mMaterialDirty) if (mMaterialDirty)
{ {
mTextNode->setFillColor(mBackgroundColor); mTextNode->setFillColor(event->getThemesManager()->getColor(mBackground));
} }
if (mTransformDirty) if (mTransformDirty)

View file

@ -5,6 +5,9 @@
#include "KeyboardEvent.h" #include "KeyboardEvent.h"
#include "TransformNode.h" #include "TransformNode.h"
#include "ThemeManager.h"
#include "PaintEvent.h"
#include <sstream> #include <sstream>
TextBox::TextBox() TextBox::TextBox()
@ -12,7 +15,7 @@ TextBox::TextBox()
mContent(), mContent(),
mCaps(false) mCaps(false)
{ {
mBackgroundColor = Color(250, 250, 250); mBackground = ThemeToken::SystemToken::Background;
mPadding = {20, 0, 20, 0}; mPadding = {20, 0, 20, 0};
} }
@ -95,7 +98,7 @@ void TextBox::updateLabel(const PaintEvent* event)
if (mMaterialDirty) if (mMaterialDirty)
{ {
mTextNode->setFillColor(mBackgroundColor); mTextNode->setFillColor(event->getThemesManager()->getColor(mBackground));
} }
if (mTransformDirty) if (mTransformDirty)

View file

@ -25,8 +25,13 @@ list(APPEND LIB_INCLUDES
widgets/BoxGeometry.cpp widgets/BoxGeometry.cpp
widgets/WidgetState.h widgets/WidgetState.h
widgets/WidgetState.cpp widgets/WidgetState.cpp
style/Theme.h style/ThemeManager.h
style/Theme.cpp 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}) add_library(${MODULE_NAME} SHARED ${LIB_INCLUDES})

View file

@ -0,0 +1,55 @@
#include "ColorPalette.h"
const std::unordered_map<ColorPaletteToken, std::string> 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();
}
}

View file

@ -0,0 +1,60 @@
#pragma once
#include "Color.h"
#include <unordered_map>
#include <string>
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<ColorPaletteToken, std::string> mPaletteColors;
};

View file

@ -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;
};

View file

@ -0,0 +1,48 @@
#include "LightTheme.h"
#include "ColorPalette.h"
const std::unordered_map<ThemeToken::SystemToken, ColorPaletteToken> 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();
}
}

View file

@ -0,0 +1,15 @@
#pragma once
#include "ITheme.h"
#include "Color.h"
#include <unordered_map>
class LightTheme : public ITheme
{
public:
Color getColor(ThemeToken::SystemToken token) const override;
private:
static const std::unordered_map<ThemeToken::SystemToken, ColorPaletteToken> mPalette;
};

View file

@ -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 {};
}

View file

@ -1,173 +1,14 @@
#include "Color.h" #include "ITheme.h"
#include <unordered_map> #include <unordered_map>
// Ref https://m3.material.io/styles/color/the-color-system/tokens // Ref https://m3.material.io/styles/color/the-color-system/tokens
enum class ColorPaletteToken class ThemeManager
{
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<ColorPaletteToken, std::string> 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<SystemToken, ColorPaletteToken> 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
{ {
public: public:
static Color getBackgroundPrimary(); Color getColor(ThemeToken::SystemToken token) const;
static Color getBannerBackground(); private:
std::unique_ptr<ITheme> mActiveTheme;
static Color getButtonPrimaryBackground();
static Color getButtonPrimaryPressed();
static Color getTextPrimary();
}; };

View file

@ -0,0 +1,17 @@
#include "ThemeManager.h"
#include "LightTheme.h"
ThemeManager::ThemeManager()
{
mTheme = std::make_unique<LightTheme>();
}
Color ThemeManager::getColor(ThemeToken::SystemToken token) const
{
return mTheme->getColor(token);
}

View file

@ -0,0 +1,12 @@
#pragma once
#include "ITheme.h"
class ThemeManager
{
public:
ThemeManager();
Color getColor(ThemeToken::SystemToken token) const;
private:
std::unique_ptr<ITheme> mTheme;
};

View file

@ -1,7 +1,9 @@
#include "PaintEvent.h" #include "PaintEvent.h"
PaintEvent::PaintEvent() PaintEvent::PaintEvent(ThemeManager* themesManager, FontsManager* fontsManager)
: UiEvent() : UiEvent(),
mThemeManager(themesManager),
mFontsManager(fontsManager)
{ {
mType = UiEvent::Type::Paint; mType = UiEvent::Type::Paint;
} }
@ -11,8 +13,18 @@ PaintEvent::~PaintEvent()
} }
std::unique_ptr<PaintEvent> PaintEvent::Create() std::unique_ptr<PaintEvent> PaintEvent::Create(ThemeManager* themesManager, FontsManager* fontsManager)
{ {
return std::make_unique<PaintEvent>(); return std::make_unique<PaintEvent>(themesManager, fontsManager);
}
ThemeManager* PaintEvent::getThemesManager() const
{
return mThemeManager;
}
FontsManager* PaintEvent::getFontsManager() const
{
return mFontsManager;
} }

View file

@ -4,13 +4,23 @@
#include "UiEvent.h" #include "UiEvent.h"
class ThemeManager;
class FontsManager;
class PaintEvent : public UiEvent class PaintEvent : public UiEvent
{ {
public: public:
PaintEvent(); PaintEvent(ThemeManager* themesManager, FontsManager* fontsManager);
static std::unique_ptr<PaintEvent> Create(ThemeManager* themesManager, FontsManager* fontsManager);
~PaintEvent(); ~PaintEvent();
static std::unique_ptr<PaintEvent> Create(); ThemeManager* getThemesManager() const;
FontsManager* getFontsManager() const;
private:
ThemeManager* mThemeManager{ nullptr };
FontsManager* mFontsManager{ nullptr };
}; };
using PaintEventUPtr = std::unique_ptr<PaintEvent>; using PaintEventUPtr = std::unique_ptr<PaintEvent>;

View file

@ -9,6 +9,7 @@
#include "TextNode.h" #include "TextNode.h"
#include "TransformNode.h" #include "TransformNode.h"
#include "RootNode.h" #include "RootNode.h"
#include "ThemeManager.h"
#include "Window.h" #include "Window.h"
#include "FileLogger.h" #include "FileLogger.h"
@ -22,8 +23,8 @@ Widget::Widget()
mRootNode(std::make_unique<TransformNode>()), mRootNode(std::make_unique<TransformNode>()),
mChildren(), mChildren(),
mBorderThickness(0), mBorderThickness(0),
mBackgroundColor(Color(255, 255, 255)), mBackground(ThemeToken::SystemToken::Primary),
mBorderColor(Color(0, 0, 0)), mBorder(ThemeToken::SystemToken::Outline),
mVisible(true) mVisible(true)
{ {
mName = "Widget"; 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; mMaterialDirty = true;
} }
} }
@ -239,8 +240,8 @@ void Widget::updateBackground(const PaintEvent* event)
if (mMaterialDirty) if (mMaterialDirty)
{ {
mBackgroundNode->setFillColor(mBackgroundColor); mBackgroundNode->setFillColor(event->getThemesManager()->getColor(mBackground));
mBackgroundNode->setStrokeColor(mBorderColor); mBackgroundNode->setStrokeColor(event->getThemesManager()->getColor(mBorder));
mBackgroundNode->setStrokeThickness(mBorderThickness); mBackgroundNode->setStrokeThickness(mBorderThickness);
} }

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "FontItem.h" #include "FontItem.h"
#include "Color.h" #include "ITheme.h"
#include "WidgetState.h" #include "WidgetState.h"
#include "BoxGeometry.h" #include "BoxGeometry.h"
@ -47,7 +47,7 @@ public:
virtual bool onKeyboardEvent(const KeyboardEvent* event); virtual bool onKeyboardEvent(const KeyboardEvent* event);
void setBackgroundColor(const Color& color); void setBackground(ThemeToken::SystemToken token);
void setVisible(bool visible); void setVisible(bool visible);
@ -78,8 +78,9 @@ protected:
std::vector<std::unique_ptr<Widget> > mChildren; std::vector<std::unique_ptr<Widget> > mChildren;
unsigned mBorderThickness{0}; unsigned mBorderThickness{0};
Color mBackgroundColor; ThemeToken::SystemToken mBackground;
Color mBorderColor; ThemeToken::SystemToken mBorder;
bool mVisible{true}; bool mVisible{true};
std::unique_ptr<RectangleNode> mBackgroundNode; std::unique_ptr<RectangleNode> mBackgroundNode;

View file

@ -13,7 +13,8 @@ DesktopManager::DesktopManager(AbstractDesktopApp* application)
mKeyboard(Keyboard::Create()), mKeyboard(Keyboard::Create()),
mUiApplication(application), mUiApplication(application),
mEventManager(EventManager::Create()), mEventManager(EventManager::Create()),
mFontsManager(FontsManager::Create()) mFontsManager(FontsManager::Create()),
mThemeManager(std::make_unique<ThemeManager>())
{ {
mWindowManager = WindowManager::Create(this); mWindowManager = WindowManager::Create(this);
} }
@ -38,6 +39,11 @@ FontsManager* DesktopManager::getFontsManager() const
return mFontsManager.get(); return mFontsManager.get();
} }
ThemeManager* DesktopManager::getThemeManager() const
{
return mThemeManager.get();
}
void DesktopManager::onKeyboardEvent(const KeyboardEvent* event) void DesktopManager::onKeyboardEvent(const KeyboardEvent* event)
{ {
mWindowManager->onKeyboardEvent(event); mWindowManager->onKeyboardEvent(event);

View file

@ -5,14 +5,18 @@
#include "Keyboard.h" #include "Keyboard.h"
#include "Screen.h" #include "Screen.h"
#include "KeyboardEvent.h" #include "KeyboardEvent.h"
#include "PaintEvent.h" #include "PaintEvent.h"
#include "MouseEvent.h" #include "MouseEvent.h"
#include "WindowManager.h"
#include "UiEvent.h" #include "UiEvent.h"
#include "AbstractApp.h" #include "AbstractApp.h"
#include "EventManager.h" #include "EventManager.h"
#include "FontsManager.h" #include "FontsManager.h"
#include "WindowManager.h"
#include "ThemeManager.h"
class AbstractDesktopApp; class AbstractDesktopApp;
@ -35,6 +39,8 @@ public:
FontsManager* getFontsManager() const; FontsManager* getFontsManager() const;
ThemeManager* getThemeManager() const;
void addScreen(ScreenPtr screen); void addScreen(ScreenPtr screen);
mt::Screen* getDefaultScreen() const; mt::Screen* getDefaultScreen() const;
@ -57,11 +63,13 @@ public:
private: private:
std::vector<ScreenPtr> mScreens; std::vector<ScreenPtr> mScreens;
KeyboardUPtr mKeyboard;
FontsManagerPtr mFontsManager; FontsManagerPtr mFontsManager;
WindowManagerUPtr mWindowManager; WindowManagerUPtr mWindowManager;
KeyboardUPtr mKeyboard;
EventManagerUPtr mEventManager; EventManagerUPtr mEventManager;
std::unique_ptr<ThemeManager> mThemeManager;
AbstractDesktopApp* mUiApplication; AbstractDesktopApp* mUiApplication;
}; };

View file

@ -86,7 +86,7 @@ void Win32Window::createNative(Win32ApplicationContext* context, DesktopManager*
void Win32Window::onPaintMessage() void Win32Window::onPaintMessage()
{ {
mDesktopManager->onUiEvent(PaintEvent::Create()); mDesktopManager->onUiEvent(PaintEvent::Create(mDesktopManager->getThemeManager(), mDesktopManager->getFontsManager()));
mWindow->doPaint(nullptr); mWindow->doPaint(nullptr);
} }