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/properties | |
parent | 8ad2966933957ac5d6ff8dcd5e732736fd5e4dc6 (diff) | |
download | cru-34a64e6ffefaab007578932ddbab931a25f1d56e.tar.gz cru-34a64e6ffefaab007578932ddbab931a25f1d56e.tar.bz2 cru-34a64e6ffefaab007578932ddbab931a25f1d56e.zip |
...
Diffstat (limited to 'src/ThemeBuilder/components/properties')
19 files changed, 685 insertions, 0 deletions
diff --git a/src/ThemeBuilder/components/properties/CheckBoxPropertyEditor.cpp b/src/ThemeBuilder/components/properties/CheckBoxPropertyEditor.cpp new file mode 100644 index 00000000..fb6f4705 --- /dev/null +++ b/src/ThemeBuilder/components/properties/CheckBoxPropertyEditor.cpp @@ -0,0 +1,19 @@ +#include "CheckBoxPropertyEditor.h" + +namespace cru::theme_builder::components::properties { +CheckBoxPropertyEditor::CheckBoxPropertyEditor() { + container_.SetFlexDirection(ui::controls::FlexDirection::Horizontal); + container_.AddChild(&label_); + container_.AddChild(&check_box_); + + check_box_.CheckedChangeEvent()->AddSpyOnlyHandler( + [this] { RaiseChangeEvent(); }); +} + +CheckBoxPropertyEditor::~CheckBoxPropertyEditor() {} + +void CheckBoxPropertyEditor::SetValue(bool value, bool trigger_change) { + if (!trigger_change) SuppressNextChangeEvent(); + check_box_.SetChecked(value); +} +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/CheckBoxPropertyEditor.h b/src/ThemeBuilder/components/properties/CheckBoxPropertyEditor.h new file mode 100644 index 00000000..f78ed6c9 --- /dev/null +++ b/src/ThemeBuilder/components/properties/CheckBoxPropertyEditor.h @@ -0,0 +1,29 @@ +#pragma once +#include "../Editor.h" +#include "cru/ui/controls/CheckBox.h" +#include "cru/ui/controls/FlexLayout.h" +#include "cru/ui/controls/TextBlock.h" + +namespace cru::theme_builder::components::properties { +class CheckBoxPropertyEditor : public Editor { + public: + using PropertyType = bool; + + CheckBoxPropertyEditor(); + ~CheckBoxPropertyEditor() override; + + public: + ui::controls::Control* GetRootControl() override { return &container_; } + + String GetLabel() const { return label_.GetText(); } + void SetLabel(String label) { label_.SetText(std::move(label)); } + + bool GetValue() const { return check_box_.IsChecked(); } + void SetValue(bool value, bool trigger_change = true); + + private: + ui::controls::FlexLayout container_; + ui::controls::TextBlock label_; + ui::controls::CheckBox check_box_; +}; +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/ColorPropertyEditor.cpp b/src/ThemeBuilder/components/properties/ColorPropertyEditor.cpp new file mode 100644 index 00000000..e9e486ac --- /dev/null +++ b/src/ThemeBuilder/components/properties/ColorPropertyEditor.cpp @@ -0,0 +1,48 @@ +#include "ColorPropertyEditor.h" +#include "cru/platform/graphics/Factory.h" +#include "cru/ui/Base.h" +#include "cru/ui/ThemeManager.h" + +namespace cru::theme_builder::components::properties { +ColorPropertyEditor::ColorPropertyEditor() { + container_.AddChild(&label_); + container_.AddChild(&color_cube_); + container_.AddChild(&color_text_); + + color_cube_.SetBorderEnabled(true); + color_cube_.GetStyleRuleSet()->SetParent( + ui::ThemeManager::GetInstance()->GetResourceStyleRuleSet( + u"cru.theme_builder.color_cube.style")); + + color_cube_brush_ = platform::gui::IUiApplication::GetInstance() + ->GetGraphicsFactory() + ->CreateSolidColorBrush(color_); + + color_cube_.SetForegroundBrush(color_cube_brush_); + + color_text_.SetText(color_.ToString()); + color_text_.SetMargin(ui::Thickness(10, 0, 0, 0)); + + color_text_.TextChangeEvent()->AddHandler([this](std::nullptr_t) { + auto text = color_text_.GetTextView(); + auto color = ui::Color::Parse(text); + if (color) { + color_ = *color; + color_cube_brush_->SetColor(*color); + is_color_text_valid_ = true; + RaiseChangeEvent(); + } else { + is_color_text_valid_ = false; + // TODO: Show error! + } + }); +} + +ColorPropertyEditor::~ColorPropertyEditor() {} + +void ColorPropertyEditor::SetValue(const ui::Color &color, + bool trigger_change) { + if (!trigger_change) SuppressNextChangeEvent(); + color_text_.SetText(color.ToString()); +} +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/ColorPropertyEditor.h b/src/ThemeBuilder/components/properties/ColorPropertyEditor.h new file mode 100644 index 00000000..aa6cfcfa --- /dev/null +++ b/src/ThemeBuilder/components/properties/ColorPropertyEditor.h @@ -0,0 +1,36 @@ +#pragma once +#include "../Editor.h" +#include "cru/platform/graphics/Base.h" +#include "cru/ui/controls/Container.h" +#include "cru/ui/controls/FlexLayout.h" +#include "cru/ui/controls/TextBlock.h" +#include "cru/ui/controls/TextBox.h" + +namespace cru::theme_builder::components::properties { +class ColorPropertyEditor : public Editor { + public: + using PropertyType = ui::Color; + + ColorPropertyEditor(); + ~ColorPropertyEditor() override; + + public: + ui::controls::Control* GetRootControl() override { return &container_; } + + String GetLabel() const { return label_.GetText(); } + void SetLabel(String label) { label_.SetText(std::move(label)); } + + ui::Color GetValue() const { return color_; } + void SetValue(const ui::Color& color, bool trigger_change = true); + + private: + ui::Color color_ = ui::colors::transparent; + + ui::controls::FlexLayout container_; + ui::controls::TextBlock label_; + ui::controls::Container color_cube_; + std::shared_ptr<platform::graphics::ISolidColorBrush> color_cube_brush_; + ui::controls::TextBox color_text_; + bool is_color_text_valid_; +}; +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/CornerRadiusPropertyEditor.cpp b/src/ThemeBuilder/components/properties/CornerRadiusPropertyEditor.cpp new file mode 100644 index 00000000..fc86b0ed --- /dev/null +++ b/src/ThemeBuilder/components/properties/CornerRadiusPropertyEditor.cpp @@ -0,0 +1,42 @@ +#include "CornerRadiusPropertyEditor.h" +#include "cru/ui/Base.h" +#include "cru/ui/controls/FlexLayout.h" + +namespace cru::theme_builder::components::properties { +CornerRadiusPropertyEditor::CornerRadiusPropertyEditor() { + container_.SetItemCrossAlign(ui::controls::FlexCrossAlignment::Start); + + left_top_editor_.SetLabel(u"⌜"); + right_top_editor_.SetLabel(u"⌝"); + left_bottom_editor_.SetLabel(u"⌞"); + right_bottom_editor_.SetLabel(u"⌟"); + + container_.SetFlexDirection(ui::controls::FlexDirection::Vertical); + container_.AddChild(left_top_editor_.GetRootControl()); + container_.AddChild(right_top_editor_.GetRootControl()); + container_.AddChild(left_bottom_editor_.GetRootControl()); + container_.AddChild(right_bottom_editor_.GetRootControl()); + + ConnectChangeEvent(left_top_editor_); + ConnectChangeEvent(right_top_editor_); + ConnectChangeEvent(left_bottom_editor_); + ConnectChangeEvent(right_bottom_editor_); +} + +CornerRadiusPropertyEditor::~CornerRadiusPropertyEditor() {} + +ui::CornerRadius CornerRadiusPropertyEditor::GetValue() const { + return ui::CornerRadius( + left_top_editor_.GetValue(), right_top_editor_.GetValue(), + left_bottom_editor_.GetValue(), right_bottom_editor_.GetValue()); +} + +void CornerRadiusPropertyEditor::SetValue(const ui::CornerRadius& corner_radius, + bool trigger_change) { + left_top_editor_.SetValue(corner_radius.left_top, false); + right_top_editor_.SetValue(corner_radius.right_top, false); + left_bottom_editor_.SetValue(corner_radius.left_bottom, false); + right_bottom_editor_.SetValue(corner_radius.right_bottom, false); + if (trigger_change) RaiseChangeEvent(); +} +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/CornerRadiusPropertyEditor.h b/src/ThemeBuilder/components/properties/CornerRadiusPropertyEditor.h new file mode 100644 index 00000000..6b6833d1 --- /dev/null +++ b/src/ThemeBuilder/components/properties/CornerRadiusPropertyEditor.h @@ -0,0 +1,28 @@ +#pragma once +#include "../Editor.h" +#include "PointPropertyEditor.h" +#include "cru/ui/Base.h" +#include "cru/ui/controls/FlexLayout.h" + +namespace cru::theme_builder::components::properties { +class CornerRadiusPropertyEditor : public Editor { + public: + using PropertyType = ui::CornerRadius; + + CornerRadiusPropertyEditor(); + ~CornerRadiusPropertyEditor() override; + + ui::controls::Control* GetRootControl() override { return &container_; } + + ui::CornerRadius GetValue() const; + void SetValue(const ui::CornerRadius& corner_radius, + bool trigger_change = true); + + private: + ui::controls::FlexLayout container_; + PointPropertyEditor left_top_editor_; + PointPropertyEditor right_top_editor_; + PointPropertyEditor left_bottom_editor_; + PointPropertyEditor right_bottom_editor_; +}; +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/FontPropertyEditor.cpp b/src/ThemeBuilder/components/properties/FontPropertyEditor.cpp new file mode 100644 index 00000000..927ada7d --- /dev/null +++ b/src/ThemeBuilder/components/properties/FontPropertyEditor.cpp @@ -0,0 +1,60 @@ +#include "FontPropertyEditor.h" +#include "cru/platform/graphics/Factory.h" +#include "cru/platform/graphics/Font.h" +#include "cru/platform/gui/UiApplication.h" +#include "cru/ui/controls/FlexLayout.h" +#include "cru/ui/render/FlexLayoutRenderObject.h" + +namespace cru::theme_builder::components::properties { +using namespace cru::ui::controls; + +FontPropertyEditor::FontPropertyEditor() { + main_container_.SetFlexDirection(FlexDirection::Horizontal); + main_container_.AddChild(&label_); + main_container_.AddChild(&right_container_); + + right_container_.SetFlexDirection(FlexDirection::Vertical); + right_container_.AddChild(&font_family_container_); + right_container_.AddChild(&font_size_container_); + + font_family_container_.SetFlexDirection(FlexDirection::Horizontal); + font_family_container_.AddChild(&font_family_label_); + font_family_container_.AddChild(&font_family_text_); + font_family_label_.SetText(u"Font Family"); + + font_size_container_.SetFlexDirection(FlexDirection::Horizontal); + font_size_container_.AddChild(&font_size_label_); + font_size_container_.AddChild(font_size_input_.GetRootControl()); + font_size_label_.SetText(u"Font Size"); + font_size_input_.SetMin(0.0f); + + font_family_text_.TextChangeEvent()->AddSpyOnlyHandler( + [this] { RaiseChangeEvent(); }); + + font_size_input_.ChangeEvent()->AddSpyOnlyHandler( + [this] { RaiseChangeEvent(); }); +} + +FontPropertyEditor::~FontPropertyEditor() {} + +Control* FontPropertyEditor::GetRootControl() { return &main_container_; } + +std::shared_ptr<platform::graphics::IFont> FontPropertyEditor::GetValue() + const { + return platform::gui::IUiApplication::GetInstance() + ->GetGraphicsFactory() + ->CreateFont(font_family_text_.GetText(), font_size_input_.GetValue()); +} + +void FontPropertyEditor::SetValue( + std::shared_ptr<platform::graphics::IFont> value, bool trigger_change) { + SuppressNextChangeEvent(); + font_family_text_.SetText(value->GetFontName()); + SuppressNextChangeEvent(); + font_size_input_.SetValue(value->GetFontSize()); + + if (trigger_change) { + RaiseChangeEvent(); + } +} +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/FontPropertyEditor.h b/src/ThemeBuilder/components/properties/FontPropertyEditor.h new file mode 100644 index 00000000..d349f1f2 --- /dev/null +++ b/src/ThemeBuilder/components/properties/FontPropertyEditor.h @@ -0,0 +1,38 @@ +#pragma once +#include "../Editor.h" +#include "cru/platform/graphics/Font.h" +#include "cru/ui/components/Input.h" +#include "cru/ui/controls/Control.h" +#include "cru/ui/controls/FlexLayout.h" +#include "cru/ui/controls/TextBlock.h" +#include "cru/ui/controls/TextBox.h" + +namespace cru::theme_builder::components::properties { +class FontPropertyEditor : public Editor { + public: + using PropertyType = std::shared_ptr<platform::graphics::IFont>; + + FontPropertyEditor(); + ~FontPropertyEditor() override; + + ui::controls::Control* GetRootControl() override; + + String GetLabelText() const { return label_.GetText(); } + void SetLabelText(String label) { label_.SetText(std::move(label)); } + + std::shared_ptr<platform::graphics::IFont> GetValue() const; + void SetValue(std::shared_ptr<platform::graphics::IFont> value, + bool trigger_change = true); + + private: + ui::controls::FlexLayout main_container_; + ui::controls::TextBlock label_; + ui::controls::FlexLayout right_container_; + ui::controls::FlexLayout font_family_container_; + ui::controls::TextBlock font_family_label_; + ui::controls::TextBox font_family_text_; + ui::controls::FlexLayout font_size_container_; + ui::controls::TextBlock font_size_label_; + ui::components::FloatInput font_size_input_; +}; +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/MeasureLengthPropertyEditor.cpp b/src/ThemeBuilder/components/properties/MeasureLengthPropertyEditor.cpp new file mode 100644 index 00000000..d1f4afce --- /dev/null +++ b/src/ThemeBuilder/components/properties/MeasureLengthPropertyEditor.cpp @@ -0,0 +1,37 @@ +#include "MeasureLengthPropertyEditor.h" +#include "cru/common/Format.h" +#include "cru/ui/mapper/MapperRegistry.h" +#include "cru/ui/render/MeasureRequirement.h" + +namespace cru::theme_builder::components::properties { +MeasureLengthPropertyEditor::MeasureLengthPropertyEditor() { + container_.AddChild(&label_); + container_.AddChild(&text_); + + text_.TextChangeEvent()->AddHandler([this](std::nullptr_t) { + auto text = text_.GetTextView(); + auto measure_length_mapper = ui::mapper::MapperRegistry::GetInstance() + ->GetMapper<ui::render::MeasureLength>(); + try { + auto measure_length = + measure_length_mapper->MapFromString(text.ToString()); + measure_length_ = measure_length; + is_text_valid_ = true; + RaiseChangeEvent(); + } catch (const Exception&) { + is_text_valid_ = false; + // TODO: Show error! + } + }); +} + +MeasureLengthPropertyEditor::~MeasureLengthPropertyEditor() {} + +void MeasureLengthPropertyEditor::SetValue( + const ui::render::MeasureLength& value, bool trigger_change) { + if (!trigger_change) SuppressNextChangeEvent(); + text_.SetText(measure_length_.IsNotSpecified() + ? u"unspecified" + : ToString(measure_length_.GetLengthOrUndefined())); +} +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/MeasureLengthPropertyEditor.h b/src/ThemeBuilder/components/properties/MeasureLengthPropertyEditor.h new file mode 100644 index 00000000..43e783c5 --- /dev/null +++ b/src/ThemeBuilder/components/properties/MeasureLengthPropertyEditor.h @@ -0,0 +1,35 @@ +#pragma once +#include "../Editor.h" +#include "cru/platform/graphics/Base.h" +#include "cru/ui/controls/Container.h" +#include "cru/ui/controls/FlexLayout.h" +#include "cru/ui/controls/TextBlock.h" +#include "cru/ui/controls/TextBox.h" +#include "cru/ui/render/MeasureRequirement.h" + +namespace cru::theme_builder::components::properties { +class MeasureLengthPropertyEditor : public Editor { + public: + using PropertyType = ui::render::MeasureLength; + + MeasureLengthPropertyEditor(); + ~MeasureLengthPropertyEditor() override; + + public: + ui::controls::Control* GetRootControl() override { return &container_; } + + String GetLabel() const { return label_.GetText(); } + void SetLabel(String label) { label_.SetText(std::move(label)); } + + PropertyType GetValue() const { return measure_length_; } + void SetValue(const PropertyType& value, bool trigger_change = true); + + private: + PropertyType measure_length_; + + ui::controls::FlexLayout container_; + ui::controls::TextBlock label_; + ui::controls::TextBox text_; + bool is_text_valid_; +}; +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/OptionalPropertyEditor.h b/src/ThemeBuilder/components/properties/OptionalPropertyEditor.h new file mode 100644 index 00000000..0f22616a --- /dev/null +++ b/src/ThemeBuilder/components/properties/OptionalPropertyEditor.h @@ -0,0 +1,65 @@ +#pragma once +#include "../Editor.h" +#include "cru/ui/controls/CheckBox.h" +#include "cru/ui/controls/FlexLayout.h" +#include "cru/ui/controls/TextBlock.h" + +#include <optional> + +namespace cru::theme_builder::components::properties { +template <typename TEditor> +class OptionalPropertyEditor : public Editor { + public: + using PropertyType = typename TEditor::PropertyType; + + OptionalPropertyEditor() { + container_.AddChild(&label_); + container_.AddChild(&check_box_); + check_box_.SetMargin({0, 0, 10, 0}); + container_.AddChild(editor_.GetRootControl()); + + editor_.ChangeEvent()->AddHandler([this](std::nullptr_t) { + if (IsEnabled()) { + RaiseChangeEvent(); + } + }); + } + ~OptionalPropertyEditor() override {} + + ui::controls::Control* GetRootControl() override { return &container_; } + + String GetLabel() const { return label_.GetText(); } + void SetLabel(String label) { label_.SetText(std::move(label)); } + + bool IsEnabled() const { return check_box_.IsChecked(); } + void SetEnabled(bool enabled, bool trigger_change = true) { + check_box_.SetChecked(enabled); + if (trigger_change) { + RaiseChangeEvent(); + } + } + + std::optional<PropertyType> GetValue() const { + return IsEnabled() ? std::optional<PropertyType>(editor_.GetValue()) + : std::nullopt; + } + + void SetValue(std::optional<PropertyType> value, bool trigger_change = true) { + if (value) { + SetEnabled(true, false); + editor_.SetValue(*value, false); + if (trigger_change) RaiseChangeEvent(); + } else { + SetEnabled(false, trigger_change); + } + } + + TEditor* GetEditor() { return &editor_; } + + private: + ui::controls::FlexLayout container_; + ui::controls::TextBlock label_; + ui::controls::CheckBox check_box_; + TEditor editor_; +}; +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/PointPropertyEditor.cpp b/src/ThemeBuilder/components/properties/PointPropertyEditor.cpp new file mode 100644 index 00000000..6d4277aa --- /dev/null +++ b/src/ThemeBuilder/components/properties/PointPropertyEditor.cpp @@ -0,0 +1,38 @@ +#include "PointPropertyEditor.h" +#include "cru/common/Format.h" +#include "cru/ui/mapper/MapperRegistry.h" +#include "cru/ui/mapper/PointMapper.h" + +namespace cru::theme_builder::components::properties { +PointPropertyEditor::PointPropertyEditor() { + container_.AddChild(&label_); + container_.AddChild(&text_); + + text_.TextChangeEvent()->AddHandler([this](std::nullptr_t) { + auto text = text_.GetTextView(); + auto point_mapper = + ui::mapper::MapperRegistry::GetInstance()->GetMapper<ui::Point>(); + try { + auto point = point_mapper->MapFromString(text.ToString()); + point_ = point; + is_text_valid_ = true; + RaiseChangeEvent(); + } catch (const Exception&) { + is_text_valid_ = false; + // TODO: Show error! + } + }); +} + +PointPropertyEditor::~PointPropertyEditor() {} + +void PointPropertyEditor::SetValue(const ui::Point& point, + bool trigger_change) { + if (!trigger_change) SuppressNextChangeEvent(); + text_.SetText(ConvertPointToString(point)); +} + +String PointPropertyEditor::ConvertPointToString(const ui::Point& point) { + return Format(u"{} {}", point.x, point.y); +} +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/PointPropertyEditor.h b/src/ThemeBuilder/components/properties/PointPropertyEditor.h new file mode 100644 index 00000000..bd852e3a --- /dev/null +++ b/src/ThemeBuilder/components/properties/PointPropertyEditor.h @@ -0,0 +1,35 @@ +#pragma once +#include "../Editor.h" +#include "cru/ui/controls/FlexLayout.h" +#include "cru/ui/controls/TextBlock.h" +#include "cru/ui/controls/TextBox.h" + +namespace cru::theme_builder::components::properties { +class PointPropertyEditor : public Editor { + public: + using PropertyType = ui::Point; + + PointPropertyEditor(); + ~PointPropertyEditor() override; + + public: + ui::controls::Control* GetRootControl() override { return &container_; } + + String GetLabel() const { return label_.GetText(); } + void SetLabel(String label) { label_.SetText(std::move(label)); } + + ui::Point GetValue() const { return point_; } + void SetValue(const ui::Point& point, bool trigger_change = true); + + private: + static String ConvertPointToString(const ui::Point& point); + + private: + ui::Point point_; + + ui::controls::FlexLayout container_; + ui::controls::TextBlock label_; + ui::controls::TextBox text_; + bool is_text_valid_; +}; +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/SelectPropertyEditor.cpp b/src/ThemeBuilder/components/properties/SelectPropertyEditor.cpp new file mode 100644 index 00000000..835b2d12 --- /dev/null +++ b/src/ThemeBuilder/components/properties/SelectPropertyEditor.cpp @@ -0,0 +1,15 @@ +#include "SelectPropertyEditor.h" +#include "cru/ui/controls/FlexLayout.h" + +namespace cru::theme_builder::components::properties { +SelectPropertyEditor::SelectPropertyEditor() { + container_.SetFlexDirection(ui::controls::FlexDirection::Horizontal); + container_.AddChild(&label_); + container_.AddChild(select_.GetRootControl()); + + select_.ItemSelectedEvent()->AddHandler( + [this](Index index) { RaiseChangeEvent(); }); +} + +SelectPropertyEditor::~SelectPropertyEditor() {} +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/SelectPropertyEditor.h b/src/ThemeBuilder/components/properties/SelectPropertyEditor.h new file mode 100644 index 00000000..475d2d0a --- /dev/null +++ b/src/ThemeBuilder/components/properties/SelectPropertyEditor.h @@ -0,0 +1,42 @@ +#pragma once +#include "../Editor.h" +#include "cru/ui/components/Select.h" +#include "cru/ui/controls/FlexLayout.h" +#include "cru/ui/controls/TextBlock.h" + +namespace cru::theme_builder::components::properties { +class SelectPropertyEditor : public Editor { + public: + using PropertyType = Index; + + SelectPropertyEditor(); + ~SelectPropertyEditor() override; + + public: + ui::controls::Control* GetRootControl() override { return &container_; } + + String GetLabel() const { return label_.GetText(); } + void SetLabel(String label) { label_.SetText(std::move(label)); } + + Index GetSelectedIndex() const { return select_.GetSelectedIndex(); } + void SetSelectedIndex(Index index, bool trigger_change = true) { + if (trigger_change == false) SuppressNextChangeEvent(); + select_.SetSelectedIndex(index); + } + + std::vector<String> GetItems() const { return select_.GetItems(); } + void SetItems(std::vector<String> items) { + select_.SetItems(std::move(items)); + } + + Index GetValue() const { return GetSelectedIndex(); } + void SetValue(Index value, bool trigger_change = true) { + SetSelectedIndex(value, trigger_change); + } + + private: + ui::controls::FlexLayout container_; + ui::controls::TextBlock label_; + ui::components::Select select_; +}; +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/TextPropertyEditor.cpp b/src/ThemeBuilder/components/properties/TextPropertyEditor.cpp new file mode 100644 index 00000000..9854019c --- /dev/null +++ b/src/ThemeBuilder/components/properties/TextPropertyEditor.cpp @@ -0,0 +1,22 @@ +#include "TextPropertyEditor.h" + +namespace cru::theme_builder::components::properties { +TextPropertyEditor::TextPropertyEditor() { + editor_.TextChangeEvent()->AddHandler([this](std::nullptr_t) { + auto text_view = editor_.GetTextView(); + String error_message; + auto validation_result = Validate(text_view, &error_message); + if (validation_result) { + OnTextChanged(text_view); + } + }); +} + +TextPropertyEditor::~TextPropertyEditor() {} + +bool TextPropertyEditor::Validate(StringView text, String* error_message) { + return true; +} + +void TextPropertyEditor::OnTextChanged(StringView text) {} +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/TextPropertyEditor.h b/src/ThemeBuilder/components/properties/TextPropertyEditor.h new file mode 100644 index 00000000..c4944228 --- /dev/null +++ b/src/ThemeBuilder/components/properties/TextPropertyEditor.h @@ -0,0 +1,31 @@ +#pragma once +#include "cru/ui/components/Component.h" +#include "cru/ui/controls/FlexLayout.h" +#include "cru/ui/controls/TextBlock.h" +#include "cru/ui/controls/TextBox.h" + +namespace cru::theme_builder::components::properties { +class TextPropertyEditor : public ui::components::Component { + public: + TextPropertyEditor(); + ~TextPropertyEditor() override; + + ui::controls::Control* GetRootControl() override { return &container_; } + + String GetLabel() const { return label_.GetText(); } + void SetLabel(String label) { label_.SetText(std::move(label)); } + + String GetText() const { return editor_.GetText(); } + StringView GetTextView() const { return editor_.GetTextView(); } + void SetText(String text) { editor_.SetText(std::move(text)); } + + protected: + virtual bool Validate(StringView text, String* error_message); + virtual void OnTextChanged(StringView text); + + private: + ui::controls::FlexLayout container_; + ui::controls::TextBlock label_; + ui::controls::TextBox editor_; +}; +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/ThicknessPropertyEditor.cpp b/src/ThemeBuilder/components/properties/ThicknessPropertyEditor.cpp new file mode 100644 index 00000000..3e022bb1 --- /dev/null +++ b/src/ThemeBuilder/components/properties/ThicknessPropertyEditor.cpp @@ -0,0 +1,34 @@ +#include "ThicknessPropertyEditor.h" +#include "cru/ui/mapper/MapperRegistry.h" +#include "cru/ui/mapper/ThicknessMapper.h" + +namespace cru::theme_builder::components::properties { +ThicknessPropertyEditor::ThicknessPropertyEditor() { + container_.AddChild(&label_); + container_.AddChild(&text_); + + text_.TextChangeEvent()->AddHandler([this](std::nullptr_t) { + auto text = text_.GetText(); + auto thickness_mapper = + ui::mapper::MapperRegistry::GetInstance()->GetMapper<ui::Thickness>(); + try { + auto thickness = thickness_mapper->MapFromString(text); + thickness_ = thickness; + is_text_valid_ = true; + RaiseChangeEvent(); + } catch (const Exception &) { + is_text_valid_ = false; + // TODO: Show error! + } + }); +} + +ThicknessPropertyEditor::~ThicknessPropertyEditor() {} + +void ThicknessPropertyEditor::SetValue(const ui::Thickness &thickness, + bool trigger_change) { + if (!trigger_change) SuppressNextChangeEvent(); + text_.SetText(Format(u"{} {} {} {}", thickness.left, thickness.top, + thickness.right, thickness.bottom)); +} +} // namespace cru::theme_builder::components::properties diff --git a/src/ThemeBuilder/components/properties/ThicknessPropertyEditor.h b/src/ThemeBuilder/components/properties/ThicknessPropertyEditor.h new file mode 100644 index 00000000..cea9ae9d --- /dev/null +++ b/src/ThemeBuilder/components/properties/ThicknessPropertyEditor.h @@ -0,0 +1,31 @@ +#pragma once +#include "../Editor.h" +#include "cru/ui/controls/FlexLayout.h" +#include "cru/ui/controls/TextBlock.h" +#include "cru/ui/controls/TextBox.h" + +namespace cru::theme_builder::components::properties { +class ThicknessPropertyEditor : public Editor { + public: + using PropertyType = ui::Thickness; + + ThicknessPropertyEditor(); + ~ThicknessPropertyEditor() override; + + ui::controls::Control* GetRootControl() override { return &container_; } + + String GetLabel() const { return label_.GetText(); } + void SetLabel(String label) { label_.SetText(std::move(label)); } + + ui::Thickness GetValue() const { return thickness_; } + void SetValue(const ui::Thickness& thickness, bool trigger_change = true); + + private: + ui::Thickness thickness_; + + ui::controls::FlexLayout container_; + ui::controls::TextBlock label_; + ui::controls::TextBox text_; + bool is_text_valid_; +}; +} // namespace cru::theme_builder::components::properties |