aboutsummaryrefslogtreecommitdiff
path: root/src/ui/controls/margin_container.cpp
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2018-09-30 20:38:10 +0800
committercrupest <crupest@outlook.com>2018-09-30 20:38:10 +0800
commit88765aab936724cb01fa2ffd86d65181182a1cd2 (patch)
treecf8f400d221756add6c6a61ef001130812f57313 /src/ui/controls/margin_container.cpp
parent20dc75e2ce6a9c38dd1888fdbf793fd8a3bc9cd3 (diff)
downloadcru-88765aab936724cb01fa2ffd86d65181182a1cd2.tar.gz
cru-88765aab936724cb01fa2ffd86d65181182a1cd2.tar.bz2
cru-88765aab936724cb01fa2ffd86d65181182a1cd2.zip
Create border delegate.
Diffstat (limited to 'src/ui/controls/margin_container.cpp')
-rw-r--r--src/ui/controls/margin_container.cpp85
1 files changed, 58 insertions, 27 deletions
diff --git a/src/ui/controls/margin_container.cpp b/src/ui/controls/margin_container.cpp
index 1f331d32..26acb172 100644
--- a/src/ui/controls/margin_container.cpp
+++ b/src/ui/controls/margin_container.cpp
@@ -25,39 +25,70 @@ namespace cru::ui::controls
Size MarginContainer::OnMeasure(const Size& available_size)
{
+ const auto layout_params = GetLayoutParams();
+
+ if (!layout_params->Validate())
+ throw std::runtime_error("LayoutParams is not valid. Please check it.");
+
+ auto&& get_available_length_for_child = [](const LayoutSideParams& layout_length, const float available_length) -> float
+ {
+ switch (layout_length.mode)
+ {
+ case MeasureMode::Exactly:
+ {
+ return std::min(layout_length.length, available_length);
+ }
+ case MeasureMode::Stretch:
+ case MeasureMode::Content:
+ {
+ return available_length;
+ }
+ default:
+ UnreachableCode();
+ }
+ };
+
+ const Size size_for_children(get_available_length_for_child(layout_params->width, available_size.width),
+ get_available_length_for_child(layout_params->height, available_size.height));
+
const auto margin_size = Size(margin_.left + margin_.right, margin_.top + margin_.bottom);
- const auto coerced_available_size = AtLeast0(available_size - margin_size);
- return Control::OnMeasure(coerced_available_size) + margin_size;
+ const auto coerced_size_for_children = AtLeast0(size_for_children - margin_size);
+
+ auto max_child_size = Size::Zero();
+ ForeachChild([coerced_size_for_children, &max_child_size](Control* control)
+ {
+ control->Measure(coerced_size_for_children);
+ 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;
+ });
+
+ auto&& calculate_final_length = [](const LayoutSideParams& layout_length, const float length_for_children, const float max_child_length) -> float
+ {
+ switch (layout_length.mode)
+ {
+ case MeasureMode::Exactly:
+ case MeasureMode::Stretch:
+ return length_for_children;
+ case MeasureMode::Content:
+ return max_child_length;
+ default:
+ UnreachableCode();
+ }
+ };
+
+ return Size(
+ calculate_final_length(layout_params->width, coerced_size_for_children.width, max_child_size.width),
+ calculate_final_length(layout_params->height, coerced_size_for_children.height, max_child_size.height)
+ );
}
void MarginContainer::OnLayout(const Rect& rect)
{
const auto anchor = Point(margin_.left, margin_.top);
const auto margin_size = Size(margin_.left + margin_.right, margin_.top + margin_.bottom);
- ForeachChild([anchor, margin_size, rect](Control* control)
- {
- 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(anchor.x, layout_params->width.alignment, rect.width - margin_size.width, size.width),
- calculate_anchor(anchor.y, layout_params->height.alignment, rect.height - margin_size.height, size.height)
- ), size));
- });
+ Control::OnLayout(Rect(anchor, AtLeast0(rect.GetSize() - margin_size)));
}
}