diff options
-rw-r--r-- | CruUI/base.h | 10 | ||||
-rw-r--r-- | CruUI/global_macros.h | 4 | ||||
-rw-r--r-- | CruUI/ui/control.cpp | 70 | ||||
-rw-r--r-- | CruUI/ui/control.h | 5 | ||||
-rw-r--r-- | CruUI/ui/layout_base.h | 84 |
5 files changed, 72 insertions, 101 deletions
diff --git a/CruUI/base.h b/CruUI/base.h index 0d401a3a..83d1968c 100644 --- a/CruUI/base.h +++ b/CruUI/base.h @@ -1,10 +1,15 @@ #pragma once +// ReSharper disable once CppUnusedIncludeDirective #include "global_macros.h" + #include <folly/String.h> #include <folly/Function.h> +#include <stdexcept> + + namespace cru { enum class FlowControl @@ -39,4 +44,9 @@ namespace cru { virtual ~Interface() = default; }; + + [[noreturn]] inline void UnreachableCode() + { + throw std::logic_error("Unreachable code."); + } } diff --git a/CruUI/global_macros.h b/CruUI/global_macros.h index fcb93174..7d8da00b 100644 --- a/CruUI/global_macros.h +++ b/CruUI/global_macros.h @@ -1,3 +1,7 @@ #pragma once +#ifdef _DEBUG +#define CRU_DEBUG +#endif + #define GLOG_NO_ABBREVIATED_SEVERITIES diff --git a/CruUI/ui/control.cpp b/CruUI/ui/control.cpp index db409e34..e8223498 100644 --- a/CruUI/ui/control.cpp +++ b/CruUI/ui/control.cpp @@ -11,8 +11,10 @@ namespace cru { Control::Control() : window_(nullptr), parent_(nullptr), + children_(), position_(Point::zero), size_(Size::zero), + position_cache_(), is_mouse_inside_(false), layout_params_(nullptr), desired_size_(Size::zero) @@ -114,11 +116,6 @@ namespace cru { return ancestor; } - Window * Control::GetWindow() - { - return window_; - } - void TraverseDescendantsInternal(Control* control, const std::function<void(Control*)>& predicate) { @@ -381,52 +378,30 @@ namespace cru { { const auto layout_params = GetLayoutParams(); -#ifdef _DEBUG if (!layout_params->Validate()) - ::OutputDebugStringW(L"LayoutParams is not valid."); -#endif - - auto&& f = []( - const MeasureLength& layout_length, - const float available_length, - const std::optional<float> max_length, - const std::optional<float> min_length - ) -> float + throw std::runtime_error("LayoutParams is not valid. Please check it."); + + auto&& get_available_length_for_child = [](const MeasureLength& layout_length, const float available_length) -> float { switch (layout_length.mode) { case MeasureMode::Exactly: { - auto length = layout_length.length; - if (min_length.has_value()) - length = std::max(min_length.value(), length); - if (max_length.has_value()) - length = std::min(max_length.value(), length); - if (available_length < length) - { - length = available_length; - ::OutputDebugStringW(L"Available length is not enough"); - } - return length; + return std::min(layout_length.length, available_length); } case MeasureMode::Stretch: case MeasureMode::Content: { - auto length = available_length; - if (min_length.has_value() && min_length.value() > length) - ::OutputDebugStringW(L"Min length is less than available length."); - if (max_length.has_value()) - length = std::min(max_length.value(), length); - return length; + return available_length; } default: - throw std::logic_error("Unreachable code."); + UnreachableCode(); } }; - Size size_for_children; - size_for_children.width = f(layout_params->size.width, available_size.width, layout_params->max_size.width, layout_params->min_size.width); - size_for_children.height = f(layout_params->size.height, available_size.height, layout_params->max_size.height, layout_params->min_size.height);; + Size size_for_children{}; + size_for_children.width = get_available_length_for_child(layout_params->width, available_size.width); + size_for_children.height = get_available_length_for_child(layout_params->height, available_size.height); auto max_child_size = Size::zero; ForeachChild([&](Control* control) @@ -439,13 +414,32 @@ namespace cru { max_child_size.height = size.height; }); + auto&& calculate_final_length = [](const MeasureLength& 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(); + } + }; - //TODO! + return Size( + calculate_final_length(layout_params->width, size_for_children.width, max_child_size.width), + calculate_final_length(layout_params->height, size_for_children.height, max_child_size.height) + ); } void Control::OnLayout(const Rect& rect) { - //TODO! + ForeachChild([](Control* control) + { + control->Layout(Rect(Point::zero, control->GetDesiredSize())); + }); } std::list<Control*> GetAncestorList(Control* control) diff --git a/CruUI/ui/control.h b/CruUI/ui/control.h index e7fe2d45..f9c47a95 100644 --- a/CruUI/ui/control.h +++ b/CruUI/ui/control.h @@ -74,7 +74,10 @@ namespace cru Control* GetAncestor(); //Get the window if attached, otherwise, return nullptr. - Window* GetWindow(); + Window* GetWindow() const + { + return window_; + } //Traverse the tree rooted the control. void TraverseDescendants(const std::function<void(Control*)>& predicate); diff --git a/CruUI/ui/layout_base.h b/CruUI/ui/layout_base.h index 409c2875..0213b879 100644 --- a/CruUI/ui/layout_base.h +++ b/CruUI/ui/layout_base.h @@ -1,7 +1,5 @@ #pragma once -#include <optional> - namespace cru { namespace ui @@ -23,55 +21,18 @@ namespace cru bool Validate() const { - return !(mode == MeasureMode::Exactly && length < 0.0); - } - - float length; - MeasureMode mode; - }; - - struct MeasureSize final - { - MeasureLength width; - MeasureLength height; - - bool Validate() const - { - return width.Validate() && height.Validate(); - } - }; - - struct OptionalSize final - { - OptionalSize() - : width(std::nullopt), height(std::nullopt) - { - - } - - OptionalSize(const std::optional<float> width, const std::optional<float> height) - : width(width), height(height) - { - - } - - OptionalSize(const OptionalSize& other) = default; - OptionalSize(OptionalSize&& other) = default; - OptionalSize& operator = (const OptionalSize& other) = default; - OptionalSize& operator = (OptionalSize&& other) = default; - ~OptionalSize() = default; - - bool Validate() const - { - if (width.has_value() && width.value() < 0.0) - return false; - if (height.has_value() && height.value() < 0.0) + if (mode == MeasureMode::Exactly && length < 0.0) + { +#ifdef CRU_DEBUG + ::OutputDebugStringW(L"MeasureLength validation error: mode is Exactly but length is less than 0.\n"); +#endif return false; + } return true; } - std::optional<float> width; - std::optional<float> height; + float length; + MeasureMode mode; }; struct BasicLayoutParams @@ -85,26 +46,25 @@ namespace cru bool Validate() const { - if (!(size.Validate() && max_size.Validate() && min_size.Validate())) - return false; - - auto&& f = [](const std::optional<float> max_length, const std::optional<float> min_length) -> bool + if (!width.Validate()) { - return max_length.has_value() && min_length.has_value() && max_length.value() < min_length.value(); - }; - - if (!f(max_size.width, min_size.width)) +#ifdef CRU_DEBUG + ::OutputDebugStringW(L"Width(MeasureLength) is not valid."); +#endif return false; - - if (!f(max_size.height, min_size.height)) + } + if (!height.Validate()) + { +#ifdef CRU_DEBUG + ::OutputDebugStringW(L"Height(MeasureLength) is not valid."); +#endif return false; - + } return true; } - MeasureSize size; - OptionalSize min_size; - OptionalSize max_size; + MeasureLength width; + MeasureLength height; }; } -}
\ No newline at end of file +} |