From 81fd0725d020e9f302c0d40fd5a5700d3dc871aa Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 6 Dec 2018 05:44:38 +0800 Subject: Done. --- src/ui/controls/button.cpp | 2 +- src/ui/controls/button.hpp | 7 ++-- src/ui/controls/frame_layout.cpp | 62 +++++++++++++++++++++++++++++++++--- src/ui/controls/frame_layout.hpp | 6 +++- src/ui/controls/linear_layout.cpp | 12 +++---- src/ui/controls/linear_layout.hpp | 2 +- src/ui/controls/list_item.cpp | 2 +- src/ui/controls/list_item.hpp | 7 ++-- src/ui/controls/popup_menu.cpp | 4 +-- src/ui/controls/scroll_control.cpp | 65 +++++++++++++++++++------------------- src/ui/controls/scroll_control.hpp | 7 ++-- src/ui/controls/text_control.cpp | 2 +- src/ui/controls/text_control.hpp | 2 +- src/ui/controls/toggle_button.hpp | 2 +- 14 files changed, 118 insertions(+), 64 deletions(-) (limited to 'src/ui/controls') diff --git a/src/ui/controls/button.cpp b/src/ui/controls/button.cpp index a9f101f8..d4537f54 100644 --- a/src/ui/controls/button.cpp +++ b/src/ui/controls/button.cpp @@ -5,7 +5,7 @@ namespace cru::ui::controls { - Button::Button() : Control(true), + Button::Button() : normal_border_{UiManager::GetInstance()->GetPredefineResources()->button_normal_border}, pressed_border_{UiManager::GetInstance()->GetPredefineResources()->button_press_border} { diff --git a/src/ui/controls/button.hpp b/src/ui/controls/button.hpp index c53f7ed9..82694fe8 100644 --- a/src/ui/controls/button.hpp +++ b/src/ui/controls/button.hpp @@ -9,16 +9,15 @@ namespace cru::ui::controls { - class Button : public Control + class Button : public SingleChildControl { public: static constexpr auto control_type = L"Button"; - static Button* Create(const std::initializer_list& children = std::initializer_list()) + static Button* Create(Control* child = nullptr) { const auto button = new Button(); - for (const auto control : children) - button->AddChild(control); + button->SetChild(child); return button; } diff --git a/src/ui/controls/frame_layout.cpp b/src/ui/controls/frame_layout.cpp index 32d25edc..d68bc338 100644 --- a/src/ui/controls/frame_layout.cpp +++ b/src/ui/controls/frame_layout.cpp @@ -2,10 +2,7 @@ namespace cru::ui::controls { - FrameLayout::FrameLayout() : Control(true) - { - - } + FrameLayout::FrameLayout() = default; FrameLayout::~FrameLayout() = default; @@ -13,4 +10,61 @@ namespace cru::ui::controls { return control_type; } + + Size FrameLayout::OnMeasureContent(const Size& available_size, const AdditionalMeasureInfo& additional_info) + { + auto max_child_size = Size::Zero(); + for (auto control: GetChildren()) + { + control->Measure(available_size, additional_info); + const auto&& size = control->GetDesiredSize(); + if (max_child_size.width < size.width) + max_child_size.width = size.width; + if (max_child_size.height < size.height) + max_child_size.height = size.height; + } + + // coerce size fro stretch. + for (auto control: GetChildren()) + { + auto size = control->GetDesiredSize(); + const auto layout_params = control->GetLayoutParams(); + if (layout_params->width.mode == MeasureMode::Stretch) + size.width = max_child_size.width; + if (layout_params->height.mode == MeasureMode::Stretch) + size.height = max_child_size.height; + control->SetDesiredSize(size); + } + + return max_child_size; + } + + void FrameLayout::OnLayoutContent(const Rect& rect, const AdditionalLayoutInfo& additional_info) + { + for (auto control: GetChildren()) + { + const auto layout_params = control->GetLayoutParams(); + const auto size = control->GetDesiredSize(); + + auto&& calculate_anchor = [](const float anchor, const Alignment alignment, const float layout_length, const float control_length) -> float + { + switch (alignment) + { + case Alignment::Center: + return anchor + (layout_length - control_length) / 2; + case Alignment::Start: + return anchor; + case Alignment::End: + return anchor + layout_length - control_length; + default: + UnreachableCode(); + } + }; + + control->Layout(Rect(Point( + calculate_anchor(rect.left, layout_params->width.alignment, rect.width, size.width), + calculate_anchor(rect.top, layout_params->height.alignment, rect.height, size.height) + ), size), additional_info); + } + } } diff --git a/src/ui/controls/frame_layout.hpp b/src/ui/controls/frame_layout.hpp index 45971584..c2d6f0d6 100644 --- a/src/ui/controls/frame_layout.hpp +++ b/src/ui/controls/frame_layout.hpp @@ -9,7 +9,7 @@ namespace cru::ui::controls { - class FrameLayout : public Control + class FrameLayout : public MultiChildControl { public: static constexpr auto control_type = L"FrameLayout"; @@ -32,5 +32,9 @@ namespace cru::ui::controls ~FrameLayout() override; StringView GetControlType() const override final; + + protected: + Size OnMeasureContent(const Size& available_size, const AdditionalMeasureInfo& additional_info) override; + void OnLayoutContent(const Rect& rect, const AdditionalLayoutInfo& additional_info) override; }; } diff --git a/src/ui/controls/linear_layout.cpp b/src/ui/controls/linear_layout.cpp index 2b8f3e43..d3fdc9b5 100644 --- a/src/ui/controls/linear_layout.cpp +++ b/src/ui/controls/linear_layout.cpp @@ -7,7 +7,7 @@ namespace cru::ui::controls { LinearLayout::LinearLayout(const Orientation orientation) - : Control(true), orientation_(orientation) + : orientation_(orientation) { } @@ -27,7 +27,7 @@ namespace cru::ui::controls // First measure Content and Exactly and count Stretch. if (orientation_ == Orientation::Horizontal) - for(auto control: GetChildren()) + for(auto control: GetInternalChildren()) { const auto mode = control->GetLayoutParams()->width.mode; if (mode == MeasureMode::Content || mode == MeasureMode::Exactly) @@ -42,7 +42,7 @@ namespace cru::ui::controls stretch_control_list.push_back(control); } else - for(auto control: GetChildren()) + for(auto control: GetInternalChildren()) { const auto mode = control->GetLayoutParams()->height.mode; if (mode == MeasureMode::Content || mode == MeasureMode::Exactly) @@ -82,7 +82,7 @@ namespace cru::ui::controls if (orientation_ == Orientation::Horizontal) { - for (auto control : GetChildren()) + for (auto control : GetInternalChildren()) { if (control->GetLayoutParams()->height.mode == MeasureMode::Stretch) { @@ -93,7 +93,7 @@ namespace cru::ui::controls } else { - for (auto control : GetChildren()) + for (auto control : GetInternalChildren()) { if (control->GetLayoutParams()->width.mode == MeasureMode::Stretch) { @@ -110,7 +110,7 @@ namespace cru::ui::controls void LinearLayout::OnLayoutContent(const Rect& rect, const AdditionalLayoutInfo& additional_info) { float current_main_side_anchor = 0; - for(auto control: GetChildren()) + for(auto control: GetInternalChildren()) { const auto layout_params = control->GetLayoutParams(); const auto size = control->GetDesiredSize(); diff --git a/src/ui/controls/linear_layout.hpp b/src/ui/controls/linear_layout.hpp index 96becc6f..ceb1c4e6 100644 --- a/src/ui/controls/linear_layout.hpp +++ b/src/ui/controls/linear_layout.hpp @@ -9,7 +9,7 @@ namespace cru::ui::controls { // Min length of main side in layout params is of no meaning. // All children will layout from start and redundant length is blank. - class LinearLayout : public Control + class LinearLayout : public MultiChildControl { public: static constexpr auto control_type = L"LinearLayout"; diff --git a/src/ui/controls/list_item.cpp b/src/ui/controls/list_item.cpp index 8234da30..e0ca28a9 100644 --- a/src/ui/controls/list_item.cpp +++ b/src/ui/controls/list_item.cpp @@ -5,7 +5,7 @@ namespace cru::ui::controls { - ListItem::ListItem() : Control(true) + ListItem::ListItem() { const auto predefine_resources = UiManager::GetInstance()->GetPredefineResources(); diff --git a/src/ui/controls/list_item.hpp b/src/ui/controls/list_item.hpp index e150efbb..a50b2496 100644 --- a/src/ui/controls/list_item.hpp +++ b/src/ui/controls/list_item.hpp @@ -10,7 +10,7 @@ namespace cru::ui::controls { - class ListItem : public Control + class ListItem : public SingleChildControl { public: static constexpr auto control_type = L"ListItem"; @@ -30,11 +30,10 @@ namespace cru::ui::controls }; public: - static ListItem* Create(const std::initializer_list& children) + static ListItem* Create(Control* child = nullptr) { const auto list_item = new ListItem(); - for (auto control : children) - list_item->AddChild(control); + list_item->SetChild(child); return list_item; } diff --git a/src/ui/controls/popup_menu.cpp b/src/ui/controls/popup_menu.cpp index 7f4b9d08..fbe9039d 100644 --- a/src/ui/controls/popup_menu.cpp +++ b/src/ui/controls/popup_menu.cpp @@ -26,7 +26,7 @@ namespace cru::ui::controls auto list_item = CreateWithLayout( LayoutSideParams::Stretch(Alignment::Center), LayoutSideParams::Content(Alignment::Start), - ControlList{ text_block } + text_block ); list_item->mouse_click_event.bubble.AddHandler([popup, action](events::MouseButtonEventArgs& args) @@ -48,7 +48,7 @@ namespace cru::ui::controls for (const auto& item : items) menu->AddChild(create_menu_item(item.first, item.second)); - popup->AddChild(menu); + popup->SetChild(menu); popup->SetSizeFitContent(); popup->SetWindowPosition(anchor); diff --git a/src/ui/controls/scroll_control.cpp b/src/ui/controls/scroll_control.cpp index 8358abc5..ae99f414 100644 --- a/src/ui/controls/scroll_control.cpp +++ b/src/ui/controls/scroll_control.cpp @@ -3,7 +3,6 @@ #include #include "cru_debug.hpp" -#include "format.hpp" #include "ui/convert_util.hpp" #include "exception.hpp" #include "math_util.hpp" @@ -14,7 +13,7 @@ namespace cru::ui::controls { constexpr auto scroll_bar_width = 15.0f; - ScrollControl::ScrollControl(const bool container) : Control(container) + ScrollControl::ScrollControl(const bool container) { SetClipContent(true); @@ -245,38 +244,25 @@ namespace cru::ui::controls available_size_for_children.height = std::numeric_limits::max(); } - auto max_child_size = Size::Zero(); - for (auto control: GetChildren()) - { - control->Measure(available_size_for_children, AdditionalMeasureInfo{false, false}); - const auto&& size = control->GetDesiredSize(); - if (max_child_size.width < size.width) - max_child_size.width = size.width; - if (max_child_size.height < size.height) - max_child_size.height = size.height; - } + const auto child = GetChild(); - // coerce size for stretch. - for (auto control: GetChildren()) + auto size = Size::Zero(); + if (child) { - auto size = control->GetDesiredSize(); - const auto child_layout_params = control->GetLayoutParams(); - if (child_layout_params->width.mode == MeasureMode::Stretch) - size.width = max_child_size.width; - if (child_layout_params->height.mode == MeasureMode::Stretch) - size.height = max_child_size.height; - control->SetDesiredSize(size); + child->Measure(available_size_for_children, AdditionalMeasureInfo{false, false}); + size = child->GetDesiredSize(); } - auto result = max_child_size; + + auto result = size; if (IsHorizontalScrollEnabled()) { - SetViewWidth(max_child_size.width); + SetViewWidth(size.width); result.width = available_size.width; } if (IsVerticalScrollEnabled()) { - SetViewHeight(max_child_size.height); + SetViewHeight(size.height); result.height = available_size.height; } @@ -292,18 +278,31 @@ namespace cru::ui::controls if (IsVerticalScrollEnabled()) layout_rect.height = GetViewHeight(); - for (auto control: GetChildren()) + const auto child = GetChild(); + + if (child) { - const auto size = control->GetDesiredSize(); - // Ignore alignment, always center aligned. - auto&& calculate_anchor = [](const float anchor, const float layout_length, const float control_length, const float offset) -> float + const auto layout_params = child->GetLayoutParams(); + const auto size = child->GetDesiredSize(); + + auto&& calculate_anchor = [](const float anchor, const Alignment alignment, const float layout_length, const float control_length) -> float { - return anchor + (layout_length - control_length) / 2 - offset; + switch (alignment) + { + case Alignment::Center: + return anchor + (layout_length - control_length) / 2; + case Alignment::Start: + return anchor; + case Alignment::End: + return anchor + layout_length - control_length; + default: + UnreachableCode(); + } }; - control->Layout(Rect(Point( - calculate_anchor(rect.left, layout_rect.width, size.width, offset_x_), - calculate_anchor(rect.top, layout_rect.height, size.height, offset_y_) + child->Layout(Rect(Point( + IsHorizontalScrollEnabled() ? layout_rect.left + offset_x_ : calculate_anchor(layout_rect.left, layout_params->width.alignment, layout_rect.width, size.width), + IsVerticalScrollEnabled() ? layout_rect.top + offset_y_ : calculate_anchor(layout_rect.top, layout_params->height.alignment, layout_rect.height, size.height) ), size), additional_info); } } @@ -327,7 +326,7 @@ namespace cru::ui::controls if (update_children) { - for (auto child : GetChildren()) + if (const auto child = GetChild()) { const auto old_position = child->GetPositionRelative(); child->SetRect(Rect(Point( diff --git a/src/ui/controls/scroll_control.hpp b/src/ui/controls/scroll_control.hpp index db29b141..7138add6 100644 --- a/src/ui/controls/scroll_control.hpp +++ b/src/ui/controls/scroll_control.hpp @@ -17,7 +17,7 @@ namespace cru::ui::controls // Done: API // Done: ScrollBar // Done: MouseEvent - class ScrollControl : public Control + class ScrollControl : public SingleChildControl { private: struct ScrollBarInfo @@ -40,11 +40,10 @@ namespace cru::ui::controls Always }; - static ScrollControl* Create(const std::initializer_list& children = std::initializer_list{}) + static ScrollControl* Create(Control* child = nullptr) { const auto control = new ScrollControl(true); - for (auto child : children) - control->AddChild(child); + control->SetChild(child); return control; } diff --git a/src/ui/controls/text_control.cpp b/src/ui/controls/text_control.cpp index 6412eec9..e53d3c69 100644 --- a/src/ui/controls/text_control.cpp +++ b/src/ui/controls/text_control.cpp @@ -44,7 +44,7 @@ namespace cru::ui::controls } TextControl::TextControl(const Microsoft::WRL::ComPtr& init_text_format, - const Microsoft::WRL::ComPtr& init_brush) : Control(false) + const Microsoft::WRL::ComPtr& init_brush) { text_format_ = init_text_format; diff --git a/src/ui/controls/text_control.hpp b/src/ui/controls/text_control.hpp index 9b83f4bb..58d48c13 100644 --- a/src/ui/controls/text_control.hpp +++ b/src/ui/controls/text_control.hpp @@ -7,7 +7,7 @@ namespace cru::ui::controls { - class TextControl : public Control + class TextControl : public NoChildControl { protected: TextControl( diff --git a/src/ui/controls/toggle_button.hpp b/src/ui/controls/toggle_button.hpp index 091f908a..dee655d4 100644 --- a/src/ui/controls/toggle_button.hpp +++ b/src/ui/controls/toggle_button.hpp @@ -7,7 +7,7 @@ namespace cru::ui::controls { - class ToggleButton : public Control + class ToggleButton : public NoChildControl { public: static constexpr auto control_type = L"ToggleButton"; -- cgit v1.2.3