diff options
author | crupest <crupest@outlook.com> | 2018-09-30 20:38:10 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2018-09-30 20:38:10 +0800 |
commit | 88765aab936724cb01fa2ffd86d65181182a1cd2 (patch) | |
tree | cf8f400d221756add6c6a61ef001130812f57313 /src/ui/controls/margin_container.cpp | |
parent | 20dc75e2ce6a9c38dd1888fdbf793fd8a3bc9cd3 (diff) | |
download | cru-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.cpp | 85 |
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))); } } |