diff options
author | crupest <crupest@outlook.com> | 2022-05-15 14:15:31 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-05-15 14:15:31 +0800 |
commit | 34a64e6ffefaab007578932ddbab931a25f1d56e (patch) | |
tree | 541fdb8279e829a129df62288d09916bf23c9200 /src/ThemeBuilder/components/conditions | |
parent | 8ad2966933957ac5d6ff8dcd5e732736fd5e4dc6 (diff) | |
download | cru-34a64e6ffefaab007578932ddbab931a25f1d56e.tar.gz cru-34a64e6ffefaab007578932ddbab931a25f1d56e.tar.bz2 cru-34a64e6ffefaab007578932ddbab931a25f1d56e.zip |
...
Diffstat (limited to 'src/ThemeBuilder/components/conditions')
12 files changed, 478 insertions, 0 deletions
diff --git a/src/ThemeBuilder/components/conditions/CheckedConditionEditor.cpp b/src/ThemeBuilder/components/conditions/CheckedConditionEditor.cpp new file mode 100644 index 00000000..64370981 --- /dev/null +++ b/src/ThemeBuilder/components/conditions/CheckedConditionEditor.cpp @@ -0,0 +1,26 @@ +#include "CheckedConditionEditor.h" +#include "cru/common/ClonablePtr.h" +#include "cru/ui/style/Condition.h" + +namespace cru::theme_builder::components::conditions { +CheckedConditionEditor::CheckedConditionEditor() { + SetLabel(u"Checked Condition"); + + checked_check_box_.SetLabel(u"Checked"); + GetContainer()->AddChild(checked_check_box_.GetRootControl()); + + ConnectChangeEvent(checked_check_box_); +} + +CheckedConditionEditor::~CheckedConditionEditor() {} + +ClonablePtr<ui::style::CheckedCondition> CheckedConditionEditor::GetValue() + const { + return ui::style::CheckedCondition::Create(checked_check_box_.GetValue()); +} + +void CheckedConditionEditor::SetValue(ui::style::CheckedCondition* value, + bool trigger_change) { + checked_check_box_.SetValue(value->IsChecked(), trigger_change); +} +} // namespace cru::theme_builder::components::conditions diff --git a/src/ThemeBuilder/components/conditions/CheckedConditionEditor.h b/src/ThemeBuilder/components/conditions/CheckedConditionEditor.h new file mode 100644 index 00000000..7cf14912 --- /dev/null +++ b/src/ThemeBuilder/components/conditions/CheckedConditionEditor.h @@ -0,0 +1,28 @@ +#pragma once +#include "../properties/CheckBoxPropertyEditor.h" +#include "ConditionEditor.h" +#include "cru/common/ClonablePtr.h" +#include "cru/ui/style/Condition.h" + +namespace cru::theme_builder::components::conditions { +class CheckedConditionEditor : public ConditionEditor { + public: + CheckedConditionEditor(); + ~CheckedConditionEditor() override; + + public: + ClonablePtr<ui::style::CheckedCondition> GetValue() const; + void SetValue(ui::style::CheckedCondition* value, bool trigger_change = true); + void SetValue(const ClonablePtr<ui::style::CheckedCondition>& value, + bool trigger_change = true) { + SetValue(value.get(), trigger_change); + } + + ClonablePtr<ui::style::Condition> GetCondition() override { + return GetValue(); + } + + private: + properties::CheckBoxPropertyEditor checked_check_box_; +}; +} // namespace cru::theme_builder::components::conditions diff --git a/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.cpp b/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.cpp new file mode 100644 index 00000000..a8d5cc87 --- /dev/null +++ b/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.cpp @@ -0,0 +1,69 @@ +#include "ClickStateConditionEditor.h" +#include "cru/common/ClonablePtr.h" +#include "cru/ui/helper/ClickDetector.h" +#include "cru/ui/style/Condition.h" + +namespace cru::theme_builder::components::conditions { +using ui::helper::ClickState; +namespace { +const std::vector<String> kClickStates{ + u"None", + u"Hover", + u"Press", + u"PressInactive", +}; + +Index ConvertClickStateToIndex(ClickState click_state) { + switch (click_state) { + case ClickState::None: + return 0; + case ClickState::Hover: + return 1; + case ClickState::Press: + return 2; + case ClickState::PressInactive: + return 3; + } + return -1; +} + +ClickState ConvertIndexToClickState(Index index) { + switch (index) { + case 0: + return ClickState::None; + case 1: + return ClickState::Hover; + case 2: + return ClickState::Press; + case 3: + return ClickState::PressInactive; + } + return ClickState::None; +} +} // namespace + +ClickStateConditionEditor::ClickStateConditionEditor() { + SetLabel(u"Click State Condition"); + GetContainer()->AddChild(click_state_select_.GetRootControl()); + + click_state_select_.SetLabel(u"Click State"); + click_state_select_.SetItems(kClickStates); + click_state_select_.SetSelectedIndex(0, false); + + ConnectChangeEvent(click_state_select_); +} + +ClickStateConditionEditor::~ClickStateConditionEditor() {} + +ClonablePtr<ui::style::ClickStateCondition> +ClickStateConditionEditor::GetValue() const { + return ui::style::ClickStateCondition::Create( + ConvertIndexToClickState(click_state_select_.GetSelectedIndex())); +} + +void ClickStateConditionEditor::SetValue(ui::style::ClickStateCondition* value, + bool trigger_change) { + click_state_select_.SetSelectedIndex( + ConvertClickStateToIndex(value->GetClickState()), trigger_change); +} +} // namespace cru::theme_builder::components::conditions diff --git a/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.h b/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.h new file mode 100644 index 00000000..454a1346 --- /dev/null +++ b/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.h @@ -0,0 +1,30 @@ +#pragma once +#include "../properties/SelectPropertyEditor.h" +#include "ConditionEditor.h" +#include "cru/common/ClonablePtr.h" +#include "cru/common/Event.h" +#include "cru/ui/style/Condition.h" + +namespace cru::theme_builder::components::conditions { +class ClickStateConditionEditor : public ConditionEditor { + public: + ClickStateConditionEditor(); + ~ClickStateConditionEditor(); + + public: + ClonablePtr<ui::style::ClickStateCondition> GetValue() const; + void SetValue(ui::style::ClickStateCondition* value, + bool trigger_change = true); + void SetValue(const ClonablePtr<ui::style::ClickStateCondition>& value, + bool trigger_change = true) { + SetValue(value.get(), trigger_change); + } + + ClonablePtr<ui::style::Condition> GetCondition() override { + return GetValue(); + } + + private: + properties::SelectPropertyEditor click_state_select_; +}; +} // namespace cru::theme_builder::components::conditions diff --git a/src/ThemeBuilder/components/conditions/CompoundConditionEditor.cpp b/src/ThemeBuilder/components/conditions/CompoundConditionEditor.cpp new file mode 100644 index 00000000..69b8ed02 --- /dev/null +++ b/src/ThemeBuilder/components/conditions/CompoundConditionEditor.cpp @@ -0,0 +1,109 @@ +#include "CompoundConditionEditor.h" +#include "CheckedConditionEditor.h" +#include "ClickStateConditionEditor.h" +#include "ConditionEditor.h" +#include "FocusConditionEditor.h" +#include "NoConditionEditor.h" +#include "cru/common/ClonablePtr.h" +#include "cru/platform/Color.h" +#include "cru/ui/Base.h" +#include "cru/ui/ThemeManager.h" +#include "cru/ui/controls/FlexLayout.h" +#include "cru/ui/style/Condition.h" + +namespace cru::theme_builder::components::conditions { + +CompoundConditionEditor::CompoundConditionEditor() { + SetLabel(u"Compound Condition"); + + GetContainer()->AddChild(&children_container_); + children_container_.SetMargin({10, 0, 0, 0}); + children_container_.SetFlexDirection(ui::controls::FlexDirection::Vertical); + children_container_.SetItemCrossAlign( + ui::controls::FlexCrossAlignment::Start); + + GetHeadContainer()->AddChild(add_child_button_.GetRootControl()); + + add_child_button_.GetButton()->GetStyleRuleSet()->SetParent( + ui::ThemeManager::GetInstance()->GetResourceStyleRuleSet( + u"cru.theme_builder.icon-button.style")); + add_child_button_.GetButton()->SetIconWithSvgPathDataStringResourceKey( + u"icon.plus", {0, 0, 16, 16}); + add_child_button_.GetButton()->SetPreferredSize({24, 24}); + add_child_button_.GetButton()->SetPadding(ui::Thickness(2)); + add_child_button_.GetButton()->SetIconFillColor(ui::colors::green); + add_child_button_.SetMenuItems({u"And Condition", u"Or Condition", + u"Click State Condition", u"Focus Condition", + u"Checked Condition", u"No Condition"}); + add_child_button_.MenuItemSelectedEvent()->AddHandler([this](Index index) { + std::unique_ptr<ConditionEditor> editor; + switch (index) { + case 0: + editor = std::make_unique<AndConditionEditor>(); + break; + case 1: + editor = std::make_unique<OrConditionEditor>(); + break; + case 2: + editor = std::make_unique<ClickStateConditionEditor>(); + break; + case 3: + editor = std::make_unique<FocusConditionEditor>(); + break; + case 4: + editor = std::make_unique<CheckedConditionEditor>(); + break; + case 5: + editor = std::make_unique<NoConditionEditor>(); + break; + default: + break; + } + if (editor) { + ConnectChangeEvent(editor.get()); + editor->RemoveEvent()->AddSpyOnlyHandler([this, c = editor.get()] { + auto index = this->children_container_.IndexOf(c->GetRootControl()); + this->children_.erase(this->children_.begin() + index); + this->children_container_.RemoveChildAt(index); + RaiseChangeEvent(); + }); + children_.push_back(std::move(editor)); + children_container_.AddChild(children_.back()->GetRootControl()); + RaiseChangeEvent(); + } + }); +} + +CompoundConditionEditor::~CompoundConditionEditor() {} + +std::vector<ClonablePtr<ui::style::Condition>> +CompoundConditionEditor::GetChildren() { + std::vector<ClonablePtr<ui::style::Condition>> children; + for (auto& child : children_) { + children.push_back(child->GetCondition()); + } + return children; +} + +void CompoundConditionEditor::SetChildren( + std::vector<ClonablePtr<ui::style::Condition>> children, + bool trigger_change) { + children_container_.ClearChildren(); + children_.clear(); + for (const auto& condition : children) { + auto editor = CreateConditionEditor(condition.get()); + ConnectChangeEvent(editor.get()); + editor->RemoveEvent()->AddSpyOnlyHandler([this, c = editor.get()] { + auto index = this->children_container_.IndexOf(c->GetRootControl()); + this->children_.erase(this->children_.begin() + index); + this->children_container_.RemoveChildAt(index); + RaiseChangeEvent(); + }); + children_.push_back(std::move(editor)); + children_container_.AddChild(children_.back()->GetRootControl()); + } + if (trigger_change) { + RaiseChangeEvent(); + } +} +} // namespace cru::theme_builder::components::conditions diff --git a/src/ThemeBuilder/components/conditions/CompoundConditionEditor.h b/src/ThemeBuilder/components/conditions/CompoundConditionEditor.h new file mode 100644 index 00000000..e1398514 --- /dev/null +++ b/src/ThemeBuilder/components/conditions/CompoundConditionEditor.h @@ -0,0 +1,72 @@ +#pragma once +#include "ConditionEditor.h" +#include "cru/common/ClonablePtr.h" +#include "cru/common/Event.h" +#include "cru/ui/components/Component.h" +#include "cru/ui/components/PopupButton.h" +#include "cru/ui/controls/Button.h" +#include "cru/ui/controls/FlexLayout.h" +#include "cru/ui/controls/TextBlock.h" +#include "cru/ui/style/Condition.h" + +namespace cru::theme_builder::components::conditions { +class CompoundConditionEditor : public ConditionEditor { + public: + CompoundConditionEditor(); + ~CompoundConditionEditor(); + + protected: + std::vector<ClonablePtr<ui::style::Condition>> GetChildren(); + void SetChildren(std::vector<ClonablePtr<ui::style::Condition>> children, + bool trigger_change = true); + + private: + ui::components::PopupMenuIconButton add_child_button_; + ui::controls::FlexLayout children_container_; + std::vector<ui::DeleteLaterPtr<ConditionEditor>> children_; +}; + +class AndConditionEditor : public CompoundConditionEditor { + public: + AndConditionEditor() = default; + ~AndConditionEditor() override = default; + + public: + ClonablePtr<ui::style::AndCondition> GetValue() { + return ui::style::AndCondition::Create(GetChildren()); + } + void SetValue(ui::style::AndCondition* value, bool trigger_change = true) { + SetChildren(value->GetChildren(), trigger_change); + } + void SetValue(const ClonablePtr<ui::style::AndCondition>& value, + bool trigger_change = true) { + SetValue(value.get(), trigger_change); + } + + ClonablePtr<ui::style::Condition> GetCondition() override { + return GetValue(); + } +}; + +class OrConditionEditor : public CompoundConditionEditor { + public: + OrConditionEditor() = default; + ~OrConditionEditor() override = default; + + public: + ClonablePtr<ui::style::OrCondition> GetValue() { + return ui::style::OrCondition::Create(GetChildren()); + } + void SetValue(ui::style::OrCondition* value, bool trigger_change = true) { + SetChildren(value->GetChildren(), trigger_change); + } + void SetValue(const ClonablePtr<ui::style::OrCondition>& value, + bool trigger_change = true) { + SetValue(value.get(), trigger_change); + } + + ClonablePtr<ui::style::Condition> GetCondition() override { + return GetValue(); + } +}; +} // namespace cru::theme_builder::components::conditions diff --git a/src/ThemeBuilder/components/conditions/ConditionEditor.cpp b/src/ThemeBuilder/components/conditions/ConditionEditor.cpp new file mode 100644 index 00000000..5b79c639 --- /dev/null +++ b/src/ThemeBuilder/components/conditions/ConditionEditor.cpp @@ -0,0 +1,50 @@ +#include "ConditionEditor.h" +#include "../Common.h" +#include "CheckedConditionEditor.h" +#include "ClickStateConditionEditor.h" +#include "CompoundConditionEditor.h" +#include "FocusConditionEditor.h" +#include "NoConditionEditor.h" +#include "cru/common/Exception.h" +#include "cru/ui/controls/FlexLayout.h" + +namespace cru::theme_builder::components::conditions { +ConditionEditor::ConditionEditor() {} + +ConditionEditor::~ConditionEditor() {} + +std::unique_ptr<ConditionEditor> CreateConditionEditor( + ui::style::Condition* condition) { + if (auto and_condition = dynamic_cast<ui::style::AndCondition*>(condition)) { + auto result = std::make_unique<AndConditionEditor>(); + result->SetValue(and_condition); + return result; + } else if (auto or_condition = + dynamic_cast<ui::style::OrCondition*>(condition)) { + auto result = std::make_unique<OrConditionEditor>(); + result->SetValue(or_condition); + return result; + } else if (auto no_condition = + dynamic_cast<ui::style::NoCondition*>(condition)) { + auto result = std::make_unique<NoConditionEditor>(); + return result; + } else if (auto click_state_condition = + dynamic_cast<ui::style::ClickStateCondition*>(condition)) { + auto result = std::make_unique<ClickStateConditionEditor>(); + result->SetValue(click_state_condition); + return result; + } else if (auto focus_condition = + dynamic_cast<ui::style::FocusCondition*>(condition)) { + auto result = std::make_unique<FocusConditionEditor>(); + result->SetValue(focus_condition); + return result; + } else if (auto checked_condition = + dynamic_cast<ui::style::CheckedCondition*>(condition)) { + auto result = std::make_unique<CheckedConditionEditor>(); + result->SetValue(checked_condition); + return result; + } else { + throw Exception(u"Unknown condition type"); + } +} +} // namespace cru::theme_builder::components::conditions diff --git a/src/ThemeBuilder/components/conditions/ConditionEditor.h b/src/ThemeBuilder/components/conditions/ConditionEditor.h new file mode 100644 index 00000000..f20132f6 --- /dev/null +++ b/src/ThemeBuilder/components/conditions/ConditionEditor.h @@ -0,0 +1,17 @@ +#pragma once +#include "../HeadBodyEditor.h" +#include "cru/ui/style/Condition.h" + +namespace cru::theme_builder::components::conditions { +class ConditionEditor : public HeadBodyEditor { + public: + ConditionEditor(); + ~ConditionEditor() override; + + public: + virtual ClonablePtr<ui::style::Condition> GetCondition() = 0; +}; + +std::unique_ptr<ConditionEditor> CreateConditionEditor( + ui::style::Condition* condition); +} // namespace cru::theme_builder::components::conditions diff --git a/src/ThemeBuilder/components/conditions/FocusConditionEditor.cpp b/src/ThemeBuilder/components/conditions/FocusConditionEditor.cpp new file mode 100644 index 00000000..1fb99d64 --- /dev/null +++ b/src/ThemeBuilder/components/conditions/FocusConditionEditor.cpp @@ -0,0 +1,25 @@ +#include "FocusConditionEditor.h" +#include "cru/common/ClonablePtr.h" +#include "cru/ui/style/Condition.h" + +namespace cru::theme_builder::components::conditions { +FocusConditionEditor::FocusConditionEditor() { + SetLabel(u"Focus Condition"); + GetContainer()->AddChild(focus_check_box_.GetRootControl()); + + focus_check_box_.SetLabel(u"Focus"); + + ConnectChangeEvent(focus_check_box_); +} + +FocusConditionEditor::~FocusConditionEditor() {} + +ClonablePtr<ui::style::FocusCondition> FocusConditionEditor::GetValue() const { + return ui::style::FocusCondition::Create(focus_check_box_.GetValue()); +} + +void FocusConditionEditor::SetValue(ui::style::FocusCondition* value, + bool trigger_change) { + focus_check_box_.SetValue(value->IsHasFocus(), trigger_change); +} +} // namespace cru::theme_builder::components::conditions diff --git a/src/ThemeBuilder/components/conditions/FocusConditionEditor.h b/src/ThemeBuilder/components/conditions/FocusConditionEditor.h new file mode 100644 index 00000000..1faf4d7d --- /dev/null +++ b/src/ThemeBuilder/components/conditions/FocusConditionEditor.h @@ -0,0 +1,28 @@ +#pragma once +#include "../properties/CheckBoxPropertyEditor.h" +#include "ConditionEditor.h" +#include "cru/common/ClonablePtr.h" +#include "cru/ui/style/Condition.h" + +namespace cru::theme_builder::components::conditions { +class FocusConditionEditor : public ConditionEditor { + public: + FocusConditionEditor(); + ~FocusConditionEditor() override; + + public: + ClonablePtr<ui::style::FocusCondition> GetValue() const; + void SetValue(ui::style::FocusCondition* value, bool trigger_change = true); + void SetValue(const ClonablePtr<ui::style::FocusCondition>& value, + bool trigger_change = true) { + SetValue(value.get(), trigger_change); + } + + ClonablePtr<ui::style::Condition> GetCondition() override { + return GetValue(); + } + + private: + properties::CheckBoxPropertyEditor focus_check_box_; +}; +} // namespace cru::theme_builder::components::conditions diff --git a/src/ThemeBuilder/components/conditions/NoConditionEditor.cpp b/src/ThemeBuilder/components/conditions/NoConditionEditor.cpp new file mode 100644 index 00000000..a5087159 --- /dev/null +++ b/src/ThemeBuilder/components/conditions/NoConditionEditor.cpp @@ -0,0 +1,7 @@ +#include "NoConditionEditor.h" + +namespace cru::theme_builder::components::conditions { +NoConditionEditor::NoConditionEditor() { SetLabel(u"No condition"); } + +NoConditionEditor::~NoConditionEditor() {} +} // namespace cru::theme_builder::components::conditions diff --git a/src/ThemeBuilder/components/conditions/NoConditionEditor.h b/src/ThemeBuilder/components/conditions/NoConditionEditor.h new file mode 100644 index 00000000..19616319 --- /dev/null +++ b/src/ThemeBuilder/components/conditions/NoConditionEditor.h @@ -0,0 +1,17 @@ +#pragma once +#include "ConditionEditor.h" +#include "cru/common/ClonablePtr.h" +#include "cru/ui/style/Condition.h" + +namespace cru::theme_builder::components::conditions { +class NoConditionEditor : public ConditionEditor { + public: + NoConditionEditor(); + ~NoConditionEditor() override; + + public: + ClonablePtr<ui::style::Condition> GetCondition() override { + return ui::style::NoCondition::Create(); + } +}; +} // namespace cru::theme_builder::components::conditions |