Start adding themed buttons.

This commit is contained in:
jmsgrogan 2023-01-18 10:47:13 +00:00
parent dfbc87cb09
commit 942cc2539c
18 changed files with 781 additions and 173 deletions

View file

@ -9,13 +9,12 @@
#include "MouseEvent.h" #include "MouseEvent.h"
#include "FileLogger.h" #include "FileLogger.h"
Button::Button() Button::Button(ButtonData::Component component)
: Widget(), : Widget(),
mLabel(), mLabel(),
mCachedColor(ThemeToken::SystemToken::Primary),
mClickedColor(ThemeToken::SystemToken::Secondary),
mClickFunc() mClickFunc()
{ {
mStyle.mComponent = component;
mName = "Button"; mName = "Button";
} }
@ -24,9 +23,9 @@ Button::~Button()
} }
std::unique_ptr<Button> Button::Create() std::unique_ptr<Button> Button::Create(ButtonData::Component component)
{ {
return std::make_unique<Button>(); return std::make_unique<Button>(component);
} }
void Button::setOnClickFunction(clickFunc func) void Button::setOnClickFunction(clickFunc func)
@ -48,8 +47,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 = mBackground; mStyle.mState = ButtonData::State::Pressed;
setBackground(mClickedColor); setBackground(mStyle.getContainerColor());
if(mClickFunc) if(mClickFunc)
{ {
mClickFunc(this); mClickFunc(this);
@ -57,7 +56,8 @@ void Button::onMyMouseEvent(const MouseEvent* event)
} }
else if(event->getAction() == MouseEvent::Action::Released) else if(event->getAction() == MouseEvent::Action::Released)
{ {
setBackground(mCachedColor); mStyle.mState = ButtonData::State::Enabled;
setBackground(mStyle.getContainerColor());
} }
} }

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "ButtonData.h"
#include "Widget.h" #include "Widget.h"
#include "Color.h" #include "Color.h"
@ -15,11 +16,11 @@ class Button : public Widget
public: public:
using clickFunc = std::function<void(Widget* self)>; using clickFunc = std::function<void(Widget* self)>;
Button(); Button(ButtonData::Component component = ButtonData::Component::Elevated);
~Button(); ~Button();
static std::unique_ptr<Button> Create(); static std::unique_ptr<Button> Create(ButtonData::Component component = ButtonData::Component::Elevated);
void setLabel(const std::string& text); void setLabel(const std::string& text);
@ -34,10 +35,10 @@ protected:
void updateLabel(const PaintEvent* event); void updateLabel(const PaintEvent* event);
private: private:
ButtonData mStyle;
std::string mLabel; std::string mLabel;
clickFunc mClickFunc; clickFunc mClickFunc;
ThemeToken::SystemToken mCachedColor;
ThemeToken::SystemToken mClickedColor;
std::unique_ptr<TextNode> mTextNode; std::unique_ptr<TextNode> mTextNode;
bool mContentDirty{true}; bool mContentDirty{true};

View file

