From 9f7de7f0775b86e3c82d4c5e3427a6f2fd98810b Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 7 Nov 2018 17:23:43 +0800 Subject: Improve layout system. --- src/main.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index ab641075..a15fa4da 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -84,7 +84,7 @@ int APIENTRY wWinMain( }); */ - /* + //test 2 const auto layout = CreateWithLayout(LayoutSideParams::Exactly(500), LayoutSideParams::Content()); @@ -112,7 +112,8 @@ int APIENTRY wWinMain( { const auto button = Button::Create(); - button->AddChild(MarginContainer::Create(Thickness(20, 5), { TextBlock::Create(L"button") })); + button->GetLayoutParams()->padding = Thickness(20, 5); + button->AddChild(TextBlock::Create(L"button")); layout->AddChild(button); } @@ -138,7 +139,6 @@ int APIENTRY wWinMain( window.AddChild(layout); - */ /* window.AddChild( @@ -149,6 +149,7 @@ int APIENTRY wWinMain( )); */ + /* test 3 const auto linear_layout = CreateWithLayout(Thickness(50, 50), Thickness(50, 50), LinearLayout::Orientation::Vertical, ControlList{ Button::Create({ TextBlock::Create(L"Button") @@ -159,6 +160,7 @@ int APIENTRY wWinMain( linear_layout->SetBordered(true); window.AddChild(linear_layout); + */ window.Show(); -- cgit v1.2.3 From 2b5b89e9483063f3af05fb5485043868d447994b Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 7 Nov 2018 18:54:41 +0800 Subject: Add min max. --- src/base.h | 28 ++++++++++++++++++++++++++++ src/main.cpp | 7 +++++++ src/ui/control.cpp | 18 ++++++++---------- src/ui/controls/linear_layout.h | 2 ++ src/ui/layout_base.h | 17 ++++++++++++++++- 5 files changed, 61 insertions(+), 11 deletions(-) (limited to 'src/main.cpp') diff --git a/src/base.h b/src/base.h index c8866cf6..9b3b50a1 100644 --- a/src/base.h +++ b/src/base.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace cru { @@ -63,4 +64,31 @@ namespace cru if (!condition) throw std::invalid_argument(error_message.data()); } + + template >> + float Coerce(const T n, const std::optional min, const std::optional max) + { + if (min.has_value() && n < min.value()) + return min.value(); + if (max.has_value() && n > max.value()) + return max.value(); + return n; + } + + template >> + float Coerce(const T n, const std::nullopt_t, const std::optional max) + { + if (max.has_value() && n > max.value()) + return max.value(); + return n; + } + + template >> + float Coerce(const T n, const std::optional min, const std::nullopt_t) + { + if (min.has_value() && n < min.value()) + return min.value(); + return n; + } + } diff --git a/src/main.cpp b/src/main.cpp index a15fa4da..5fd59ede 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -128,6 +128,13 @@ int APIENTRY wWinMain( layout->AddChild(text_block); } + { + const auto text_box = TextBox::Create(); + text_box->GetLayoutParams()->width.min = 50.0f; + text_box->GetLayoutParams()->width.max = 100.0f; + layout->AddChild(text_box); + } + { const auto text_block = CreateWithLayout(LayoutSideParams::Stretch(), LayoutSideParams::Stretch(), L"This is a very very very very very long sentence!!!"); text_block->SetSelectable(true); diff --git a/src/ui/control.cpp b/src/ui/control.cpp index 79def066..9416d48a 100644 --- a/src/ui/control.cpp +++ b/src/ui/control.cpp @@ -689,11 +689,6 @@ namespace cru { return value < 0 ? 0 : value; } - inline Size AtLeast0(const Size& size) - { - return Size(AtLeast0(size.width), AtLeast0(size.height)); - } - Size Control::OnMeasureCore(const Size& available_size) { const auto layout_params = GetLayoutParams(); @@ -715,11 +710,14 @@ namespace cru { auto&& get_content_measure_length = [](const LayoutSideParams& layout_length, const float available_length, const float outer_length) -> float { + float length; if (layout_length.mode == MeasureMode::Exactly) - return layout_length.length; - if (available_length > outer_length) - return available_length - outer_length; - return 0.0; + length = layout_length.length; + else if (available_length > outer_length) + length = available_length - outer_length; + else + length = 0; + return Coerce(length, layout_length.min, layout_length.max); }; // if padding, margin and border exceeded, then content size is 0. @@ -735,7 +733,7 @@ namespace cru { // only use measure length when stretch and actual length is smaller than measure length, that is "stretch" if (layout_length.mode == MeasureMode::Stretch && actual_length < measure_length) return measure_length; - return actual_length; + return Coerce(actual_length, layout_length.min, std::nullopt); }; const auto final_size = Size( diff --git a/src/ui/controls/linear_layout.h b/src/ui/controls/linear_layout.h index 1c2232bb..021f4b7d 100644 --- a/src/ui/controls/linear_layout.h +++ b/src/ui/controls/linear_layout.h @@ -4,6 +4,8 @@ namespace cru::ui::controls { + // Min length of main side in layout params is of no meaning. + // All children will layout from start and redundant length is blank. class LinearLayout : public Control { public: diff --git a/src/ui/layout_base.h b/src/ui/layout_base.h index 662210bd..4a4c09ea 100644 --- a/src/ui/layout_base.h +++ b/src/ui/layout_base.h @@ -101,12 +101,27 @@ namespace cru constexpr bool Validate() const { - return length >= 0.0; + if (length < 0.0) + return false; + if (min.has_value() && min.value() < 0.0) + return false; + if (max.has_value() && max.value() < 0.0) + return false; + if (min.has_value() && max.has_value() && min.value() > max.value()) + return false; + return true; } + // only used in exactly mode, specify the exactly side length of content. float length = 0.0; MeasureMode mode = MeasureMode::Content; Alignment alignment = Alignment::Center; + + // min and max specify the min/max side length of content. + // they are used as hint and respect the actual size that content needs. + // when mode is exactly, length is coerced into the min-max range. + std::optional min = std::nullopt; + std::optional max = std::nullopt; }; struct BasicLayoutParams final -- cgit v1.2.3 From 6f76a0ad3df99ea0d99623347d019536cc07e920 Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 7 Nov 2018 20:46:57 +0800 Subject: Fix bugs in release mode. --- src/cru_debug.h | 4 ++-- src/main.cpp | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/main.cpp') diff --git a/src/cru_debug.h b/src/cru_debug.h index a9800774..c750e11f 100644 --- a/src/cru_debug.h +++ b/src/cru_debug.h @@ -30,13 +30,13 @@ namespace cru::debug return std::move(result); } #else - inline void DebugTime(Function&& action, const StringView& hint_message) + inline void DebugTime(const std::function& action, const StringView& hint_message) { action(); } template - TReturn DebugTime(Function&& action, const StringView& hint_message) + TReturn DebugTime(const std::function& action, const StringView& hint_message) { return action(); } diff --git a/src/main.cpp b/src/main.cpp index 5fd59ede..f2e65dd2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -101,11 +101,12 @@ int APIENTRY wWinMain( inner_layout->AddChild(TextBlock::Create(L"Toggle debug border")); const auto toggle_button = ToggleButton::Create(); +#ifdef CRU_DEBUG_LAYOUT toggle_button->toggle_event.AddHandler([&window](cru::ui::events::ToggleEventArgs& args) { window.SetDebugLayout(args.GetNewState()); }); - +#endif inner_layout->AddChild(toggle_button); layout->AddChild(inner_layout); } -- cgit v1.2.3