aboutsummaryrefslogtreecommitdiff
path: root/src/ThemeBuilder/components/conditions
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-05-15 14:15:31 +0800
committercrupest <crupest@outlook.com>2022-05-15 14:15:31 +0800
commit34a64e6ffefaab007578932ddbab931a25f1d56e (patch)
tree541fdb8279e829a129df62288d09916bf23c9200 /src/ThemeBuilder/components/conditions
parent8ad2966933957ac5d6ff8dcd5e732736fd5e4dc6 (diff)
downloadcru-34a64e6ffefaab007578932ddbab931a25f1d56e.tar.gz
cru-34a64e6ffefaab007578932ddbab931a25f1d56e.tar.bz2
cru-34a64e6ffefaab007578932ddbab931a25f1d56e.zip
...
Diffstat (limited to 'src/ThemeBuilder/components/conditions')
-rw-r--r--src/ThemeBuilder/components/conditions/CheckedConditionEditor.cpp26
-rw-r--r--src/ThemeBuilder/components/conditions/CheckedConditionEditor.h28
-rw-r--r--src/ThemeBuilder/components/conditions/ClickStateConditionEditor.cpp69
-rw-r--r--src/ThemeBuilder/components/conditions/ClickStateConditionEditor.h30
-rw-r--r--src/ThemeBuilder/components/conditions/CompoundConditionEditor.cpp109
-rw-r--r--src/ThemeBuilder/components/conditions/CompoundConditionEditor.h72
-rw-r--r--src/ThemeBuilder/components/conditions/ConditionEditor.cpp50
-rw-r--r--src/ThemeBuilder/components/conditions/ConditionEditor.h17
-rw-r--r--src/ThemeBuilder/components/conditions/FocusConditionEditor.cpp25
-rw-r--r--src/ThemeBuilder/components/conditions/FocusConditionEditor.h28
-rw-r--r--src/ThemeBuilder/components/conditions/NoConditionEditor.cpp7
-rw-r--r--src/ThemeBuilder/components/conditions/NoConditionEditor.h17
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