aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CruUI/base.h10
-rw-r--r--CruUI/global_macros.h4
-rw-r--r--CruUI/ui/control.cpp70
-rw-r--r--CruUI/ui/control.h5
-rw-r--r--CruUI/ui/layout_base.h84
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
+}