aboutsummaryrefslogtreecommitdiff
path: root/CruUI/ui/controls/linear_layout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'CruUI/ui/controls/linear_layout.cpp')
-rw-r--r--CruUI/ui/controls/linear_layout.cpp178
1 files changed, 0 insertions, 178 deletions
diff --git a/CruUI/ui/controls/linear_layout.cpp b/CruUI/ui/controls/linear_layout.cpp
deleted file mode 100644
index 8f537ea8..00000000
--- a/CruUI/ui/controls/linear_layout.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-#include "linear_layout.h"
-
-namespace cru::ui::controls
-{
- LinearLayout::LinearLayout(const Orientation orientation)
- : Control(true), orientation_(orientation)
- {
-
- }
-
- inline float AtLeast0(const float value)
- {
- return value < 0 ? 0 : value;
- }
-
- inline Size AtLeast0(const Size& size)
- {
- return Size(AtLeast0(size.width), AtLeast0(size.height));
- }
-
- Size LinearLayout::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();
- }
- };
-
- Size total_available_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)
- );
-
- auto rest_available_size_for_children = total_available_size_for_children;
-
- float secondary_side_child_max_length = 0;
-
- std::list<Control*> stretch_control_list;
-
- // First measure Content and Exactly and count Stretch.
- if (orientation_ == Orientation::Horizontal)
- ForeachChild([&](Control* const control)
- {
- const auto mode = control->GetLayoutParams()->width.mode;
- if (mode == MeasureMode::Content || mode == MeasureMode::Exactly)
- {
- control->Measure(AtLeast0(rest_available_size_for_children));
- const auto size = control->GetDesiredSize();
- rest_available_size_for_children.width -= size.width;
- secondary_side_child_max_length = std::max(size.height, secondary_side_child_max_length);
- }
- else
- stretch_control_list.push_back(control);
- });
- else
- ForeachChild([&](Control* const control)
- {
- const auto mode = control->GetLayoutParams()->height.mode;
- if (mode == MeasureMode::Content || mode == MeasureMode::Exactly)
- {
- control->Measure(AtLeast0(rest_available_size_for_children));
- const auto size = control->GetDesiredSize();
- rest_available_size_for_children.height -= size.height;
- secondary_side_child_max_length = std::max(size.width, secondary_side_child_max_length);
- }
- else
- stretch_control_list.push_back(control);
- });
-
- if (orientation_ == Orientation::Horizontal)
- {
- const auto available_width = rest_available_size_for_children.width / stretch_control_list.size();
- for (const auto control : stretch_control_list)
- {
- control->Measure(Size(AtLeast0(available_width), rest_available_size_for_children.height));
- const auto size = control->GetDesiredSize();
- rest_available_size_for_children.width -= size.width;
- secondary_side_child_max_length = std::max(size.height, secondary_side_child_max_length);
- }
- }
- else
- {
- const auto available_height = rest_available_size_for_children.height / stretch_control_list.size();
- for (const auto control : stretch_control_list)
- {
- control->Measure(Size(rest_available_size_for_children.width, AtLeast0(available_height)));
- const auto size = control->GetDesiredSize();
- rest_available_size_for_children.height -= size.height;
- secondary_side_child_max_length = std::max(size.width, secondary_side_child_max_length);
- }
- }
-
- auto actual_size_for_children = total_available_size_for_children;
- if (orientation_ == Orientation::Horizontal)
- {
- actual_size_for_children.width -= rest_available_size_for_children.width;
- actual_size_for_children.height = secondary_side_child_max_length;
- }
- else
- {
- actual_size_for_children.width = secondary_side_child_max_length;
- actual_size_for_children.height -= rest_available_size_for_children.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, total_available_size_for_children.width, actual_size_for_children.width),
- calculate_final_length(layout_params->height, total_available_size_for_children.height, actual_size_for_children.height)
- );
- }
-
- void LinearLayout::OnLayout(const Rect& rect)
- {
- float current_anchor_length = 0;
- ForeachChild([this, &current_anchor_length, rect](Control* control)
- {
- const auto layout_params = control->GetLayoutParams();
- const auto size = control->GetDesiredSize();
- const auto alignment = orientation_ == Orientation::Horizontal ? layout_params->height.alignment : layout_params->width.alignment;
-
- auto&& calculate_anchor = [alignment](const float layout_length, const float control_length) -> float
- {
- switch (alignment)
- {
- case Alignment::Center:
- return (layout_length - control_length) / 2;
- case Alignment::Start:
- return 0;
- case Alignment::End:
- return layout_length - control_length;
- default:
- UnreachableCode();
- }
- };
-
- if (orientation_ == Orientation::Horizontal)
- {
- control->Layout(Rect(Point(current_anchor_length, calculate_anchor(rect.height, size.height)), size));
- current_anchor_length += size.width;
- }
- else
- {
- control->Layout(Rect(Point(calculate_anchor(rect.width, size.width), current_anchor_length), size));
- current_anchor_length += size.height;
- }
- });
- }
-}