From c6baeb6432a4db7433aab4fc8f89cc235473f11a Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 2 Dec 2020 20:50:26 +0800 Subject: ... --- include/cru/ui/style/Condition.hpp | 31 +++++++++++++++++++-- include/cru/ui/style/StyleRule.hpp | 57 ++++++++++++++++++++++++++++++++++++++ include/cru/ui/style/Styler.hpp | 8 ++++++ src/ui/CMakeLists.txt | 2 ++ src/ui/style/Condition.cpp | 17 ++++++++++-- src/ui/style/StyleRule.cpp | 11 ++++++++ 6 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 include/cru/ui/style/StyleRule.hpp create mode 100644 src/ui/style/StyleRule.cpp diff --git a/include/cru/ui/style/Condition.hpp b/include/cru/ui/style/Condition.hpp index 97d29287..c4fd2106 100644 --- a/include/cru/ui/style/Condition.hpp +++ b/include/cru/ui/style/Condition.hpp @@ -5,6 +5,7 @@ #include "cru/ui/controls/IClickableControl.hpp" #include "cru/ui/helper/ClickDetector.hpp" +#include #include #include #include @@ -15,18 +16,26 @@ class Condition : public Object { virtual std::vector ChangeOn( controls::Control* control) const = 0; virtual bool Judge(controls::Control* control) const = 0; + + virtual std::unique_ptr Clone() const = 0; }; class CompoundCondition : public Condition { public: - explicit CompoundCondition(std::vector conditions); + explicit CompoundCondition( + std::vector> conditions); + + const std::vector& GetConditions() const { + return readonly_conditions_; + } - const std::vector& GetConditions() const { return conditions_; } + std::vector> CloneConditions() const; std::vector ChangeOn(controls::Control* control) const override; private: - std::vector conditions_; + std::vector> conditions_; + std::vector readonly_conditions_; }; class AndCondition : public CompoundCondition { @@ -34,6 +43,10 @@ class AndCondition : public CompoundCondition { using CompoundCondition::CompoundCondition; bool Judge(controls::Control* control) const override; + + std::unique_ptr Clone() const override { + return std::make_unique(CloneConditions()); + } }; class OrCondition : public CompoundCondition { @@ -41,6 +54,10 @@ class OrCondition : public CompoundCondition { using CompoundCondition::CompoundCondition; bool Judge(controls::Control* control) const override; + + std::unique_ptr Clone() const override { + return std::make_unique(CloneConditions()); + } }; class FocusCondition : public Condition { @@ -50,6 +67,10 @@ class FocusCondition : public Condition { std::vector ChangeOn(controls::Control* control) const override; bool Judge(controls::Control* control) const override; + std::unique_ptr Clone() const override { + return std::make_unique(has_focus_); + } + private: bool has_focus_; }; @@ -61,6 +82,10 @@ class ClickStateCondition : public Condition { std::vector ChangeOn(controls::Control* control) const override; bool Judge(controls::Control* control) const override; + std::unique_ptr Clone() const override { + return std::make_unique(click_state_); + } + private: helper::ClickState click_state_; }; diff --git a/include/cru/ui/style/StyleRule.hpp b/include/cru/ui/style/StyleRule.hpp new file mode 100644 index 00000000..f1283e24 --- /dev/null +++ b/include/cru/ui/style/StyleRule.hpp @@ -0,0 +1,57 @@ +#pragma once +#include "Condition.hpp" +#include "Styler.hpp" +#include "cru/common/Base.hpp" +#include "cru/ui/Base.hpp" + +#include +#include +#include + +namespace cru::ui::style { +class StyleRule : public Object { + public: + StyleRule(std::unique_ptr condition, + std::unique_ptr styler, std::u16string name = {}); + + StyleRule(const StyleRule& other) + : condition_(other.condition_->Clone()), + styler_(other.styler_->Clone()), + name_(other.name_) {} + + StyleRule& operator=(const StyleRule& other) { + if (this != &other) { + condition_ = other.condition_->Clone(); + styler_ = other.styler_->Clone(); + name_ = other.name_; + } + return *this; + } + + CRU_DEFAULT_MOVE(StyleRule) + + ~StyleRule() override = default; + + public: + const std::u16string& GetName() const { return name_; } + Condition* GetCondition() const { return condition_.get(); } + Styler* GetStyler() const { return styler_.get(); } + + StyleRule WithNewCondition(std::unique_ptr condition, + std::u16string name = {}) const { + return StyleRule{std::move(condition), styler_->Clone(), std::move(name)}; + } + + StyleRule WithNewStyler(std::unique_ptr styler, + std::u16string name = {}) const { + return StyleRule{condition_->Clone(), std::move(styler), std::move(name)}; + } + + bool CheckAndApply(controls::Control* control) const; + + private: + std::unique_ptr condition_; + std::unique_ptr styler_; + std::u16string name_; +}; +} // namespace cru::ui::style diff --git a/include/cru/ui/style/Styler.hpp b/include/cru/ui/style/Styler.hpp index 89731033..4f4b18ba 100644 --- a/include/cru/ui/style/Styler.hpp +++ b/include/cru/ui/style/Styler.hpp @@ -3,10 +3,14 @@ #include "ApplyBorderStyleInfo.hpp" #include "cru/common/Base.hpp" +#include + namespace cru::ui::style { class Styler : public Object { public: virtual void Apply(controls::Control* control) const; + + virtual std::unique_ptr Clone() const = 0; }; class BorderStyler : public Styler { @@ -15,6 +19,10 @@ class BorderStyler : public Styler { void Apply(controls::Control* control) const override; + std::unique_ptr Clone() const override { + return std::make_unique(style_); + } + private: ApplyBorderStyleInfo style_; }; diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 03297988..e61ed7de 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -36,6 +36,7 @@ add_library(cru_ui STATIC render/TextRenderObject.cpp style/Condition.cpp style/Styler.cpp + style/StyleRule.cpp ) target_sources(cru_ui PUBLIC ${CRU_UI_INCLUDE_DIR}/Base.hpp @@ -77,5 +78,6 @@ target_sources(cru_ui PUBLIC ${CRU_UI_INCLUDE_DIR}/style/ApplyBorderStyleInfo.hpp ${CRU_UI_INCLUDE_DIR}/style/Condition.hpp ${CRU_UI_INCLUDE_DIR}/style/Styler.hpp + ${CRU_UI_INCLUDE_DIR}/style/StyleRule.hpp ) target_link_libraries(cru_ui PUBLIC cru_platform_gui) diff --git a/src/ui/style/Condition.cpp b/src/ui/style/Condition.cpp index bc24e265..2b51bde3 100644 --- a/src/ui/style/Condition.cpp +++ b/src/ui/style/Condition.cpp @@ -1,4 +1,5 @@ #include "cru/ui/style/Condition.hpp" +#include #include "cru/common/Event.hpp" #include "cru/ui/controls/Control.hpp" @@ -6,8 +7,11 @@ #include "cru/ui/helper/ClickDetector.hpp" namespace cru::ui::style { -CompoundCondition::CompoundCondition(std::vector conditions) - : conditions_(std::move(conditions)) {} +CompoundCondition::CompoundCondition( + std::vector> conditions) + : conditions_(std::move(conditions)) { + for (const auto& p : conditions_) readonly_conditions_.push_back(p.get()); +} std::vector CompoundCondition::ChangeOn( controls::Control* control) const { @@ -22,6 +26,15 @@ std::vector CompoundCondition::ChangeOn( return result; } +std::vector> CompoundCondition::CloneConditions() + const { + std::vector> result; + for (auto condition : GetConditions()) { + result.push_back(condition->Clone()); + } + return result; +} + bool AndCondition::Judge(controls::Control* control) const { for (auto condition : GetConditions()) { if (!condition->Judge(control)) return false; diff --git a/src/ui/style/StyleRule.cpp b/src/ui/style/StyleRule.cpp new file mode 100644 index 00000000..4a5ecf7e --- /dev/null +++ b/src/ui/style/StyleRule.cpp @@ -0,0 +1,11 @@ +#include "cru/ui/style/StyleRule.hpp" + +namespace cru::ui::style { +bool StyleRule::CheckAndApply(controls::Control *control) const { + auto active = condition_->Judge(control); + if (active) { + styler_->Apply(control); + } + return active; +} +} // namespace cru::ui::style -- cgit v1.2.3