diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/StringUtil.cpp | 26 | ||||
-rw-r--r-- | src/platform/Color.cpp | 38 | ||||
-rw-r--r-- | src/ui/ThemeManager.cpp | 54 | ||||
-rw-r--r-- | src/ui/UiManager.cpp | 36 | ||||
-rw-r--r-- | src/ui/render/ScrollBar.cpp | 87 |
5 files changed, 178 insertions, 63 deletions
diff --git a/src/common/StringUtil.cpp b/src/common/StringUtil.cpp index 0cadc545..bf95f88d 100644 --- a/src/common/StringUtil.cpp +++ b/src/common/StringUtil.cpp @@ -284,4 +284,30 @@ gsl::index Utf16NextWord(std::u16string_view str, gsl::index position, return Utf16ForwardUntil(str, position, IsSpace); } } + +char16_t ToLower(char16_t c) { + if (c >= u'A' && c <= u'Z') { + return c - u'A' + u'a'; + } + return c; +} + +char16_t ToUpper(char16_t c) { + if (c >= u'a' && c <= u'z') { + return c - u'a' + u'A'; + } + return c; +} + +std::u16string ToLower(std::u16string_view s) { + std::u16string result; + for (auto c : s) result.push_back(ToLower(c)); + return result; +} + +std::u16string ToUpper(std::u16string_view s) { + std::u16string result; + for (auto c : s) result.push_back(ToUpper(c)); + return result; +} } // namespace cru diff --git a/src/platform/Color.cpp b/src/platform/Color.cpp index 325cf413..d1c60217 100644 --- a/src/platform/Color.cpp +++ b/src/platform/Color.cpp @@ -1,12 +1,48 @@ #include "cru/platform/Color.hpp" #include <cstdint> +#include <gsl/gsl> #include <optional> #include <stdexcept> +#include <string> #include <string_view> -#include "gsl/gsl_util" +#include "fmt/core.h" namespace cru::platform { +std::string Color::ToUtf8String() const { + auto to_hex = [](std::uint8_t v) -> char { + return v >= 10 ? v - 10 + 'a' : v + '0'; + }; + + auto to_two_hex_digit = [to_hex](std::uint8_t v) -> std::string { + return {to_hex(v /= 16), to_hex(v %= 16)}; + }; + + std::string result = "#"; + result.append(to_two_hex_digit(alpha)); + result.append(to_two_hex_digit(red)); + result.append(to_two_hex_digit(green)); + result.append(to_two_hex_digit(blue)); + return result; +} + +std::u16string Color::ToString() const { + auto to_hex = [](std::uint8_t v) -> char16_t { + return v >= 10 ? v - 10 + u'a' : v + u'0'; + }; + + auto to_two_hex_digit = [to_hex](std::uint8_t v) -> std::u16string { + return {to_hex(v /= 16), to_hex(v %= 16)}; + }; + + std::u16string result = u"#"; + result.append(to_two_hex_digit(alpha)); + result.append(to_two_hex_digit(red)); + result.append(to_two_hex_digit(green)); + result.append(to_two_hex_digit(blue)); + return result; +} + std::optional<Color> Color::Parse(std::u16string_view string, bool parse_predefined_color) { if (parse_predefined_color) { diff --git a/src/ui/ThemeManager.cpp b/src/ui/ThemeManager.cpp index 993edc34..9311a3df 100644 --- a/src/ui/ThemeManager.cpp +++ b/src/ui/ThemeManager.cpp @@ -1 +1,55 @@ #include "cru/ui/ThemeManager.hpp" + +#include "Helper.hpp" +#include "cru/common/StringUtil.hpp" +#include "cru/platform/graphics/Brush.hpp" +#include "cru/platform/graphics/Factory.hpp" +#include "cru/platform/gui/UiApplication.hpp" + +namespace cru::ui { +ThemeManager* ThemeManager::GetInstance() { + static ThemeManager instance; + return &instance; +} + +ThemeManager::ThemeManager() { Init(); } + +void ThemeManager::Init() { + theme_tree_.put("scrollbar.collapse-thumb.color", + colors::gray.WithAlpha(128).ToUtf8String()); + theme_tree_.put("scrollbar.arrow.normal.color", "black"); + theme_tree_.put("scrollbar.arrow.hover.color", "black"); + theme_tree_.put("scrollbar.arrow.press.color", "black"); + theme_tree_.put("scrollbar.arrow.disable.color", "black"); + theme_tree_.put("scrollbar.arrow-background.normal.color", "seashell"); + theme_tree_.put("scrollbar.arrow-background.hover.color", "seashell"); + theme_tree_.put("scrollbar.arrow-background.press.color", "seashell"); + theme_tree_.put("scrollbar.arrow-background.disable.color", "seashell"); + theme_tree_.put("scrollbar.slot.normal.color", "seashell"); + theme_tree_.put("scrollbar.slot.hover.color", "seashell"); + theme_tree_.put("scrollbar.slot.press.color", "seashell"); + theme_tree_.put("scrollbar.slot.disable.color", "seashell"); + theme_tree_.put("scrollbar.thumb.normal.color", "gray"); + theme_tree_.put("scrollbar.thumb.hover.color", "gray"); + theme_tree_.put("scrollbar.thumb.press.color", "gray"); + theme_tree_.put("scrollbar.thumb.disable.color", "gray"); +} + +gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> +ThemeManager::GetBrush(std::u16string key) { + std::u16string k = ToLower(key); + auto cached_brush_iter = brushes_.find(k); + if (cached_brush_iter != brushes_.cend()) { + return cached_brush_iter->second; + } + + auto color_string = ToUtf16(theme_tree_.get_value<std::string>(ToUtf8(key))); + auto color = Color::Parse(color_string); + if (!color) throw BadThemeResourceException("Value is not a valid color."); + std::shared_ptr<platform::graphics::IBrush> brush = + GetUiApplication()->GetGraphFactory()->CreateSolidColorBrush(*color); + brushes_[k] = brush; + return brush; +} + +} // namespace cru::ui diff --git a/src/ui/UiManager.cpp b/src/ui/UiManager.cpp index 65490f6d..45dd1775 100644 --- a/src/ui/UiManager.cpp +++ b/src/ui/UiManager.cpp @@ -115,42 +115,6 @@ UiManager::UiManager() { BorderStyler::Create( ApplyBorderStyleInfo{std::nullopt, Thickness{0}, CornerRadius{0}}), u"DefaultMenuItem"}); - - theme_resource_.scroll_bar_colllapsed_thumb_brush = - factory->CreateSolidColorBrush(colors::gray.WithAlpha(128)); - theme_resource_.scroll_bar_brushes[render::ScrollBarBrushUsageKind::Arrow] = { - {helper::ClickState::None, factory->CreateSolidColorBrush(colors::black)}, - {helper::ClickState::Hover, - factory->CreateSolidColorBrush(colors::black)}, - {helper::ClickState::Press, - factory->CreateSolidColorBrush(colors::black)}, - {helper::ClickState::PressInactive, - factory->CreateSolidColorBrush(colors::black)}}; - theme_resource_ - .scroll_bar_brushes[render::ScrollBarBrushUsageKind::ArrowBackground] = { - {helper::ClickState::None, - factory->CreateSolidColorBrush(colors::seashell)}, - {helper::ClickState::Hover, - factory->CreateSolidColorBrush(colors::seashell)}, - {helper::ClickState::Press, - factory->CreateSolidColorBrush(colors::seashell)}, - {helper::ClickState::PressInactive, - factory->CreateSolidColorBrush(colors::seashell)}}; - theme_resource_.scroll_bar_brushes[render::ScrollBarBrushUsageKind::Slot] = { - {helper::ClickState::None, - factory->CreateSolidColorBrush(colors::seashell)}, - {helper::ClickState::Hover, - factory->CreateSolidColorBrush(colors::seashell)}, - {helper::ClickState::Press, - factory->CreateSolidColorBrush(colors::seashell)}, - {helper::ClickState::PressInactive, - factory->CreateSolidColorBrush(colors::seashell)}}; - theme_resource_.scroll_bar_brushes[render::ScrollBarBrushUsageKind::Thumb] = { - {helper::ClickState::None, factory->CreateSolidColorBrush(colors::gray)}, - {helper::ClickState::Hover, factory->CreateSolidColorBrush(colors::gray)}, - {helper::ClickState::Press, factory->CreateSolidColorBrush(colors::gray)}, - {helper::ClickState::PressInactive, - factory->CreateSolidColorBrush(colors::gray)}}; } UiManager::~UiManager() = default; diff --git a/src/ui/render/ScrollBar.cpp b/src/ui/render/ScrollBar.cpp index 198e0a6e..fa8e0118 100644 --- a/src/ui/render/ScrollBar.cpp +++ b/src/ui/render/ScrollBar.cpp @@ -10,6 +10,7 @@ #include "cru/platform/gui/Base.hpp" #include "cru/platform/gui/Cursor.hpp" #include "cru/ui/Base.hpp" +#include "cru/ui/ThemeManager.hpp" #include "cru/ui/UiManager.hpp" #include "cru/ui/events/UiEvent.hpp" #include "cru/ui/helper/ClickDetector.hpp" @@ -22,6 +23,7 @@ #include <memory> #include <optional> #include <stdexcept> +#include <string> namespace cru::ui::render { using namespace std::chrono_literals; @@ -36,6 +38,42 @@ constexpr std::array<ScrollBarAreaKind, 5> kScrollBarAreaKindList{ ScrollBarAreaKind::UpSlot, ScrollBarAreaKind::DownSlot, ScrollBarAreaKind::Thumb}; +std::u16string GenerateScrollBarThemeColorKey(ScrollBarBrushUsageKind usage, + ScrollBarBrushStateKind state) { + std::u16string result = u"scrollbar."; + switch (usage) { + case ScrollBarBrushUsageKind::Arrow: + result.append(u"arrow"); + break; + case ScrollBarBrushUsageKind::ArrowBackground: + result.append(u"arrow-background"); + break; + case ScrollBarBrushUsageKind::Slot: + result.append(u"slot"); + break; + case ScrollBarBrushUsageKind::Thumb: + result.append(u"thumb"); + break; + } + result.push_back(u'.'); + switch (state) { + case ScrollBarBrushStateKind::Normal: + result.append(u"normal"); + break; + case ScrollBarBrushStateKind::Hover: + result.append(u"hover"); + break; + case ScrollBarBrushStateKind::Press: + result.append(u"press"); + break; + case ScrollBarBrushStateKind::Disable: + result.append(u"disable"); + break; + } + result.append(u".color"); + return result; +} + namespace { std::unique_ptr<platform::graphics::IGeometry> CreateScrollBarArrowGeometry() { auto geometry_builder = GetGraphFactory()->CreateGeometryBuilder(); @@ -207,10 +245,9 @@ void ScrollBar::InstallHandlers(controls::Control* control) { gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> ScrollBar::GetCollapsedThumbBrush() { - return collapsed_thumb_brush_ ? collapsed_thumb_brush_ - : UiManager::GetInstance() - ->GetThemeResources() - ->scroll_bar_colllapsed_thumb_brush; + return collapsed_thumb_brush_ ? gsl::not_null(collapsed_thumb_brush_) + : ThemeManager::GetInstance()->GetBrush( + u"scrollbar.collapse-thumb.color"); } void ScrollBar::SetCollapsedThumbBrush( @@ -221,21 +258,19 @@ void ScrollBar::SetCollapsedThumbBrush( } gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> ScrollBar::GetBrush( - ScrollBarBrushUsageKind kind, helper::ClickState click_state) { - auto b = brushes_[kind][click_state]; - return b ? b - : UiManager::GetInstance() - ->GetThemeResources() - ->scroll_bar_brushes.at(kind) - .at(click_state); + ScrollBarBrushUsageKind usage, ScrollBarBrushStateKind state) { + auto b = brushes_[usage][state]; + return b ? gsl::not_null(b) + : ThemeManager::GetInstance()->GetBrush( + GenerateScrollBarThemeColorKey(usage, state)); } // Brush could be nullptr to use the theme brush. -void ScrollBar::SetBrush(ScrollBarBrushUsageKind kind, - helper::ClickState click_state, +void ScrollBar::SetBrush(ScrollBarBrushUsageKind usage, + ScrollBarBrushStateKind state, std::shared_ptr<platform::graphics::IBrush> brush) { - if (brushes_[kind][click_state] == brush) return; - brushes_[kind][click_state] = std::move(brush); + if (brushes_[usage][state] == brush) return; + brushes_[usage][state] = std::move(brush); render_object_->InvalidatePaint(); } @@ -244,14 +279,14 @@ void ScrollBar::OnDraw(platform::graphics::IPainter* painter, if (is_expanded) { auto thumb_rect = GetExpandedAreaRect(ScrollBarAreaKind::Thumb); if (thumb_rect) - painter->FillRectangle( - *thumb_rect, - GetBrush(ScrollBarBrushUsageKind::Thumb, helper::ClickState::None) - .get() - .get()); + painter->FillRectangle(*thumb_rect, + GetBrush(ScrollBarBrushUsageKind::Thumb, + ScrollBarBrushStateKind::Normal) + .get() + .get()); auto slot_brush = - GetBrush(ScrollBarBrushUsageKind::Slot, helper::ClickState::None) + GetBrush(ScrollBarBrushUsageKind::Slot, ScrollBarBrushStateKind::Normal) .get() .get(); @@ -261,13 +296,13 @@ void ScrollBar::OnDraw(platform::graphics::IPainter* painter, auto down_slot_rect = GetExpandedAreaRect(ScrollBarAreaKind::DownSlot); if (down_slot_rect) painter->FillRectangle(*down_slot_rect, slot_brush); - auto arrow_brush = - GetBrush(ScrollBarBrushUsageKind::Arrow, helper::ClickState::None) - .get() - .get(); + auto arrow_brush = GetBrush(ScrollBarBrushUsageKind::Arrow, + ScrollBarBrushStateKind::Normal) + .get() + .get(); auto arrow_background_brush = GetBrush(ScrollBarBrushUsageKind::ArrowBackground, - helper::ClickState::None) + ScrollBarBrushStateKind::Normal) .get() .get(); |