@ -0,0 +1,347 @@
#include "ButtonData.h"
#include "OpacityTokens.h"
const float ButtonData::DEFAULT_CONTAINER_OPACITY = 1;
const std::unordered_map<ButtonData::ComponentState, Theme::Sys::Color> ButtonData::mContainerColors = {
{{Component::Elevated, State::Enabled}, Theme::Sys::Color::Surface},
{{Component::Elevated, State::Disabled}, Theme::Sys::Color::On_Surface},
{{Component::Elevated, State::Hovered}, Theme::Sys::Color::Primary},
{{Component::Elevated, State::Focused}, Theme::Sys::Color::Primary},
{{Component::Elevated, State::Pressed}, Theme::Sys::Color::Primary},
{{Component::Filled, State::Enabled}, Theme::Sys::Color::Primary},
{{Component::Filled, State::Disabled}, Theme::Sys::Color::On_Surface},
{{Component::Filled, State::Hovered}, Theme::Sys::Color::On_Primary},
{{Component::Filled, State::Focused}, Theme::Sys::Color::On_Primary},
{{Component::Filled, State::Pressed}, Theme::Sys::Color::On_Primary},
};
const std::unordered_map<ButtonData::ComponentState, Theme::Sys::Color> ButtonData::mContainerShadowColors = {
{{Component::Elevated, State::Enabled}, Theme::Sys::Color::Shadow},
{{Component::Filled, State::Enabled}, Theme::Sys::Color::Shadow},
};
const std::unordered_map<ButtonData::ComponentState, Theme::Sys::Elevation> ButtonData::mContainerElevations = {
{{Component::Elevated, State::Enabled}, Theme::Sys::Elevation::Level_1},
{{Component::Elevated, State::Disabled}, Theme::Sys::Elevation::Level_0},
{{Component::Elevated, State::Hovered}, Theme::Sys::Elevation::Level_2},
{{Component::Elevated, State::Focused}, Theme::Sys::Elevation::Level_1},
{{Component::Filled, State::Enabled}, Theme::Sys::Elevation::Level_0},
{{Component::Filled, State::Disabled}, Theme::Sys::Elevation::Level_0},
{{Component::Filled, State::Hovered}, Theme::Sys::Elevation::Level_1},
{{Component::Filled, State::Focused}, Theme::Sys::Elevation::Level_0},
{{Component::Filled, State::Pressed}, Theme::Sys::Elevation::Level_0},
};
const std::unordered_map<ButtonData::ComponentState, float> ButtonData::mContainerOpacity = {
{{Component::Elevated, State::Disabled}, 0.12},
{{Component::Elevated, State::Hovered}, OpacityTokens::getValue(Theme::Sys::StateLayerOpacity::State::Hover)},
{{Component::Elevated, State::Focused}, OpacityTokens::getValue(Theme::Sys::StateLayerOpacity::State::Focus)},
{{Component::Elevated, State::Pressed}, OpacityTokens::getValue(Theme::Sys::StateLayerOpacity::State::Pressed)},
{{Component::Filled, State::Disabled}, 0.12},
{{Component::Filled, State::Hovered}, OpacityTokens::getValue(Theme::Sys::StateLayerOpacity::State::Hover)},
{{Component::Filled, State::Focused}, OpacityTokens::getValue(Theme::Sys::StateLayerOpacity::State::Focus)},
{{Component::Filled, State::Pressed}, OpacityTokens::getValue(Theme::Sys::StateLayerOpacity::State::Pressed)},
};
const std::unordered_map<ButtonData::ComponentState, Theme::Sys::Color> ButtonData::mLabelTextColors = {
{{Component::Elevated, State::Enabled}, Theme::Sys::Color::Primary},
{{Component::Elevated, State::Disabled}, Theme::Sys::Color::On_Surface},
{{Component::Elevated, State::Hovered}, Theme::Sys::Color::Primary},
{{Component::Elevated, State::Focused}, Theme::Sys::Color::Primary},
{{Component::Elevated, State::Pressed}, Theme::Sys::Color::Primary},
{{Component::Filled, State::Enabled}, Theme::Sys::Color::On_Primary},
{{Component::Filled, State::Disabled}, Theme::Sys::Color::On_Surface},
{{Component::Filled, State::Hovered}, Theme::Sys::Color::On_Primary},
{{Component::Filled, State::Focused}, Theme::Sys::Color::On_Primary},
{{Component::Filled, State::Pressed}, Theme::Sys::Color::On_Primary},
};
const std::unordered_map<ButtonData::ComponentState, Theme::Sys::Typescale> ButtonData::mLabelTypescales = {
{{Component::Elevated, State::Enabled}, Theme::Sys::Typescale::Label_Large},
{{Component::Filled, State::Enabled}, Theme::Sys::Typescale::Label_Large},
};
const std::unordered_map<ButtonData::ComponentState, float> ButtonData::mLabelTextOpacity = {
{{Component::Elevated, State::Disabled}, 0.38},
{{Component::Filled, State::Disabled}, 0.38},
};
const std::unordered_map<ButtonData::ComponentState, Theme::Sys::Color> ButtonData::mIconColors = {
{{Component::Elevated, State::Enabled}, Theme::Sys::Color::Primary},
{{Component::Elevated, State::Disabled}, Theme::Sys::Color::On_Surface},
{{Component::Elevated, State::Hovered}, Theme::Sys::Color::Primary},
{{Component::Elevated, State::Focused}, Theme::Sys::Color::Primary},
{{Component::Elevated, State::Pressed}, Theme::Sys::Color::Primary},
{{Component::Filled, State::Enabled}, Theme::Sys::Color::On_Primary},
{{Component::Filled, State::Disabled}, Theme::Sys::Color::On_Surface},
{{Component::Filled, State::Hovered}, Theme::Sys::Color::On_Primary},
{{Component::Filled, State::Focused}, Theme::Sys::Color::On_Primary},
{{Component::Filled, State::Pressed}, Theme::Sys::Color::On_Primary},
};
const std::unordered_map<ButtonData::ComponentState, float> ButtonData::mIconOpacity = {
{{Component::Elevated, State::Disabled}, 0.38},
{{Component::Filled, State::Disabled}, 0.38},
};
Theme::Sys::Color ButtonData::getContainerColor() const
{
if (auto iter = mContainerColors.find(std::make_pair(mComponent, mState)); iter != mContainerColors.end())
{
return iter->second;
}
else
{
if (mState == State::Enabled)
{
return DEFAULT_CONTAINER_COLOR;
}
else if (auto iter = mContainerColors.find(std::make_pair(mComponent, State::Enabled)); iter != mContainerColors.end())
{
return iter->second;
}
else
{
return DEFAULT_CONTAINER_COLOR;
}
}
}
Theme::Sys::Color ButtonData::getContainerShadowColor() const
{
if (auto iter = mContainerShadowColors.find(std::make_pair(mComponent, mState)); iter != mContainerShadowColors.end())
{
return iter->second;
}
else
{
if (mState == State::Enabled)
{
return DEFAULT_CONTAINER_SHADOW_COLOR;
}
else if (auto iter = mContainerShadowColors.find(std::make_pair(mComponent, State::Enabled)); iter != mContainerShadowColors.end())
{
return iter->second;
}
else
{
return DEFAULT_CONTAINER_SHADOW_COLOR;
}
}
}
Theme::Sys::Color ButtonData::getContainerSurfaceTintColor() const
{
switch (mComponent)
{
case Component::Elevated:
return Theme::Sys::Color::Surface_Tint_Color;
default:
return Theme::Sys::Color::None;
}
}
Theme::Sys::Color ButtonData::getLabelTextColor() const
{
if (auto iter = mLabelTextColors.find(std::make_pair(mComponent, mState)); iter != mLabelTextColors.end())
{
return iter->second;
}
else
{
if (mState == State::Enabled)
{
return getContainerColor();
}
else if (auto iter = mLabelTextColors.find(std::make_pair(mComponent, State::Enabled)); iter != mLabelTextColors.end())
{
return iter->second;
}
else
{
return getContainerColor();
}
}
}
Theme::Sys::Elevation ButtonData::getContainerElevation() const
{
if (auto iter = mContainerElevations.find(std::make_pair(mComponent, mState)); iter != mContainerElevations.end())
{
return iter->second;
}
else
{
if (mState == State::Enabled)
{
return DEFAULT_CONTAINER_ELEVATION;
}
else if (auto iter = mContainerElevations.find(std::make_pair(mComponent, State::Enabled)); iter != mContainerElevations.end())
{
return iter->second;
}
else
{
return DEFAULT_CONTAINER_ELEVATION;
}
}
}
float ButtonData::getStateLayerOverlayOpacity() const
{
if (auto iter = mContainerOpacity.find(std::make_pair(mComponent, mState)); iter != mContainerOpacity.end())
{
return iter->second;
}
else
{
if (mState == State::Enabled)
{
return DEFAULT_CONTAINER_OPACITY;
}
else if (auto iter = mContainerOpacity.find(std::make_pair(mComponent, State::Enabled)); iter != mContainerOpacity.end())
{
return iter->second;
}
else
{
return DEFAULT_CONTAINER_OPACITY;
}
}
}
Theme::Sys::Typescale ButtonData::getLabelTypescale() const
{
switch (mComponent)
{
case Component::Elevated:
return Theme::Sys::Typescale::Label_Large;
default:
return Theme::Sys::Typescale::Label_Large;
}
}
bool ButtonData::canHaveIcon() const
{
switch (mComponent)
{
case Component::Elevated:
return true;
default:
return false;
}
}
Theme::Sys::Color ButtonData::getIconColor() const
{
switch (mComponent)
{
case Component::Elevated:
return Theme::Sys::Color::Primary;
default:
return Theme::Sys::Color::None;
}
}
unsigned ButtonData::getContainerHeight() const
{
switch (mComponent)
{
case Component::Elevated:
case Component::Filled:
return 40;
default:
return 40;
}
}
unsigned ButtonData::getContainerCornerRadius() const
{
switch (mComponent)
{
case Component::Elevated:
case Component::Filled:
return 20;
default:
return 20;
}
}
unsigned ButtonData::getIconSize() const
{
switch (mComponent)
{
case Component::Elevated:
case Component::Filled:
return 18;
default:
return 18;
}
}
unsigned ButtonData::getLeftRightPadding() const
{
switch (mComponent)
{
case Component::Elevated:
case Component::Filled:
return 24;
default:
return 24;
}
}
unsigned ButtonData::getLeftPaddingWithIcon() const
{
switch (mComponent)
{
case Component::Elevated:
case Component::Filled:
return 16;
default:
return 16;
}
}
unsigned ButtonData::getRightPaddingWithIcon() const
{
switch (mComponent)
{
case Component::Elevated:
case Component::Filled:
return 24;
default:
return 24;
}
}
unsigned ButtonData::getBetweenElementPadding() const
{
switch (mComponent)
{
case Component::Elevated:
case Component::Filled:
return 8;
default:
return 8;
}
}
ButtonData::LabelTextAlign ButtonData::getLabelTextAlign() const
{
switch (mComponent)
{
case Component::Elevated:
case Component::Filled:
return ButtonData::LabelTextAlign::Centre;
default:
return ButtonData::LabelTextAlign::Centre;
}
}

