diff options
author | crupest <crupest@outlook.com> | 2020-12-03 22:44:57 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-12-03 22:44:57 +0800 |
commit | b29fb11be2f043a3438a50d8942b4ad7d2af0034 (patch) | |
tree | 5847f7b880b43f2596bc10b46fc52c6f028a7a58 /include/cru | |
parent | 93a8bf8b967817031cd2798cdaedfa73f867dead (diff) | |
download | cru-b29fb11be2f043a3438a50d8942b4ad7d2af0034.tar.gz cru-b29fb11be2f043a3438a50d8942b4ad7d2af0034.tar.bz2 cru-b29fb11be2f043a3438a50d8942b4ad7d2af0034.zip |
...
Diffstat (limited to 'include/cru')
-rw-r--r-- | include/cru/common/ClonablePtr.hpp | 7 | ||||
-rw-r--r-- | include/cru/common/Event.hpp | 4 | ||||
-rw-r--r-- | include/cru/ui/Base.hpp | 12 | ||||
-rw-r--r-- | include/cru/ui/UiManager.hpp | 5 | ||||
-rw-r--r-- | include/cru/ui/controls/Base.hpp | 22 | ||||
-rw-r--r-- | include/cru/ui/controls/Button.hpp | 5 | ||||
-rw-r--r-- | include/cru/ui/controls/Control.hpp | 5 | ||||
-rw-r--r-- | include/cru/ui/controls/TextBox.hpp | 14 | ||||
-rw-r--r-- | include/cru/ui/helper/ClickDetector.hpp | 2 | ||||
-rw-r--r-- | include/cru/ui/render/BorderRenderObject.hpp | 2 | ||||
-rw-r--r-- | include/cru/ui/style/Condition.hpp | 42 | ||||
-rw-r--r-- | include/cru/ui/style/StyleRuleSet.hpp | 55 | ||||
-rw-r--r-- | include/cru/ui/style/Styler.hpp | 7 |
13 files changed, 127 insertions, 55 deletions
diff --git a/include/cru/common/ClonablePtr.hpp b/include/cru/common/ClonablePtr.hpp index 47a1d3bd..5e4b80c9 100644 --- a/include/cru/common/ClonablePtr.hpp +++ b/include/cru/common/ClonablePtr.hpp @@ -8,13 +8,16 @@ namespace cru { template <typename TClonable> class ClonablePtr { + template <typename T> + friend class ClonablePtr; + public: using element_type = typename std::unique_ptr<TClonable>::element_type; using pointer = typename std::unique_ptr<TClonable>::pointer; ClonablePtr() = default; ClonablePtr(std::nullptr_t) noexcept : ptr_(nullptr) {} - ClonablePtr(pointer p) noexcept : ptr_(p) {} + explicit ClonablePtr(pointer p) noexcept : ptr_(p) {} ClonablePtr(std::unique_ptr<element_type>&& p) noexcept : ptr_(std::move(p)) {} template <typename O, @@ -52,7 +55,7 @@ class ClonablePtr { } ClonablePtr& operator=(const ClonablePtr& other) { if (this != &other) { - ptr_ = std::unique_ptr<element_type>(other.ptr->Clone()); + ptr_ = std::unique_ptr<element_type>(other.ptr_->Clone()); } return *this; } diff --git a/include/cru/common/Event.hpp b/include/cru/common/Event.hpp index 59502527..7f7b4dd4 100644 --- a/include/cru/common/Event.hpp +++ b/include/cru/common/Event.hpp @@ -98,7 +98,7 @@ struct IBaseEvent { using SpyOnlyHandler = std::function<void()>; public: - virtual EventRevoker AddHandler(SpyOnlyHandler handler) = 0; + virtual EventRevoker AddSpyOnlyHandler(SpyOnlyHandler handler) = 0; }; // Provides an interface of event. @@ -147,7 +147,7 @@ class Event : public details::EventBase, public IEvent<TEventArgs> { CRU_DEFAULT_MOVE(Event) ~Event() = default; - EventRevoker AddHandler(SpyOnlyHandler handler) override { + EventRevoker AddSpyOnlyHandler(SpyOnlyHandler handler) override { const auto token = current_token_++; this->handler_data_list_.emplace_back(token, std::move(handler)); return CreateRevoker(token); diff --git a/include/cru/ui/Base.hpp b/include/cru/ui/Base.hpp index 8595258d..57beb723 100644 --- a/include/cru/ui/Base.hpp +++ b/include/cru/ui/Base.hpp @@ -40,6 +40,10 @@ namespace render { class RenderObject; } +namespace style { +class StyleRuleSet; +} + //-------------------- region: basic types -------------------- namespace internal { constexpr int align_start = 0; @@ -87,14 +91,6 @@ inline bool operator!=(const CornerRadius& left, const CornerRadius& right) { return !(left == right); } -struct BorderStyle { - std::shared_ptr<platform::graphics::IBrush> border_brush; - Thickness border_thickness; - CornerRadius border_radius; - std::shared_ptr<platform::graphics::IBrush> foreground_brush; - std::shared_ptr<platform::graphics::IBrush> background_brush; -}; - class CanvasPaintEventArgs { public: CanvasPaintEventArgs(platform::graphics::IPainter* painter, diff --git a/include/cru/ui/UiManager.hpp b/include/cru/ui/UiManager.hpp index 64599d99..e747fcd2 100644 --- a/include/cru/ui/UiManager.hpp +++ b/include/cru/ui/UiManager.hpp @@ -2,6 +2,7 @@ #include "Base.hpp" #include "controls/Base.hpp" +#include "style/StyleRuleSet.hpp" #include <memory> #include <string> @@ -13,8 +14,8 @@ struct ThemeResources { std::shared_ptr<platform::graphics::IBrush> text_brush; std::shared_ptr<platform::graphics::IBrush> text_selection_brush; std::shared_ptr<platform::graphics::IBrush> caret_brush; - controls::ButtonStyle button_style; - controls::TextBoxBorderStyle text_box_border_style; + style::StyleRuleSet button_style; + style::StyleRuleSet text_box_style; }; class UiManager : public Object { diff --git a/include/cru/ui/controls/Base.hpp b/include/cru/ui/controls/Base.hpp index 82c31d1e..7c85cdb2 100644 --- a/include/cru/ui/controls/Base.hpp +++ b/include/cru/ui/controls/Base.hpp @@ -1,24 +1,4 @@ #pragma once #include "../Base.hpp" -namespace cru::ui::controls { -using ButtonStateStyle = ui::BorderStyle; - -struct ButtonStyle { - // corresponds to ClickState::None - ButtonStateStyle normal; - // corresponds to ClickState::Hover - ButtonStateStyle hover; - // corresponds to ClickState::Press - ButtonStateStyle press; - // corresponds to ClickState::PressInactive - ButtonStateStyle press_cancel; -}; - -struct TextBoxBorderStyle { - ui::BorderStyle normal; - ui::BorderStyle hover; - ui::BorderStyle focus; - ui::BorderStyle focus_hover; -}; -} // namespace cru::ui::controls +namespace cru::ui::controls {} // namespace cru::ui::controls diff --git a/include/cru/ui/controls/Button.hpp b/include/cru/ui/controls/Button.hpp index 7299c146..1c9b1216 100644 --- a/include/cru/ui/controls/Button.hpp +++ b/include/cru/ui/controls/Button.hpp @@ -41,14 +41,9 @@ class Button : public ContentControl, void ApplyBorderStyle(const style::ApplyBorderStyleInfo& style) override; - const ButtonStyle& GetStyle() const { return style_; } - void SetStyle(ButtonStyle style); - private: std::unique_ptr<render::BorderRenderObject> render_object_{}; - ButtonStyle style_; - helper::ClickDetector click_detector_; }; } // namespace cru::ui::controls diff --git a/include/cru/ui/controls/Control.hpp b/include/cru/ui/controls/Control.hpp index 96aad2bd..0d34bc63 100644 --- a/include/cru/ui/controls/Control.hpp +++ b/include/cru/ui/controls/Control.hpp @@ -66,6 +66,9 @@ class Control : public Object { // null to unset void SetCursor(std::shared_ptr<platform::gui::ICursor> cursor); + public: + style::StyleRuleSet* GetStyleRuleSet(); + //*************** region: events *************** public: // Raised when mouse enter the control. Even when the control itself captures @@ -147,5 +150,7 @@ class Control : public Object { bool is_mouse_over_ = false; std::shared_ptr<platform::gui::ICursor> cursor_ = nullptr; + + std::unique_ptr<style::StyleRuleSet> style_rule_set_; }; } // namespace cru::ui::controls diff --git a/include/cru/ui/controls/TextBox.hpp b/include/cru/ui/controls/TextBox.hpp index 91d38c61..75e7cb65 100644 --- a/include/cru/ui/controls/TextBox.hpp +++ b/include/cru/ui/controls/TextBox.hpp @@ -1,5 +1,6 @@ #pragma once #include "NoChildControl.hpp" +#include "IBorderControl.hpp" #include <memory> @@ -7,7 +8,7 @@ namespace cru::ui::controls { template <typename TControl> class TextControlService; -class TextBox : public NoChildControl { +class TextBox : public NoChildControl, public IBorderControl { public: static constexpr std::u16string_view control_type = u"TextBox"; @@ -29,22 +30,13 @@ class TextBox : public NoChildControl { gsl::not_null<render::TextRenderObject*> GetTextRenderObject(); render::ScrollRenderObject* GetScrollRenderObject(); - const TextBoxBorderStyle& GetBorderStyle(); - void SetBorderStyle(TextBoxBorderStyle border_style); - - protected: - void OnMouseHoverChange(bool newHover) override; - - private: - void UpdateBorderStyle(); + void ApplyBorderStyle(const style::ApplyBorderStyleInfo& style) override; private: std::unique_ptr<render::BorderRenderObject> border_render_object_; std::unique_ptr<render::ScrollRenderObject> scroll_render_object_; std::unique_ptr<render::TextRenderObject> text_render_object_; - TextBoxBorderStyle border_style_; - std::unique_ptr<TextControlService<TextBox>> service_; }; } // namespace cru::ui::controls diff --git a/include/cru/ui/helper/ClickDetector.hpp b/include/cru/ui/helper/ClickDetector.hpp index 0df77c60..b58297b1 100644 --- a/include/cru/ui/helper/ClickDetector.hpp +++ b/include/cru/ui/helper/ClickDetector.hpp @@ -71,7 +71,7 @@ class ClickDetector : public Object { private: controls::Control* control_; - ClickState state_; + ClickState state_ = ClickState::None; bool enable_ = true; MouseButton trigger_button_ = mouse_buttons::left | mouse_buttons::right; diff --git a/include/cru/ui/render/BorderRenderObject.hpp b/include/cru/ui/render/BorderRenderObject.hpp index ec0bd52b..3d4f4dad 100644 --- a/include/cru/ui/render/BorderRenderObject.hpp +++ b/include/cru/ui/render/BorderRenderObject.hpp @@ -64,8 +64,6 @@ class BorderRenderObject : public RenderObject { InvalidatePaint(); } - void SetBorderStyle(const BorderStyle& style); - void ApplyBorderStyle(const style::ApplyBorderStyleInfo& style); RenderObject* HitTest(const Point& point) override; diff --git a/include/cru/ui/style/Condition.hpp b/include/cru/ui/style/Condition.hpp index 13ab7764..d5cf16f2 100644 --- a/include/cru/ui/style/Condition.hpp +++ b/include/cru/ui/style/Condition.hpp @@ -21,6 +21,21 @@ class Condition : public Object { virtual Condition* Clone() const = 0; }; +class NoCondition : public Condition { + public: + static ClonablePtr<NoCondition> Create() { + return ClonablePtr<NoCondition>(new NoCondition); + }; + + std::vector<IBaseEvent*> ChangeOn(controls::Control*) const override { + return {}; + } + + bool Judge(controls::Control*) const override { return true; } + + NoCondition* Clone() const override { return new NoCondition; } +}; + class CompoundCondition : public Condition { public: explicit CompoundCondition(std::vector<ClonablePtr<Condition>> conditions); @@ -51,6 +66,10 @@ class OrCondition : public CompoundCondition { class FocusCondition : public Condition { public: + static ClonablePtr<FocusCondition> Create(bool has_focus) { + return ClonablePtr<FocusCondition>(new FocusCondition(has_focus)); + } + explicit FocusCondition(bool has_focus); std::vector<IBaseEvent*> ChangeOn(controls::Control* control) const override; @@ -64,8 +83,31 @@ class FocusCondition : public Condition { bool has_focus_; }; +class HoverCondition : public Condition { + public: + static ClonablePtr<HoverCondition> Create(bool hover) { + return ClonablePtr<HoverCondition>(new HoverCondition(hover)); + } + + explicit HoverCondition(bool hover) : hover_(hover) {} + + std::vector<IBaseEvent*> ChangeOn(controls::Control* control) const override; + bool Judge(controls::Control* control) const override; + + HoverCondition* Clone() const override { return new HoverCondition(hover_); } + + private: + bool hover_; +}; + class ClickStateCondition : public Condition { public: + static ClonablePtr<ClickStateCondition> Create( + helper::ClickState click_state) { + return ClonablePtr<ClickStateCondition>( + new ClickStateCondition(click_state)); + } + explicit ClickStateCondition(helper::ClickState click_state); std::vector<IBaseEvent*> ChangeOn(controls::Control* control) const override; diff --git a/include/cru/ui/style/StyleRuleSet.hpp b/include/cru/ui/style/StyleRuleSet.hpp index e69de29b..3ec71730 100644 --- a/include/cru/ui/style/StyleRuleSet.hpp +++ b/include/cru/ui/style/StyleRuleSet.hpp @@ -0,0 +1,55 @@ +#pragma once +#include "StyleRule.hpp" +#include "cru/common/Base.hpp" +#include "cru/common/Event.hpp" +#include "gsl/gsl_assert" + +namespace cru::ui::style { +class StyleRuleSet : public Object { + public: + StyleRuleSet() : control_(nullptr) {} + explicit StyleRuleSet(controls::Control* control) : control_(control) {} + + CRU_DELETE_COPY(StyleRuleSet) + CRU_DELETE_MOVE(StyleRuleSet) + + ~StyleRuleSet() override = default; + + public: + gsl::index GetSize() const { return static_cast<gsl::index>(rules_.size()); } + const std::vector<StyleRule>& GetRules() const { return rules_; } + + void AddStyleRule(StyleRule rule) { + AddStyleRule(std::move(rule), GetSize()); + } + + void AddStyleRule(StyleRule rule, gsl::index index); + + template <typename Iter> + void AddStyleRuleRange(Iter start, Iter end, gsl::index index) { + Expects(index >= 0 && index <= GetSize()); + rules_.insert(rules_.cbegin() + index, std::move(start), std::move(end)); + UpdateChangeListener(); + UpdateStyle(); + } + + void RemoveStyleRule(gsl::index index, gsl::index count = 1); + + void Clear() { RemoveStyleRule(0, GetSize()); } + + void Set(const StyleRuleSet& other); + + const StyleRule& operator[](gsl::index index) const { return rules_[index]; } + + private: + void UpdateChangeListener(); + void UpdateStyle(); + + private: + controls::Control* control_; + + std::vector<StyleRule> rules_; + + EventRevokerListGuard guard_; +}; +} // namespace cru::ui::style diff --git a/include/cru/ui/style/Styler.hpp b/include/cru/ui/style/Styler.hpp index 2aece114..10b169b1 100644 --- a/include/cru/ui/style/Styler.hpp +++ b/include/cru/ui/style/Styler.hpp @@ -2,19 +2,24 @@ #include "../Base.hpp" #include "ApplyBorderStyleInfo.hpp" #include "cru/common/Base.hpp" +#include "cru/common/ClonablePtr.hpp" #include <memory> namespace cru::ui::style { class Styler : public Object { public: - virtual void Apply(controls::Control* control) const; + virtual void Apply(controls::Control* control) const = 0; virtual Styler* Clone() const = 0; }; class BorderStyler : public Styler { public: + static ClonablePtr<BorderStyler> Create(ApplyBorderStyleInfo style) { + return ClonablePtr<BorderStyler>(new BorderStyler(std::move(style))); + } + explicit BorderStyler(ApplyBorderStyleInfo style); void Apply(controls::Control* control) const override; |