aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2020-07-04 16:43:49 +0800
committercrupest <crupest@outlook.com>2020-07-04 16:43:49 +0800
commite10ef322e5f6268aec5d7717a82fceb42607a000 (patch)
treecb635f26fb9caa86d0486ca91a146bff77fad44d
parent5a1c45f69b858f8c578806df54d276d5084d032b (diff)
downloadcru-e10ef322e5f6268aec5d7717a82fceb42607a000.tar.gz
cru-e10ef322e5f6268aec5d7717a82fceb42607a000.tar.bz2
cru-e10ef322e5f6268aec5d7717a82fceb42607a000.zip
...
-rw-r--r--include/cru/ui/render/ScrollRenderObject.hpp8
-rw-r--r--src/ui/render/ScrollRenderObject.cpp48
2 files changed, 34 insertions, 22 deletions
diff --git a/include/cru/ui/render/ScrollRenderObject.hpp b/include/cru/ui/render/ScrollRenderObject.hpp
index 43e6d7f9..0c1fb16b 100644
--- a/include/cru/ui/render/ScrollRenderObject.hpp
+++ b/include/cru/ui/render/ScrollRenderObject.hpp
@@ -4,6 +4,14 @@
#include "cru/platform/graph/util/Painter.hpp"
namespace cru::ui::render {
+// Measure logic:
+// Measure child with unspecified min and max size.
+// If parent's preferred size is specified, then it is used as measure result.
+// Or child's size is coerced into requirement and then used as result.
+// If no child, then use the preferred size if set or min size if set or 0.
+// Layout logic:
+// If child is smaller than content area, layout at lefttop.
+// Or layout by scroll state.
class ScrollRenderObject : public RenderObject {
public:
ScrollRenderObject() : RenderObject(ChildMode::Single) {}
diff --git a/src/ui/render/ScrollRenderObject.cpp b/src/ui/render/ScrollRenderObject.cpp
index aab8c003..a367afd9 100644
--- a/src/ui/render/ScrollRenderObject.cpp
+++ b/src/ui/render/ScrollRenderObject.cpp
@@ -69,30 +69,34 @@ void ScrollRenderObject::SetScrollOffset(const Point& offset) {
Size ScrollRenderObject::OnMeasureContent(const MeasureRequirement& requirement,
const MeasureSize& preferred_size) {
- // TODO: Rewrite this.
- CRU_UNUSED(requirement);
- CRU_UNUSED(preferred_size);
- throw std::runtime_error("Not implemented.");
-
- // if (const auto child = GetSingleChild()) {
- // child->Measure(MeasureRequirement::Infinate());
- // const auto preferred_size = child->GetMeasuredSize();
- // return Min(preferred_size, requirement.GetMaxSize());
- // } else {
- // return Size{};
- // }
+ if (const auto child = GetSingleChild()) {
+ child->Measure(MeasureRequirement{MeasureSize::NotSpecified(),
+ MeasureSize::NotSpecified()},
+ MeasureSize::NotSpecified());
+
+ Size result = requirement.Coerce(child->GetSize());
+ if (preferred_size.width.IsSpecified()) {
+ result.width = preferred_size.width.GetLengthOrUndefined();
+ }
+ if (preferred_size.height.IsSpecified()) {
+ result.height = preferred_size.height.GetLengthOrUndefined();
+ }
+ return result;
+ } else {
+ Size result{preferred_size.width.IsSpecified()
+ ? preferred_size.width.GetLengthOrUndefined()
+ : requirement.min.width.GetLengthOr0(),
+ preferred_size.height.IsSpecified()
+ ? preferred_size.height.GetLengthOrUndefined()
+ : requirement.min.height.GetLengthOr0()};
+ return result;
+ }
} // namespace cru::ui::render
void ScrollRenderObject::OnLayoutContent(const Rect& content_rect) {
- // TODO: Rewrite this.
- CRU_UNUSED(content_rect);
- throw std::runtime_error("Not implemented.");
-
- // if (const auto child = GetSingleChild()) {
- // const auto child_size = child->GetMeasuredSize();
- // const auto true_scroll =
- // CoerceScroll(scroll_offset_, content_rect.GetSize(), child_size);
- // child->Layout(Rect{content_rect.GetLeftTop() - true_scroll, child_size});
- // }
+ if (const auto child = GetSingleChild()) {
+ const auto child_size = child->GetSize();
+ child->Layout(content_rect.GetLeftTop() - GetScrollOffset());
+ }
}
} // namespace cru::ui::render