aboutsummaryrefslogtreecommitdiff
path: root/src/ui/controls
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2018-12-06 05:44:38 +0800
committercrupest <crupest@outlook.com>2018-12-06 05:44:38 +0800
commit81fd0725d020e9f302c0d40fd5a5700d3dc871aa (patch)
tree1a99936949271641fbdfa3b4fb7ea448344164f7 /src/ui/controls
parentf0e2b2d3763dd100a5e9d6cda566724d2b7da965 (diff)
downloadcru-81fd0725d020e9f302c0d40fd5a5700d3dc871aa.tar.gz
cru-81fd0725d020e9f302c0d40fd5a5700d3dc871aa.tar.bz2
cru-81fd0725d020e9f302c0d40fd5a5700d3dc871aa.zip
Done.
Diffstat (limited to 'src/ui/controls')
-rw-r--r--src/ui/controls/button.cpp2
-rw-r--r--src/ui/controls/button.hpp7
-rw-r--r--src/ui/controls/frame_layout.cpp62
-rw-r--r--src/ui/controls/frame_layout.hpp6
-rw-r--r--src/ui/controls/linear_layout.cpp12
-rw-r--r--src/ui/controls/linear_layout.hpp2
-rw-r--r--src/ui/controls/list_item.cpp2
-rw-r--r--src/ui/controls/list_item.hpp7
-rw-r--r--src/ui/controls/popup_menu.cpp4
-rw-r--r--src/ui/controls/scroll_control.cpp65
-rw-r--r--src/ui/controls/scroll_control.hpp7
-rw-r--r--src/ui/controls/text_control.cpp2
-rw-r--r--src/ui/controls/text_control.hpp2
-rw-r--r--src/ui/controls/toggle_button.hpp2
14 files changed, 118 insertions, 64 deletions
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<Control*>& children = std::initializer_list<Control*>())
+ 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<Control*>& 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<ListItem>(
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 <limits>
#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<float>::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<Control*>& children = std::initializer_list<Control*>{})
+ 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<IDWriteTextFormat>& init_text_format,
- const Microsoft::WRL::ComPtr<ID2D1Brush>& init_brush) : Control(false)
+ const Microsoft::WRL::ComPtr<ID2D1Brush>& 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";