aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-03-17 15:04:16 +0800
committercrupest <crupest@outlook.com>2021-03-17 15:04:16 +0800
commitaf2e38b320905bf3b1e5d0969d0811c47289bbfe (patch)
tree18a55d5cf3fc5bea4ab342476dc5a57574808839
parent7703063a5816b089483e78ccd74bb9902ccfbea8 (diff)
downloadcru-af2e38b320905bf3b1e5d0969d0811c47289bbfe.tar.gz
cru-af2e38b320905bf3b1e5d0969d0811c47289bbfe.tar.bz2
cru-af2e38b320905bf3b1e5d0969d0811c47289bbfe.zip
...
-rw-r--r--include/cru/platform/GraphBase.hpp5
-rw-r--r--include/cru/ui/render/BorderRenderObject.hpp16
-rw-r--r--include/cru/ui/render/RenderObject.hpp2
-rw-r--r--include/cru/ui/render/ScrollRenderObject.hpp2
-rw-r--r--include/cru/ui/render/StackLayoutRenderObject.hpp4
-rw-r--r--include/cru/ui/render/TextRenderObject.hpp2
-rw-r--r--src/ui/render/BorderRenderObject.cpp105
-rw-r--r--src/ui/render/FlexLayoutRenderObject.cpp41
-rw-r--r--src/ui/render/LayoutHelper.cpp18
-rw-r--r--src/ui/render/RenderObject.cpp62
-rw-r--r--src/ui/render/StackLayoutRenderObject.cpp26
-rw-r--r--src/ui/render/TextRenderObject.cpp27
12 files changed, 73 insertions, 237 deletions
diff --git a/include/cru/platform/GraphBase.hpp b/include/cru/platform/GraphBase.hpp
index 6bf2736f..4d3c8f83 100644
--- a/include/cru/platform/GraphBase.hpp
+++ b/include/cru/platform/GraphBase.hpp
@@ -129,6 +129,11 @@ constexpr Size operator+(const Thickness& thickness, const Size& size) {
return operator+(size, thickness);
}
+constexpr Thickness operator+(const Thickness& left, const Thickness& right) {
+ return {left.left + right.left, left.top + right.top,
+ left.right + right.right, left.bottom + right.bottom};
+}
+
constexpr bool operator==(const Thickness& left, const Thickness& right) {
return left.left == right.left && left.top == right.top &&
left.right == right.right && left.bottom == right.bottom;
diff --git a/include/cru/ui/render/BorderRenderObject.hpp b/include/cru/ui/render/BorderRenderObject.hpp
index 3d4f4dad..34ad71d6 100644
--- a/include/cru/ui/render/BorderRenderObject.hpp
+++ b/include/cru/ui/render/BorderRenderObject.hpp
@@ -1,6 +1,8 @@
#pragma once
+#include <string_view>
#include "../style/ApplyBorderStyleInfo.hpp"
#include "RenderObject.hpp"
+#include "cru/platform/GraphBase.hpp"
#include "cru/ui/Base.hpp"
namespace cru::ui::render {
@@ -28,7 +30,7 @@ class BorderRenderObject : public RenderObject {
InvalidatePaint();
}
- Thickness GetBorderThickness() { return border_thickness_; }
+ Thickness GetBorderThickness() const { return border_thickness_; }
void SetBorderThickness(const Thickness thickness) {
if (thickness == border_thickness_) return;
@@ -68,21 +70,21 @@ class BorderRenderObject : public RenderObject {
RenderObject* HitTest(const Point& point) override;
+ Thickness GetOuterSpaceThickness() const override;
+ Rect GetPaddingRect() const override;
+ Rect GetContentRect() const override;
+
+ std::u16string_view GetName() const override { return u"BorderRenderObject"; }
+
protected:
void OnDrawCore(platform::graphics::IPainter* painter) override;
- Size OnMeasureCore(const MeasureRequirement& requirement,
- const MeasureSize& preferred_size) override;
- void OnLayoutCore() override;
Size OnMeasureContent(const MeasureRequirement& requirement,
const MeasureSize& preferred_size) override;
void OnLayoutContent(const Rect& content_rect) override;
void OnAfterLayout() override;
- Rect GetPaddingRect() const override;
- Rect GetContentRect() const override;
-
private:
void RecreateGeometry();
diff --git a/include/cru/ui/render/RenderObject.hpp b/include/cru/ui/render/RenderObject.hpp
index 8bcd4c62..622c27f2 100644
--- a/include/cru/ui/render/RenderObject.hpp
+++ b/include/cru/ui/render/RenderObject.hpp
@@ -4,6 +4,7 @@
#include "MeasureRequirement.hpp"
#include "cru/common/Base.hpp"
#include "cru/common/Event.hpp"
+#include "cru/platform/GraphBase.hpp"
#include "cru/ui/Base.hpp"
#include <cstddef>
@@ -131,6 +132,7 @@ class RenderObject : public Object {
// This will set offset of this render object and call OnLayoutCore.
void Layout(const Point& offset);
+ virtual Thickness GetOuterSpaceThickness() const;
virtual Rect GetPaddingRect() const;
virtual Rect GetContentRect() const;
diff --git a/include/cru/ui/render/ScrollRenderObject.hpp b/include/cru/ui/render/ScrollRenderObject.hpp
index aed25f8e..7b98ab72 100644
--- a/include/cru/ui/render/ScrollRenderObject.hpp
+++ b/include/cru/ui/render/ScrollRenderObject.hpp
@@ -60,6 +60,8 @@ class ScrollRenderObject : public RenderObject {
// Param margin is just for convenience and it will just add to the rect.
void ScrollToContain(const Rect& rect, const Thickness& margin = Thickness{});
+ std::u16string_view GetName() const override { return u"ScrollRenderObject"; }
+
protected:
void OnDrawCore(platform::graphics::IPainter* painter) override;
diff --git a/include/cru/ui/render/StackLayoutRenderObject.hpp b/include/cru/ui/render/StackLayoutRenderObject.hpp
index 303241c5..4f15ad11 100644
--- a/include/cru/ui/render/StackLayoutRenderObject.hpp
+++ b/include/cru/ui/render/StackLayoutRenderObject.hpp
@@ -31,6 +31,10 @@ class StackLayoutRenderObject
CRU_DELETE_MOVE(StackLayoutRenderObject)
~StackLayoutRenderObject() = default;
+ std::u16string_view GetName() const override {
+ return u"StackLayoutRenderObject";
+ }
+
protected:
Size OnMeasureContent(const MeasureRequirement& requirement,
const MeasureSize& preferred_size) override;
diff --git a/include/cru/ui/render/TextRenderObject.hpp b/include/cru/ui/render/TextRenderObject.hpp
index bdec18d1..cf585d6f 100644
--- a/include/cru/ui/render/TextRenderObject.hpp
+++ b/include/cru/ui/render/TextRenderObject.hpp
@@ -89,6 +89,8 @@ class TextRenderObject : public RenderObject {
RenderObject* HitTest(const Point& point) override;
+ std::u16string_view GetName() const override { return u"TextRenderObject"; }
+
protected:
void OnDrawContent(platform::graphics::IPainter* painter) override;
diff --git a/src/ui/render/BorderRenderObject.cpp b/src/ui/render/BorderRenderObject.cpp
index e2c40f0c..6b2404db 100644
--- a/src/ui/render/BorderRenderObject.cpp
+++ b/src/ui/render/BorderRenderObject.cpp
@@ -5,6 +5,7 @@
#include "cru/platform/graphics/Factory.hpp"
#include "cru/platform/graphics/Geometry.hpp"
#include "cru/platform/graphics/util/Painter.hpp"
+#include "cru/ui/Base.hpp"
#include "cru/ui/style/ApplyBorderStyleInfo.hpp"
#include "gsl/gsl_assert"
@@ -75,104 +76,6 @@ void BorderRenderObject::OnDrawCore(platform::graphics::IPainter* painter) {
DefaultDrawChildren(painter);
}
-Size BorderRenderObject::OnMeasureCore(const MeasureRequirement& requirement,
- const MeasureSize& preferred_size) {
- if (!is_border_enabled_) {
- return RenderObject::OnMeasureCore(requirement, preferred_size);
- }
-
- const auto margin = GetMargin();
- const auto padding = GetPadding();
- const Size space_size{margin.GetHorizontalTotal() +
- padding.GetHorizontalTotal() +
- border_thickness_.GetHorizontalTotal(),
- margin.GetVerticalTotal() + padding.GetVerticalTotal() +
- border_thickness_.GetVerticalTotal()};
-
- auto coerced_space_size = space_size;
-
- MeasureRequirement content_requirement = requirement;
-
- if (!requirement.max.width.IsNotSpecified()) {
- const auto max_width = requirement.max.width.GetLengthOrMax();
- if (coerced_space_size.width > max_width) {
- log::TagWarn(log_tag,
- u"(Measure) Horizontal length of padding, border and margin "
- u"is bigger than required max length.");
- coerced_space_size.width = max_width;
- }
- content_requirement.max.width = max_width - coerced_space_size.width;
- }
-
- if (!requirement.min.width.IsNotSpecified()) {
- const auto min_width = requirement.min.width.GetLengthOr0();
- content_requirement.min.width = std::max(0.f, min_width - space_size.width);
- }
-
- if (!requirement.max.height.IsNotSpecified()) {
- const auto max_height = requirement.max.height.GetLengthOrMax();
- if (coerced_space_size.height > max_height) {
- log::TagWarn(
- log_tag,
- u"(Measure) Vertical length of padding, border and margin is "
- u"bigger than required max length.");
- coerced_space_size.height = max_height;
- }
- content_requirement.max.height = max_height - coerced_space_size.height;
- }
-
- if (!requirement.min.height.IsNotSpecified()) {
- const auto min_height = requirement.min.height.GetLengthOr0();
- content_requirement.min.height =
- std::max(0.f, min_height - space_size.height);
- }
-
- MeasureSize content_preferred_size =
- content_requirement.Coerce(preferred_size.Minus(space_size));
-
- const auto content_size =
- OnMeasureContent(content_requirement, content_preferred_size);
-
- return coerced_space_size + content_size;
-}
-
-void BorderRenderObject::OnLayoutCore() {
- if (!is_border_enabled_) {
- return RenderObject::OnLayoutCore();
- }
-
- const auto margin = GetMargin();
- const auto padding = GetPadding();
- Size space_size{margin.GetHorizontalTotal() + padding.GetHorizontalTotal() +
- border_thickness_.GetHorizontalTotal(),
- margin.GetVerticalTotal() + padding.GetVerticalTotal() +
- border_thickness_.GetVerticalTotal()};
-
- const auto size = GetSize();
-
- auto content_size = size - space_size;
-
- if (content_size.width < 0) {
- content_size.width = 0;
- }
- if (content_size.height < 0) {
- content_size.height = 0;
- }
-
- Point lefttop{margin.left + padding.left + border_thickness_.left,
- margin.top + padding.top + border_thickness_.top};
- if (lefttop.x > size.width) {
- lefttop.x = size.width;
- }
- if (lefttop.y > size.height) {
- lefttop.y = size.height;
- }
-
- const Rect content_rect{lefttop, content_size};
-
- OnLayoutContent(content_rect);
-}
-
Size BorderRenderObject::OnMeasureContent(const MeasureRequirement& requirement,
const MeasureSize& preferred_size) {
const auto child = GetSingleChild();
@@ -193,6 +96,12 @@ void BorderRenderObject::OnLayoutContent(const Rect& content_rect) {
void BorderRenderObject::OnAfterLayout() { RecreateGeometry(); }
+Thickness BorderRenderObject::GetOuterSpaceThickness() const {
+ return is_border_enabled_
+ ? RenderObject::GetOuterSpaceThickness() + GetBorderThickness()
+ : RenderObject::GetOuterSpaceThickness();
+}
+
Rect BorderRenderObject::GetPaddingRect() const {
const auto size = GetSize();
Rect rect{Point{}, size};
diff --git a/src/ui/render/FlexLayoutRenderObject.cpp b/src/ui/render/FlexLayoutRenderObject.cpp
index b1ef69ee..e4b3774f 100644
--- a/src/ui/render/FlexLayoutRenderObject.cpp
+++ b/src/ui/render/FlexLayoutRenderObject.cpp
@@ -107,25 +107,12 @@ Size FlexLayoutMeasureContentImpl(
MeasureLength min_main_length = GetMain(requirement.min, direction_tag);
MeasureLength min_cross_length = GetCross(requirement.min, direction_tag);
- std::vector<MeasureLength> child_cross_measure_requirement;
- child_cross_measure_requirement.reserve(children.size());
-
- for (auto child : children) {
- child_cross_measure_requirement.push_back(
- StackLayoutCalculateChildMaxLength(
- preferred_cross_length, max_cross_length,
- GetCross(child->GetMinSize(), direction_tag), log_tag,
- u"(Measure) Child's min cross size is bigger than parent's max "
- u"cross size."));
- }
-
// step 1.
for (Index i = 0; i < child_count; i++) {
const auto child = children[i];
child->Measure(MeasureRequirement{CreateTSize<MeasureSize>(
MeasureLength::NotSpecified(),
- child_cross_measure_requirement[i],
- direction_tag),
+ max_cross_length, direction_tag),
MeasureSize::NotSpecified()},
MeasureSize::NotSpecified());
}
@@ -213,21 +200,17 @@ Size FlexLayoutMeasureContentImpl(
new_measure_length = 0.f;
}
- child->Measure(
- MeasureRequirement{
- CreateTSize<MeasureSize>(new_measure_length,
- child_cross_measure_requirement[i],
- direction_tag),
- MeasureSize::NotSpecified()},
- CreateTSize<MeasureSize>(new_measure_length,
- MeasureLength::NotSpecified(),
- direction_tag));
+ child->Measure(MeasureRequirement{CreateTSize<MeasureSize>(
+ new_measure_length,
+ max_cross_length, direction_tag),
+ MeasureSize::NotSpecified()},
+ CreateTSize<MeasureSize>(new_measure_length,
+ MeasureLength::NotSpecified(),
+ direction_tag));
const Size new_size = child->GetSize();
const float new_main_length = GetMain(new_size, direction_tag);
- if (new_main_length == 0.f ||
- (child_min_main_length.IsSpecified() &&
- new_main_length == child_min_main_length.GetLengthOrUndefined())) {
+ if (new_main_length > new_measure_length) {
to_remove.push_back(i);
}
}
@@ -278,8 +261,7 @@ Size FlexLayoutMeasureContentImpl(
child->Measure(
MeasureRequirement{
CreateTSize<MeasureSize>(MeasureLength::NotSpecified(),
- child_cross_measure_requirement[i],
- direction_tag),
+ max_cross_length, direction_tag),
CreateTSize<MeasureSize>(new_measure_length,
MeasureLength::NotSpecified(),
direction_tag)},
@@ -289,8 +271,7 @@ Size FlexLayoutMeasureContentImpl(
const Size new_size = child->GetSize();
const float new_main_length = GetMain(new_size, direction_tag);
- if (child_max_main_length.IsSpecified() &&
- new_main_length == child_max_main_length.GetLengthOrUndefined()) {
+ if (new_main_length < new_measure_length) {
to_remove.push_back(i);
}
}
diff --git a/src/ui/render/LayoutHelper.cpp b/src/ui/render/LayoutHelper.cpp
index 9ad2d862..5854a945 100644
--- a/src/ui/render/LayoutHelper.cpp
+++ b/src/ui/render/LayoutHelper.cpp
@@ -16,22 +16,4 @@ float CalculateAnchorByAlignment(Alignment alignment, float start_point,
return start_point;
}
}
-
-MeasureLength StackLayoutCalculateChildMaxLength(
- MeasureLength parent_preferred_size, MeasureLength parent_max_size,
- MeasureLength child_min_size, std::u16string_view log_tag,
- std::u16string_view exceeds_message) {
- if (parent_max_size.GetLengthOrMax() < child_min_size.GetLengthOr0()) {
- log::TagWarn(log_tag, exceeds_message);
- return parent_max_size;
- }
-
- if (parent_preferred_size.IsSpecified() &&
- parent_preferred_size.GetLengthOrUndefined() >=
- child_min_size.GetLengthOr0()) {
- return parent_preferred_size;
- } else {
- return parent_max_size;
- }
-}
} // namespace cru::ui::render
diff --git a/src/ui/render/RenderObject.cpp b/src/ui/render/RenderObject.cpp
index 7cf750cd..e49ed3c2 100644
--- a/src/ui/render/RenderObject.cpp
+++ b/src/ui/render/RenderObject.cpp
@@ -1,7 +1,9 @@
#include "cru/ui/render/RenderObject.hpp"
#include "cru/common/Logger.hpp"
+#include "cru/platform/GraphBase.hpp"
#include "cru/platform/graphics/util/Painter.hpp"
+#include "cru/ui/Base.hpp"
#include "cru/ui/DebugFlags.hpp"
#include "cru/ui/host/WindowHost.hpp"
@@ -105,18 +107,21 @@ void RenderObject::Measure(const MeasureRequirement& requirement,
Ensures(size_.width >= 0);
Ensures(size_.height >= 0);
- Ensures(requirement.Satisfy(size_));
}
void RenderObject::Layout(const Point& offset) {
if constexpr (cru::ui::debug_flags::layout) {
- log::Debug(u"{} Layout :\noffset: {}", this->GetDebugPathInTree(),
- offset.ToDebugString());
+ log::Debug(u"{} Layout :\noffset: {} size: {}", this->GetDebugPathInTree(),
+ offset.ToDebugString(), GetSize().ToDebugString());
}
offset_ = offset;
OnLayoutCore();
}
+Thickness RenderObject::GetOuterSpaceThickness() const {
+ return margin_ + padding_;
+}
+
void RenderObject::Draw(platform::graphics::IPainter* painter) {
OnDrawCore(painter);
}
@@ -180,46 +185,14 @@ void RenderObject::OnDrawContent(platform::graphics::IPainter* painter) {
Size RenderObject::OnMeasureCore(const MeasureRequirement& requirement,
const MeasureSize& preferred_size) {
- const Size space_size{
- margin_.GetHorizontalTotal() + padding_.GetHorizontalTotal(),
- margin_.GetVerticalTotal() + padding_.GetVerticalTotal()};
-
- auto coerced_space_size = space_size;
+ const Thickness outer_space = GetOuterSpaceThickness();
+ const Size space_size{outer_space.GetHorizontalTotal(),
+ outer_space.GetVerticalTotal()};
MeasureRequirement content_requirement = requirement;
- if (!requirement.max.width.IsNotSpecified()) {
- const auto max_width = requirement.max.width.GetLengthOrMax();
- if (coerced_space_size.width > max_width) {
- log::TagWarn(log_tag,
- u"(Measure) Horizontal length of padding and margin is "
- u"bigger than required max length.");
- coerced_space_size.width = max_width;
- }
- content_requirement.max.width = max_width - coerced_space_size.width;
- }
-
- if (!requirement.min.width.IsNotSpecified()) {
- const auto min_width = requirement.min.width.GetLengthOr0();
- content_requirement.min.width = std::max(0.f, min_width - space_size.width);
- }
-
- if (!requirement.max.height.IsNotSpecified()) {
- const auto max_height = requirement.max.height.GetLengthOrMax();
- if (coerced_space_size.height > max_height) {
- log::TagWarn(log_tag,
- u"(Measure) Vertical length of padding and margin is bigger "
- u"than required max length.");
- coerced_space_size.height = max_height;
- }
- content_requirement.max.height = max_height - coerced_space_size.height;
- }
-
- if (!requirement.min.height.IsNotSpecified()) {
- const auto min_height = requirement.min.height.GetLengthOr0();
- content_requirement.min.height =
- std::max(0.f, min_height - space_size.height);
- }
+ content_requirement.max = content_requirement.max.Minus(space_size);
+ content_requirement.min = content_requirement.min.Minus(space_size);
MeasureSize content_preferred_size =
content_requirement.Coerce(preferred_size.Minus(space_size));
@@ -227,13 +200,14 @@ Size RenderObject::OnMeasureCore(const MeasureRequirement& requirement,
const auto content_size =
OnMeasureContent(content_requirement, content_preferred_size);
- return coerced_space_size + content_size;
+ return space_size + content_size;
}
void RenderObject::OnLayoutCore() {
Size total_size = GetSize();
- Size space_size{margin_.GetHorizontalTotal() + padding_.GetHorizontalTotal(),
- margin_.GetVerticalTotal() + padding_.GetVerticalTotal()};
+ const Thickness outer_space = GetOuterSpaceThickness();
+ const Size space_size{outer_space.GetHorizontalTotal(),
+ outer_space.GetVerticalTotal()};
auto content_size = total_size - space_size;
@@ -244,7 +218,7 @@ void RenderObject::OnLayoutCore() {
content_size.height = 0;
}
- Point lefttop{margin_.left + padding_.left, margin_.top + padding_.top};
+ Point lefttop{outer_space.left, outer_space.top};
if (lefttop.x > total_size.width) {
lefttop.x = total_size.width;
}
diff --git a/src/ui/render/StackLayoutRenderObject.cpp b/src/ui/render/StackLayoutRenderObject.cpp
index 75ab0ee3..753612af 100644
--- a/src/ui/render/StackLayoutRenderObject.cpp
+++ b/src/ui/render/StackLayoutRenderObject.cpp
@@ -2,37 +2,27 @@
#include "cru/common/Logger.hpp"
#include "cru/ui/render/LayoutHelper.hpp"
+#include "cru/ui/render/MeasureRequirement.hpp"
#include <algorithm>
namespace cru::ui::render {
Size StackLayoutRenderObject::OnMeasureContent(
const MeasureRequirement& requirement, const MeasureSize& preferred_size) {
- Size max_size;
+ Size child_max_size;
for (const auto child : GetChildren()) {
child->Measure(
- MeasureRequirement{
- MeasureSize{StackLayoutCalculateChildMaxLength(
- preferred_size.width, requirement.max.width,
- child->GetMinSize().width, log_tag,
- u"(Measure) Child's min width is bigger than "
- u"parent's max width."),
- StackLayoutCalculateChildMaxLength(
- preferred_size.height, requirement.max.height,
- child->GetMinSize().height, log_tag,
- u"(Measure) Child's min height is bigger than "
- u"parent's max height.")},
- MeasureSize::NotSpecified()},
+ MeasureRequirement(requirement.max, MeasureSize::NotSpecified()),
MeasureSize::NotSpecified());
const auto size = child->GetSize();
- max_size.width = std::max(max_size.width, size.width);
- max_size.height = std::max(max_size.height, size.height);
+ child_max_size.width = std::max(child_max_size.width, size.width);
+ child_max_size.height = std::max(child_max_size.height, size.height);
}
- max_size = Max(preferred_size.GetSizeOr0(), max_size);
- max_size = Max(requirement.min.GetSizeOr0(), max_size);
+ child_max_size = Max(preferred_size.GetSizeOr0(), child_max_size);
+ child_max_size = Max(requirement.min.GetSizeOr0(), child_max_size);
- return max_size;
+ return child_max_size;
}
void StackLayoutRenderObject::OnLayoutContent(const Rect& content_rect) {
diff --git a/src/ui/render/TextRenderObject.cpp b/src/ui/render/TextRenderObject.cpp
index 06092d52..a5dcf053 100644
--- a/src/ui/render/TextRenderObject.cpp
+++ b/src/ui/render/TextRenderObject.cpp
@@ -197,29 +197,12 @@ Size TextRenderObject::OnMeasureContent(const MeasureRequirement& requirement,
.GetSize();
auto result = text_size;
- if (requirement.max.width.IsSpecified() &&
- text_size.width > requirement.max.width.GetLengthOrUndefined()) {
- log::TagWarn(
- log_tag,
- u"(Measure) Text actual width exceeds the required max width.");
- result.width = requirement.max.width.GetLengthOrUndefined();
- } else {
- result.width = std::max(result.width, preferred_size.width.GetLengthOr0());
- result.width = std::max(result.width, requirement.min.width.GetLengthOr0());
- }
+ result.width = std::max(result.width, preferred_size.width.GetLengthOr0());
+ result.width = std::max(result.width, requirement.min.width.GetLengthOr0());
- if (requirement.max.height.IsSpecified() &&
- text_size.height > requirement.max.height.GetLengthOrUndefined()) {
- log::TagWarn(
- log_tag,
- u"(Measure) Text actual height exceeds the required max height.");
- result.height = requirement.max.height.GetLengthOrUndefined();
- } else {
- result.height =
- std::max(result.height, preferred_size.height.GetLengthOr0());
- result.height =
- std::max(result.height, requirement.min.height.GetLengthOr0());
- }
+ result.height = std::max(result.height, preferred_size.height.GetLengthOr0());
+ result.height =
+ std::max(result.height, requirement.min.height.GetLengthOr0());
return result;
}