diff options
author | crupest <crupest@outlook.com> | 2021-04-02 20:36:15 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-04-02 20:36:15 +0800 |
commit | 4bc40b874d63442faf42fecc789f15db0a80e440 (patch) | |
tree | 6cdad9d6107207a1d4a5b1247b7e28793fd5dc15 | |
parent | 854865677c5af4f7010b6f5a5f8bf6b0aad49480 (diff) | |
download | cru-4bc40b874d63442faf42fecc789f15db0a80e440.tar.gz cru-4bc40b874d63442faf42fecc789f15db0a80e440.tar.bz2 cru-4bc40b874d63442faf42fecc789f15db0a80e440.zip |
...
-rw-r--r-- | include/cru/ui/UiManager.hpp | 12 | ||||
-rw-r--r-- | include/cru/ui/render/ScrollBar.hpp | 68 | ||||
-rw-r--r-- | src/ui/UiManager.cpp | 38 | ||||
-rw-r--r-- | src/ui/render/ScrollBar.cpp | 143 |
4 files changed, 173 insertions, 88 deletions
diff --git a/include/cru/ui/UiManager.hpp b/include/cru/ui/UiManager.hpp index 6c0d9500..b9af0065 100644 --- a/include/cru/ui/UiManager.hpp +++ b/include/cru/ui/UiManager.hpp @@ -2,10 +2,15 @@ #include "Base.hpp" #include "controls/Base.hpp" +#include "cru/platform/graphics/Brush.hpp" +#include "cru/ui/helper/ClickDetector.hpp" +#include "render/ScrollBar.hpp" #include "style/StyleRuleSet.hpp" +#include <gsl/pointers> #include <memory> #include <string> +#include <unordered_map> namespace cru::ui { struct ThemeResources { @@ -18,6 +23,13 @@ struct ThemeResources { style::StyleRuleSet text_box_style; style::StyleRuleSet menu_item_style; + + std::shared_ptr<platform::graphics::IBrush> scroll_bar_colllapsed_thumb_brush; + std::unordered_map< + render::ScrollBarBrushUsageKind, + std::unordered_map<helper::ClickState, + std::shared_ptr<platform::graphics::IBrush>>> + scroll_bar_brushes; }; class UiManager : public Object { diff --git a/include/cru/ui/render/ScrollBar.hpp b/include/cru/ui/render/ScrollBar.hpp index 3293e9d0..f72aef9b 100644 --- a/include/cru/ui/render/ScrollBar.hpp +++ b/include/cru/ui/render/ScrollBar.hpp @@ -3,16 +3,19 @@ #include "cru/common/Base.hpp" #include "cru/common/Event.hpp" #include "cru/platform/graphics/Base.hpp" +#include "cru/platform/graphics/Brush.hpp" #include "cru/platform/graphics/Geometry.hpp" #include "cru/platform/graphics/Painter.hpp" #include "cru/platform/gui/Cursor.hpp" #include "cru/platform/gui/UiApplication.hpp" #include "cru/ui/Base.hpp" #include "cru/ui/controls/Control.hpp" +#include "cru/ui/helper/ClickDetector.hpp" #include <gsl/pointers> #include <memory> #include <optional> +#include <unordered_map> namespace cru::ui::render { class ScrollRenderObject; @@ -34,6 +37,8 @@ enum class ScrollBarAreaKind { Thumb }; +enum class ScrollBarBrushUsageKind { Arrow, ArrowBackground, Slot, Thumb }; + class ScrollBar : public Object { public: ScrollBar(gsl::not_null<ScrollRenderObject*> render_object, @@ -61,23 +66,27 @@ class ScrollBar : public Object { void UninstallHandlers() { InstallHandlers(nullptr); } gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> - GetCollapsedThumbBrush() const; - gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> - GetExpandedThumbBrush() const; - gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> - GetExpandedSlotBrush() const; - gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> - GetExpandedArrowBrush() const; - gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> - GetExpandedArrowBackgroundBrush() const; + GetCollapsedThumbBrush(); + // Brush could be nullptr to use the theme brush. + void SetCollapsedThumbBrush( + std::shared_ptr<platform::graphics::IBrush> brush); + gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> GetBrush( + ScrollBarBrushUsageKind kind, helper::ClickState click_state); + // Brush could be nullptr to use the theme brush. + void SetBrush(ScrollBarBrushUsageKind kind, helper::ClickState click_state, + std::shared_ptr<platform::graphics::IBrush> brush); protected: void OnDraw(platform::graphics::IPainter* painter, bool expand); - virtual void DrawUpArrow(platform::graphics::IPainter* painter, - const Rect& area) = 0; - virtual void DrawDownArrow(platform::graphics::IPainter* painter, - const Rect& area) = 0; + virtual void DrawUpArrow( + platform::graphics::IPainter* painter, const Rect& area, + gsl::not_null<platform::graphics::IBrush*> arrow_brush, + gsl::not_null<platform::graphics::IBrush*> background_brush) = 0; + virtual void DrawDownArrow( + platform::graphics::IPainter* painter, const Rect& area, + gsl::not_null<platform::graphics::IBrush*> arrow_brush, + gsl::not_null<platform::graphics::IBrush*> background_brush) = 0; std::optional<ScrollBarAreaKind> ExpandedHitTest(const Point& point); @@ -113,10 +122,11 @@ class ScrollBar : public Object { bool is_expanded_ = false; std::shared_ptr<platform::graphics::IBrush> collapsed_thumb_brush_; - std::shared_ptr<platform::graphics::IBrush> expanded_thumb_brush_; - std::shared_ptr<platform::graphics::IBrush> expanded_slot_brush_; - std::shared_ptr<platform::graphics::IBrush> expanded_arrow_brush_; - std::shared_ptr<platform::graphics::IBrush> expanded_arrow_background_brush_; + std::unordered_map< + ScrollBarBrushUsageKind, + std::unordered_map<helper::ClickState, + std::shared_ptr<platform::graphics::IBrush>>> + brushes_; Rect move_thumb_thumb_original_rect_; std::optional<Point> move_thumb_start_; @@ -141,10 +151,14 @@ class HorizontalScrollBar : public ScrollBar { ~HorizontalScrollBar() override = default; protected: - void DrawUpArrow(platform::graphics::IPainter* painter, - const Rect& area) override; - void DrawDownArrow(platform::graphics::IPainter* painter, - const Rect& area) override; + void DrawUpArrow( + platform::graphics::IPainter* painter, const Rect& area, + gsl::not_null<platform::graphics::IBrush*> arrow_brush, + gsl::not_null<platform::graphics::IBrush*> background_brush) override; + void DrawDownArrow( + platform::graphics::IPainter* painter, const Rect& area, + gsl::not_null<platform::graphics::IBrush*> arrow_brush, + gsl::not_null<platform::graphics::IBrush*> background_brush) override; bool IsShowBar() override; @@ -166,10 +180,14 @@ class VerticalScrollBar : public ScrollBar { ~VerticalScrollBar() override = default; protected: - void DrawUpArrow(platform::graphics::IPainter* painter, - const Rect& area) override; - void DrawDownArrow(platform::graphics::IPainter* painter, - const Rect& area) override; + void DrawUpArrow( + platform::graphics::IPainter* painter, const Rect& area, + gsl::not_null<platform::graphics::IBrush*> arrow_brush, + gsl::not_null<platform::graphics::IBrush*> background_brush) override; + void DrawDownArrow( + platform::graphics::IPainter* painter, const Rect& area, + gsl::not_null<platform::graphics::IBrush*> arrow_brush, + gsl::not_null<platform::graphics::IBrush*> background_brush) override; bool IsShowBar() override; diff --git a/src/ui/UiManager.cpp b/src/ui/UiManager.cpp index 7981aa86..65490f6d 100644 --- a/src/ui/UiManager.cpp +++ b/src/ui/UiManager.cpp @@ -9,6 +9,8 @@ #include "cru/platform/gui/Cursor.hpp" #include "cru/platform/gui/UiApplication.hpp" #include "cru/ui/Base.hpp" +#include "cru/ui/helper/ClickDetector.hpp" +#include "cru/ui/render/ScrollBar.hpp" #include "cru/ui/style/ApplyBorderStyleInfo.hpp" #include "cru/ui/style/Condition.hpp" #include "cru/ui/style/Styler.hpp" @@ -113,6 +115,42 @@ 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 7f69c1e2..198e0a6e 100644 --- a/src/ui/render/ScrollBar.cpp +++ b/src/ui/render/ScrollBar.cpp @@ -10,9 +10,10 @@ #include "cru/platform/gui/Base.hpp" #include "cru/platform/gui/Cursor.hpp" #include "cru/ui/Base.hpp" +#include "cru/ui/UiManager.hpp" #include "cru/ui/events/UiEvent.hpp" +#include "cru/ui/helper/ClickDetector.hpp" #include "cru/ui/render/ScrollRenderObject.hpp" -#include "gsl/gsl_assert" #include <algorithm> #include <cassert> @@ -49,19 +50,6 @@ std::unique_ptr<platform::graphics::IGeometry> CreateScrollBarArrowGeometry() { ScrollBar::ScrollBar(gsl::not_null<ScrollRenderObject*> render_object, Direction direction) : render_object_(render_object), direction_(direction) { - // TODO: Use theme resource and delete this. - - auto graphics_factory = GetUiApplication()->GetInstance()->GetGraphFactory(); - - collapsed_thumb_brush_ = - graphics_factory->CreateSolidColorBrush(colors::gray.WithAlpha(128)); - expanded_thumb_brush_ = graphics_factory->CreateSolidColorBrush(colors::gray); - expanded_slot_brush_ = - graphics_factory->CreateSolidColorBrush(colors::seashell); - expanded_arrow_brush_ = graphics_factory->CreateSolidColorBrush(colors::gray); - expanded_arrow_background_brush_ = - graphics_factory->CreateSolidColorBrush(colors::seashell); - arrow_geometry_ = CreateScrollBarArrowGeometry(); } @@ -218,33 +206,37 @@ void ScrollBar::InstallHandlers(controls::Control* control) { } gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> -ScrollBar::GetCollapsedThumbBrush() const { - // TODO: Read theme resource. - return collapsed_thumb_brush_; -} - -gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> -ScrollBar::GetExpandedThumbBrush() const { - // TODO: Read theme resource. - return expanded_thumb_brush_; +ScrollBar::GetCollapsedThumbBrush() { + return collapsed_thumb_brush_ ? collapsed_thumb_brush_ + : UiManager::GetInstance() + ->GetThemeResources() + ->scroll_bar_colllapsed_thumb_brush; } -gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> -ScrollBar::GetExpandedSlotBrush() const { - // TODO: Read theme resource. - return expanded_slot_brush_; +void ScrollBar::SetCollapsedThumbBrush( + std::shared_ptr<platform::graphics::IBrush> brush) { + if (brush == collapsed_thumb_brush_) return; + collapsed_thumb_brush_ = std::move(brush); + render_object_->InvalidatePaint(); } -gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> -ScrollBar::GetExpandedArrowBrush() const { - // TODO: Read theme resource. - return expanded_arrow_brush_; +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); } -gsl::not_null<std::shared_ptr<platform::graphics::IBrush>> -ScrollBar::GetExpandedArrowBackgroundBrush() const { - // TODO: Read theme resource. - return expanded_arrow_background_brush_; +// Brush could be nullptr to use the theme brush. +void ScrollBar::SetBrush(ScrollBarBrushUsageKind kind, + helper::ClickState click_state, + std::shared_ptr<platform::graphics::IBrush> brush) { + if (brushes_[kind][click_state] == brush) return; + brushes_[kind][click_state] = std::move(brush); + render_object_->InvalidatePaint(); } void ScrollBar::OnDraw(platform::graphics::IPainter* painter, @@ -252,9 +244,16 @@ void ScrollBar::OnDraw(platform::graphics::IPainter* painter, if (is_expanded) { auto thumb_rect = GetExpandedAreaRect(ScrollBarAreaKind::Thumb); if (thumb_rect) - painter->FillRectangle(*thumb_rect, GetExpandedThumbBrush().get().get()); + painter->FillRectangle( + *thumb_rect, + GetBrush(ScrollBarBrushUsageKind::Thumb, helper::ClickState::None) + .get() + .get()); - auto slot_brush = GetExpandedSlotBrush().get().get(); + auto slot_brush = + GetBrush(ScrollBarBrushUsageKind::Slot, helper::ClickState::None) + .get() + .get(); auto up_slot_rect = GetExpandedAreaRect(ScrollBarAreaKind::UpSlot); if (up_slot_rect) painter->FillRectangle(*up_slot_rect, slot_brush); @@ -262,11 +261,25 @@ 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_background_brush = + GetBrush(ScrollBarBrushUsageKind::ArrowBackground, + helper::ClickState::None) + .get() + .get(); + auto up_arrow = GetExpandedAreaRect(ScrollBarAreaKind::UpArrow); - if (up_arrow) this->DrawUpArrow(painter, *up_arrow); + if (up_arrow) + this->DrawUpArrow(painter, *up_arrow, arrow_brush, + arrow_background_brush); auto down_arrow = GetExpandedAreaRect(ScrollBarAreaKind::DownArrow); - if (down_arrow) this->DrawDownArrow(painter, *down_arrow); + if (down_arrow) + this->DrawDownArrow(painter, *down_arrow, arrow_brush, + arrow_background_brush); } else { auto optional_rect = GetCollapsedThumbRect(); if (optional_rect) { @@ -327,27 +340,29 @@ HorizontalScrollBar::HorizontalScrollBar( gsl::not_null<ScrollRenderObject*> render_object) : ScrollBar(render_object, Direction::Horizontal) {} -void HorizontalScrollBar::DrawUpArrow(platform::graphics::IPainter* painter, - const Rect& area) { - painter->FillRectangle(area, GetExpandedArrowBackgroundBrush().get().get()); +void HorizontalScrollBar::DrawUpArrow( + platform::graphics::IPainter* painter, const Rect& area, + gsl::not_null<platform::graphics::IBrush*> arrow_brush, + gsl::not_null<platform::graphics::IBrush*> background_brush) { + painter->FillRectangle(area, background_brush.get()); platform::graphics::util::WithTransform( painter, Matrix::Translation(area.GetCenter()), - [this](platform::graphics::IPainter* painter) { - painter->FillGeometry(arrow_geometry_.get(), - GetExpandedArrowBrush().get().get()); + [this, arrow_brush](platform::graphics::IPainter* painter) { + painter->FillGeometry(arrow_geometry_.get(), arrow_brush.get()); }); } -void HorizontalScrollBar::DrawDownArrow(platform::graphics::IPainter* painter, - const Rect& area) { - painter->FillRectangle(area, GetExpandedArrowBackgroundBrush().get().get()); +void HorizontalScrollBar::DrawDownArrow( + platform::graphics::IPainter* painter, const Rect& area, + gsl::not_null<platform::graphics::IBrush*> arrow_brush, + gsl::not_null<platform::graphics::IBrush*> background_brush) { + painter->FillRectangle(area, background_brush.get()); platform::graphics::util::WithTransform( painter, Matrix::Rotation(180) * Matrix::Translation(area.GetCenter()), - [this](platform::graphics::IPainter* painter) { - painter->FillGeometry(arrow_geometry_.get(), - GetExpandedArrowBrush().get().get()); + [this, arrow_brush](platform::graphics::IPainter* painter) { + painter->FillGeometry(arrow_geometry_.get(), arrow_brush.get()); }); } @@ -466,27 +481,29 @@ VerticalScrollBar::VerticalScrollBar( gsl::not_null<ScrollRenderObject*> render_object) : ScrollBar(render_object, Direction::Vertical) {} -void VerticalScrollBar::DrawUpArrow(platform::graphics::IPainter* painter, - const Rect& area) { - painter->FillRectangle(area, GetExpandedArrowBackgroundBrush().get().get()); +void VerticalScrollBar::DrawUpArrow( + platform::graphics::IPainter* painter, const Rect& area, + gsl::not_null<platform::graphics::IBrush*> arrow_brush, + gsl::not_null<platform::graphics::IBrush*> background_brush) { + painter->FillRectangle(area, background_brush.get()); platform::graphics::util::WithTransform( painter, Matrix::Rotation(90) * Matrix::Translation(area.GetCenter()), - [this](platform::graphics::IPainter* painter) { - painter->FillGeometry(arrow_geometry_.get(), - GetExpandedArrowBrush().get().get()); + [this, arrow_brush](platform::graphics::IPainter* painter) { + painter->FillGeometry(arrow_geometry_.get(), arrow_brush.get()); }); } -void VerticalScrollBar::DrawDownArrow(platform::graphics::IPainter* painter, - const Rect& area) { - painter->FillRectangle(area, GetExpandedArrowBackgroundBrush().get().get()); +void VerticalScrollBar::DrawDownArrow( + platform::graphics::IPainter* painter, const Rect& area, + gsl::not_null<platform::graphics::IBrush*> arrow_brush, + gsl::not_null<platform::graphics::IBrush*> background_brush) { + painter->FillRectangle(area, background_brush.get()); platform::graphics::util::WithTransform( painter, Matrix::Rotation(270) * Matrix::Translation(area.GetCenter()), - [this](platform::graphics::IPainter* painter) { - painter->FillGeometry(arrow_geometry_.get(), - GetExpandedArrowBrush().get().get()); + [this, arrow_brush](platform::graphics::IPainter* painter) { + painter->FillGeometry(arrow_geometry_.get(), arrow_brush.get()); }); } |