View file

@ -0,0 +1,86 @@
#pragma once
#include "ITheme.h"
#include "FontTokens.h"
#include "ElevationTokens.h"
#include <unordered_map>
class ButtonData
{
public:
enum class State
{
Enabled,
Disabled,
Hovered,
Focused,
Pressed
};
enum class Component
{
Elevated,
Filled,
Filled_Tonal,
Outlined,
Text,
Icon,
Segmented,
Floating_Action,
Extended_Floating_Action
};
enum class LabelTextAlign
{
Centre
};
Theme::Sys::Color getContainerColor() const;
Theme::Sys::Color getContainerShadowColor() const;
Theme::Sys::Color getContainerSurfaceTintColor() const;
Theme::Sys::Elevation getContainerElevation() const;
Theme::Sys::Color getLabelTextColor() const;
Theme::Sys::Typescale getLabelTypescale() const;
bool canHaveIcon() const;
Theme::Sys::Color getIconColor() const;
float getStateLayerOverlayOpacity() const;
unsigned getContainerHeight() const;
unsigned getContainerCornerRadius() const;
unsigned getIconSize() const;
unsigned getLeftRightPadding() const;
unsigned getLeftPaddingWithIcon() const;
unsigned getRightPaddingWithIcon() const;
unsigned getBetweenElementPadding() const;
LabelTextAlign getLabelTextAlign() const;
State mState{ State::Enabled };
Component mComponent{ Component::Elevated };
private:
using ComponentState = std::pair<Component, State>;
static const std::unordered_map<ComponentState, Theme::Sys::Color> mContainerColors;
static const std::unordered_map<ComponentState, Theme::Sys::Color> mContainerShadowColors;
static const std::unordered_map<ComponentState, Theme::Sys::Elevation> mContainerElevations;
static const std::unordered_map<ComponentState, float> mContainerOpacity;
static const std::unordered_map<ComponentState, Theme::Sys::Color> mLabelTextColors;
static const std::unordered_map<ComponentState, Theme::Sys::Typescale> mLabelTypescales;
static const std::unordered_map<ComponentState, float> mLabelTextOpacity;
static const std::unordered_map<ComponentState, Theme::Sys::Color> mIconColors;
static const std::unordered_map<ComponentState, float> mIconOpacity;
static const Theme::Sys::Color DEFAULT_CONTAINER_COLOR{ Theme::Sys::Color::None };
static const Theme::Sys::Color DEFAULT_CONTAINER_SHADOW_COLOR{ Theme::Sys::Color::None };
static const Theme::Sys::Elevation DEFAULT_CONTAINER_ELEVATION{ Theme::Sys::Elevation::Level_0 };
static const float DEFAULT_CONTAINER_OPACITY;
};

View file

@ -2,6 +2,7 @@ set(MODULE_NAME ui_controls)
list(APPEND HEADERS list(APPEND HEADERS
Button.h Button.h
ButtonData.h
ButtonGroup.h ButtonGroup.h
Label.h Label.h
HorizontalSpacer.h HorizontalSpacer.h
@ -12,6 +13,7 @@ list(APPEND HEADERS
list(APPEND LIB_INCLUDES list(APPEND LIB_INCLUDES
Button.cpp Button.cpp
ButtonData.cpp
ButtonGroup.cpp ButtonGroup.cpp
Label.cpp Label.cpp
HorizontalSpacer.cpp HorizontalSpacer.cpp

View file

@ -32,6 +32,12 @@ list(APPEND LIB_INCLUDES
style/LightTheme.cpp style/LightTheme.cpp
style/ColorPalette.h style/ColorPalette.h
style/ColorPalette.cpp style/ColorPalette.cpp
style/FontTokens.h
style/FontTokens.cpp
style/ElevationTokens.h
style/OpacityTokens.h
IconNode.h
IconNode.cpp
) )
add_library(${MODULE_NAME} SHARED ${LIB_INCLUDES}) add_library(${MODULE_NAME} SHARED ${LIB_INCLUDES})
@ -43,7 +49,7 @@ target_include_directories(${MODULE_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/ui_events ${CMAKE_CURRENT_SOURCE_DIR}/ui_events
${CMAKE_CURRENT_SOURCE_DIR}/desktop_elements ${CMAKE_CURRENT_SOURCE_DIR}/desktop_elements
) )
target_link_libraries(${MODULE_NAME} PUBLIC core geometry graphics visual_elements image) target_link_libraries(${MODULE_NAME} PUBLIC core geometry graphics visual_elements image web)
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER src/ui) set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER src/ui)

View file

View file

View file

@ -1,48 +1,48 @@
#include "ColorPalette.h" #include "ColorPalette.h"
const std::unordered_map<ColorPaletteToken, std::string> ColorPalette::mPaletteColors = { const std::unordered_map<Theme::Ref::Color, std::string> ColorPalette::mPaletteColors = {
{ColorPaletteToken::Primary_10, "#21005E"}, {Theme::Ref::Color::Primary_10, "#21005E"},
{ColorPaletteToken::Primary_20, "#371E73"}, {Theme::Ref::Color::Primary_20, "#371E73"},
{ColorPaletteToken::Primary_30, "#4F378B"}, {Theme::Ref::Color::Primary_30, "#4F378B"},
{ColorPaletteToken::Primary_40, "#6750A4"}, {Theme::Ref::Color::Primary_40, "#6750A4"},
{ColorPaletteToken::Primary_80, "#D0BCFF"}, {Theme::Ref::Color::Primary_80, "#D0BCFF"},
{ColorPaletteToken::Primary_90, "#EADDFF"}, {Theme::Ref::Color::Primary_90, "#EADDFF"},
{ColorPaletteToken::Primary_100, "#FFFFFF"}, {Theme::Ref::Color::Primary_100, "#FFFFFF"},
{ColorPaletteToken::Secondary_10, "#1E192B"}, {Theme::Ref::Color::Secondary_10, "#1E192B"},
{ColorPaletteToken::Secondary_20, "#332D41"}, {Theme::Ref::Color::Secondary_20, "#332D41"},
{ColorPaletteToken::Secondary_30, "#4A4458"}, {Theme::Ref::Color::Secondary_30, "#4A4458"},
{ColorPaletteToken::Secondary_40, "#625B71"}, {Theme::Ref::Color::Secondary_40, "#625B71"},
{ColorPaletteToken::Secondary_80, "#CCC2DC"}, {Theme::Ref::Color::Secondary_80, "#CCC2DC"},
{ColorPaletteToken::Secondary_90, "#E8DEF8"}, {Theme::Ref::Color::Secondary_90, "#E8DEF8"},
{ColorPaletteToken::Secondary_100, "#FFFFFF"}, {Theme::Ref::Color::Secondary_100, "#FFFFFF"},
{ColorPaletteToken::Tertiary_10, "#370B1E"}, {Theme::Ref::Color::Tertiary_10, "#370B1E"},
{ColorPaletteToken::Tertiary_20, "#492532"}, {Theme::Ref::Color::Tertiary_20, "#492532"},
{ColorPaletteToken::Tertiary_30, "#633B48"}, {Theme::Ref::Color::Tertiary_30, "#633B48"},
{ColorPaletteToken::Tertiary_40, "#7D5260"}, {Theme::Ref::Color::Tertiary_40, "#7D5260"},
{ColorPaletteToken::Tertiary_80, "#EFB8C8"}, {Theme::Ref::Color::Tertiary_80, "#EFB8C8"},
{ColorPaletteToken::Tertiary_90, "#FFD8E4"}, {Theme::Ref::Color::Tertiary_90, "#FFD8E4"},
{ColorPaletteToken::Tertiary_100, "#FFFFFF"}, {Theme::Ref::Color::Tertiary_100, "#FFFFFF"},
{ColorPaletteToken::Neutral_0, "#000000"}, {Theme::Ref::Color::Neutral_0, "#000000"},
{ColorPaletteToken::Neutral_10, "#1C1B1F"}, {Theme::Ref::Color::Neutral_10, "#1C1B1F"},
{ColorPaletteToken::Neutral_20, "#313033"}, {Theme::Ref::Color::Neutral_20, "#313033"},
{ColorPaletteToken::Neutral_90, "#E6E1E5"}, {Theme::Ref::Color::Neutral_90, "#E6E1E5"},
{ColorPaletteToken::Neutral_95, "#F4EFF4"}, {Theme::Ref::Color::Neutral_95, "#F4EFF4"},
{ColorPaletteToken::Neutral_99, "#FFFBFE"}, {Theme::Ref::Color::Neutral_99, "#FFFBFE"},
{ColorPaletteToken::Neutral_Variant_30, "#49454F"}, {Theme::Ref::Color::Neutral_Variant_30, "#49454F"},
{ColorPaletteToken::Neutral_Variant_50, "#79747E"}, {Theme::Ref::Color::Neutral_Variant_50, "#79747E"},
{ColorPaletteToken::Neutral_Variant_60, "#938F99"}, {Theme::Ref::Color::Neutral_Variant_60, "#938F99"},
{ColorPaletteToken::Neutral_Variant_80, "#CAC4D0"}, {Theme::Ref::Color::Neutral_Variant_80, "#CAC4D0"},
{ColorPaletteToken::Neutral_Variant_90, "#E7E0EC"}, {Theme::Ref::Color::Neutral_Variant_90, "#E7E0EC"},
{ColorPaletteToken::Error_10, "#410E0B"}, {Theme::Ref::Color::Error_10, "#410E0B"},
{ColorPaletteToken::Error_20, "#601410"}, {Theme::Ref::Color::Error_20, "#601410"},
{ColorPaletteToken::Error_30, "#8C1D18"}, {Theme::Ref::Color::Error_30, "#8C1D18"},
{ColorPaletteToken::Error_40, "#B3261E"}, {Theme::Ref::Color::Error_40, "#B3261E"},
{ColorPaletteToken::Error_80, "#F2B8B5"}, {Theme::Ref::Color::Error_80, "#F2B8B5"},
{ColorPaletteToken::Error_90, "#F9DEDC"}, {Theme::Ref::Color::Error_90, "#F9DEDC"},
{ColorPaletteToken::Error_100, "#FFFFFF"}, {Theme::Ref::Color::Error_100, "#FFFFFF"},
}; };
Color ColorPalette::getColor(ColorPaletteToken token) Color ColorPalette::getColor(Theme::Ref::Color token)
{ {
if (auto iter = mPaletteColors.find(token); iter != mPaletteColors.end()) if (auto iter = mPaletteColors.find(token); iter != mPaletteColors.end())
{ {

View file

@ -5,7 +5,11 @@
#include <unordered_map> #include <unordered_map>
#include <string> #include <string>
enum class ColorPaletteToken namespace Theme
{
namespace Ref
{
enum class Color
{ {
Primary_10, Primary_10,
Primary_20, Primary_20,
@ -49,12 +53,14 @@ enum class ColorPaletteToken
Error_90, Error_90,
Error_100 Error_100
}; };
}
}
class ColorPalette class ColorPalette
{ {
public: public:
static Color getColor(ColorPaletteToken token); static Color getColor(Theme::Ref::Color token);
private: private:
static const std::unordered_map<ColorPaletteToken, std::string> mPaletteColors; static const std::unordered_map<Theme::Ref::Color, std::string> mPaletteColors;
}; };

View file

@ -0,0 +1,43 @@
#pragma once
namespace Theme
{
namespace Sys
{
enum class Elevation
{
Level_0,
Level_1,
Level_2,
Level_3,
Level_4,
Level_5,
};
}
}
class ElevationToken
{
public:
static unsigned getValue(Theme::Sys::Elevation token)
{
switch (token)
{
case Theme::Sys::Elevation::Level_0:
return 0;
case Theme::Sys::Elevation::Level_1:
return 1;
case Theme::Sys::Elevation::Level_2:
return 3;
case Theme::Sys::Elevation::Level_3:
return 6;
case Theme::Sys::Elevation::Level_4:
return 8;
case Theme::Sys::Elevation::Level_5:
return 12;
default:
return 0;
}
}
};

View file

View file

@ -0,0 +1,72 @@
#pragma once
#include <string>
namespace Theme
{
namespace Ref
{
namespace Typeface
{
enum class Font
{
Plain,
Brand
};
enum class Weight
{
Weight_Regular,
Weight_Medium
};
}
};
};
namespace Theme
{
namespace Sys
{
enum class Typescale
{
Display_Large,
Display_Medium,
Display_Small,
Headline_Large,
Headline_Medium,
Headline_Small,
Title_Large,
Title_Medium,
Title_Small,
Label_Large,
Label_Medium,
Label_Small,
Body_Large,
Body_Medium,
Body_Small,
Label_Large,
Label_Medium,
Label_Small
};
};
};
class FontTokens
{
static std::string getFont(Theme::Ref::Typeface::Font font);
static Theme::Ref::Typeface::Font getFont(Theme::Sys::Typescale typescale);
static unsigned getLineHeight(Theme::Sys::Typescale typescale);
static unsigned getSize(Theme::Sys::Typescale typescale);
static unsigned getTracking(Theme::Sys::Typescale typescale);
static unsigned getWeight(Theme::Ref::Typeface::Font font);
static Theme::Ref::Typeface::Font getWeight(Theme::Sys::Typescale typescale);
};

View file

@ -2,9 +2,11 @@
#include "ColorPalette.h" #include "ColorPalette.h"
namespace ThemeToken namespace Theme
{ {
enum class SystemToken namespace Sys
{
enum class Color
{ {
Primary, Primary,
Primary_Container, Primary_Container,
@ -35,12 +37,14 @@ namespace ThemeToken
Inverse_Surface, Inverse_Surface,
Inverse_On_Surface, Inverse_On_Surface,
Inverse_Primary, Inverse_Primary,
Scrim Scrim,
None
}; };
} }
}
class ITheme class ITheme
{ {
public: public:
virtual Color getColor(ThemeToken::SystemToken token) const = 0; virtual Color getColor(Theme::Sys::Color token) const = 0;
}; };

View file

@ -2,40 +2,40 @@
#include "ColorPalette.h" #include "ColorPalette.h"
const std::unordered_map<ThemeToken::SystemToken, ColorPaletteToken> LightTheme::mPalette = { const std::unordered_map<Theme::Sys::Color, Theme::Ref::Color> LightTheme::mPalette = {
{ThemeToken::SystemToken::Primary, ColorPaletteToken::Primary_40}, {Theme::Sys::Color::Primary, Theme::Ref::Color::Primary_40},
{ThemeToken::SystemToken::Primary_Container, ColorPaletteToken::Primary_90}, {Theme::Sys::Color::Primary_Container, Theme::Ref::Color::Primary_90},
{ThemeToken::SystemToken::Secondary, ColorPaletteToken::Secondary_40}, {Theme::Sys::Color::Secondary, Theme::Ref::Color::Secondary_40},
{ThemeToken::SystemToken::Secondary_Container, ColorPaletteToken::Secondary_90}, {Theme::Sys::Color::Secondary_Container, Theme::Ref::Color::Secondary_90},
{ThemeToken::SystemToken::Tertiary, ColorPaletteToken::Tertiary_40}, {Theme::Sys::Color::Tertiary, Theme::Ref::Color::Tertiary_40},
{ThemeToken::SystemToken::Tertiary_Container, ColorPaletteToken::Tertiary_90}, {Theme::Sys::Color::Tertiary_Container, Theme::Ref::Color::Tertiary_90},
{ThemeToken::SystemToken::Surface, ColorPaletteToken::Neutral_99}, {Theme::Sys::Color::Surface, Theme::Ref::Color::Neutral_99},
{ThemeToken::SystemToken::Surface_Variant, ColorPaletteToken::Neutral_Variant_90}, {Theme::Sys::Color::Surface_Variant, Theme::Ref::Color::Neutral_Variant_90},
{ThemeToken::SystemToken::Background, ColorPaletteToken::Neutral_99}, {Theme::Sys::Color::Background, Theme::Ref::Color::Neutral_99},
{ThemeToken::SystemToken::Error, ColorPaletteToken::Error_40}, {Theme::Sys::Color::Error, Theme::Ref::Color::Error_40},
{ThemeToken::SystemToken::Error_Container, ColorPaletteToken::Error_90}, {Theme::Sys::Color::Error_Container, Theme::Ref::Color::Error_90},
{ThemeToken::SystemToken::On_Primary, ColorPaletteToken::Primary_100}, {Theme::Sys::Color::On_Primary, Theme::Ref::Color::Primary_100},
{ThemeToken::SystemToken::On_Primary_Container, ColorPaletteToken::Primary_10}, {Theme::Sys::Color::On_Primary_Container, Theme::Ref::Color::Primary_10},
{ThemeToken::SystemToken::On_Secondary, ColorPaletteToken::Secondary_100}, {Theme::Sys::Color::On_Secondary, Theme::Ref::Color::Secondary_100},
{ThemeToken::SystemToken::On_Secondary_Container, ColorPaletteToken::Secondary_10}, {Theme::Sys::Color::On_Secondary_Container, Theme::Ref::Color::Secondary_10},
{ThemeToken::SystemToken::On_Tertiary, ColorPaletteToken::Tertiary_100}, {Theme::Sys::Color::On_Tertiary, Theme::Ref::Color::Tertiary_100},
{ThemeToken::SystemToken::On_Tertiary_Container, ColorPaletteToken::Tertiary_10}, {Theme::Sys::Color::On_Tertiary_Container, Theme::Ref::Color::Tertiary_10},
{ThemeToken::SystemToken::On_Surface, ColorPaletteToken::Neutral_10}, {Theme::Sys::Color::On_Surface, Theme::Ref::Color::Neutral_10},
{ThemeToken::SystemToken::On_Surface_Variant, ColorPaletteToken::Neutral_Variant_30}, {Theme::Sys::Color::On_Surface_Variant, Theme::Ref::Color::Neutral_Variant_30},
{ThemeToken::SystemToken::On_Error, ColorPaletteToken::Error_100}, {Theme::Sys::Color::On_Error, Theme::Ref::Color::Error_100},
{ThemeToken::SystemToken::On_Error_Container, ColorPaletteToken::Error_10}, {Theme::Sys::Color::On_Error_Container, Theme::Ref::Color::Error_10},
{ThemeToken::SystemToken::On_Background, ColorPaletteToken::Neutral_10}, {Theme::Sys::Color::On_Background, Theme::Ref::Color::Neutral_10},
{ThemeToken::SystemToken::Outline, ColorPaletteToken::Neutral_Variant_50}, {Theme::Sys::Color::Outline, Theme::Ref::Color::Neutral_Variant_50},
{ThemeToken::SystemToken::Ouline_Variant, ColorPaletteToken::Neutral_Variant_80}, {Theme::Sys::Color::Ouline_Variant, Theme::Ref::Color::Neutral_Variant_80},
{ThemeToken::SystemToken::Shadow, ColorPaletteToken::Neutral_0}, {Theme::Sys::Color::Shadow, Theme::Ref::Color::Neutral_0},
{ThemeToken::SystemToken::Surface_Tint_Color, ColorPaletteToken::Primary_40}, {Theme::Sys::Color::Surface_Tint_Color, Theme::Ref::Color::Primary_40},
{ThemeToken::SystemToken::Inverse_Surface, ColorPaletteToken::Neutral_20}, {Theme::Sys::Color::Inverse_Surface, Theme::Ref::Color::Neutral_20},
{ThemeToken::SystemToken::Inverse_On_Surface, ColorPaletteToken::Neutral_95}, {Theme::Sys::Color::Inverse_On_Surface, Theme::Ref::Color::Neutral_95},
{ThemeToken::SystemToken::Inverse_Primary, ColorPaletteToken::Primary_80}, {Theme::Sys::Color::Inverse_Primary, Theme::Ref::Color::Primary_80},
{ThemeToken::SystemToken::Scrim, ColorPaletteToken::Neutral_0}, {Theme::Sys::Color::Scrim, Theme::Ref::Color::Neutral_0},
}; };
Color LightTheme::getColor(ThemeToken::SystemToken token) const Color LightTheme::getColor(Theme::Sys::Color token) const
{ {
if (auto iter = mPalette.find(token); iter != mPalette.end()) if (auto iter = mPalette.find(token); iter != mPalette.end())
{ {

View file

@ -8,8 +8,8 @@
class LightTheme : public ITheme class LightTheme : public ITheme
{ {
public: public:
Color getColor(ThemeToken::SystemToken token) const override; Color getColor(Theme::Sys::Color token) const override;
private: private:
static const std::unordered_map<ThemeToken::SystemToken, ColorPaletteToken> mPalette; static const std::unordered_map<Theme::Sys::Color, Theme::Ref::Color> mPalette;
}; };

View file

@ -0,0 +1,39 @@
#pragma once
namespace Theme
{
namespace Sys
{
namespace StateLayerOpacity
{
enum class State
{
Hover,
Focus,
Pressed,
Dragged
};
}
}
}
class OpacityTokens
{
public:
static float getValue(Theme::Sys::StateLayerOpacity::State token)
{
switch (token)
{
case Theme::Sys::StateLayerOpacity::State::Hover:
return 0.08;
case Theme::Sys::StateLayerOpacity::State::Focus:
return 0.12;
case Theme::Sys::StateLayerOpacity::State::Pressed:
return 0.12;
case Theme::Sys::StateLayerOpacity::State::Dragged:
return 0.16;
default:
return 0.0;
}
}
};

View file

@ -1,9 +1,11 @@
#pragma once #pragma once
struct WidgetState enum class WidgetState
{ {
bool mIsSelected{ false }; ENABLED,
bool mIsHovered{ false }; DISABLED,
bool mIsPressed{ false }; HOVERED,
bool mIsFocused{ false }; FOCUSED,
PRESSED,
SELECTED
}; };