diff options
author | crupest <crupest@outlook.com> | 2020-06-22 01:09:24 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-06-22 01:09:24 +0800 |
commit | 4f0a2f32c273780c32cc3937615c2a8bbd993aab (patch) | |
tree | 6e1f45447854a40fe2d16ef9bec79f3c0fef030a /include/cru/ui/render | |
parent | d86a71f79afe0e4dac768f61d6bff690567aca5b (diff) | |
download | cru-4f0a2f32c273780c32cc3937615c2a8bbd993aab.tar.gz cru-4f0a2f32c273780c32cc3937615c2a8bbd993aab.tar.bz2 cru-4f0a2f32c273780c32cc3937615c2a8bbd993aab.zip |
...
Diffstat (limited to 'include/cru/ui/render')
-rw-r--r-- | include/cru/ui/render/BorderRenderObject.hpp | 8 | ||||
-rw-r--r-- | include/cru/ui/render/CanvasRenderObject.hpp | 2 | ||||
-rw-r--r-- | include/cru/ui/render/FlexLayoutRenderObject.hpp | 2 | ||||
-rw-r--r-- | include/cru/ui/render/MeasureRequirement.hpp | 79 | ||||
-rw-r--r-- | include/cru/ui/render/RenderObject.hpp | 48 | ||||
-rw-r--r-- | include/cru/ui/render/ScrollRenderObject.hpp | 8 | ||||
-rw-r--r-- | include/cru/ui/render/StackLayoutRenderObject.hpp | 2 | ||||
-rw-r--r-- | include/cru/ui/render/TextRenderObject.hpp | 2 | ||||
-rw-r--r-- | include/cru/ui/render/WindowRenderObject.hpp | 2 |
9 files changed, 130 insertions, 23 deletions
diff --git a/include/cru/ui/render/BorderRenderObject.hpp b/include/cru/ui/render/BorderRenderObject.hpp index c3031f59..45df89f9 100644 --- a/include/cru/ui/render/BorderRenderObject.hpp +++ b/include/cru/ui/render/BorderRenderObject.hpp @@ -67,9 +67,9 @@ class BorderRenderObject : public RenderObject { RenderObject* HitTest(const Point& point) override; protected: - void OnMeasureCore(const Size& available_size) override; - void OnLayoutCore(const Rect& rect) override; - Size OnMeasureContent(const Size& available_size) override; + Size OnMeasureCore(const MeasureRequirement& requirement) override; + void OnLayoutCore(const Size& size) override; + Size OnMeasureContent(const MeasureRequirement& requirement) override; void OnLayoutContent(const Rect& content_rect) override; void OnAfterLayout() override; @@ -85,7 +85,7 @@ class BorderRenderObject : public RenderObject { bool is_border_enabled_ = false; std::shared_ptr<platform::graph::IBrush> border_brush_; - platform::Thickness border_thickness_; + Thickness border_thickness_; CornerRadius border_radius_; std::shared_ptr<platform::graph::IBrush> foreground_brush_; diff --git a/include/cru/ui/render/CanvasRenderObject.hpp b/include/cru/ui/render/CanvasRenderObject.hpp index ba50a985..402302cb 100644 --- a/include/cru/ui/render/CanvasRenderObject.hpp +++ b/include/cru/ui/render/CanvasRenderObject.hpp @@ -28,7 +28,7 @@ class CanvasRenderObject : public RenderObject { IEvent<CanvasPaintEventArgs>* PaintEvent() { return &paint_event_; } protected: - Size OnMeasureContent(const Size& available_size) override; + Size OnMeasureContent(const MeasureRequirement& requirement) override; void OnLayoutContent(const Rect& content_rect) override; private: diff --git a/include/cru/ui/render/FlexLayoutRenderObject.hpp b/include/cru/ui/render/FlexLayoutRenderObject.hpp index bc43141d..217ca6cb 100644 --- a/include/cru/ui/render/FlexLayoutRenderObject.hpp +++ b/include/cru/ui/render/FlexLayoutRenderObject.hpp @@ -31,7 +31,7 @@ class FlexLayoutRenderObject : public LayoutRenderObject<FlexChildLayoutData> { } protected: - Size OnMeasureContent(const Size& available_size) override; + Size OnMeasureContent(const MeasureRequirement& requirement) override; void OnLayoutContent(const Rect& content_rect) override; private: diff --git a/include/cru/ui/render/MeasureRequirement.hpp b/include/cru/ui/render/MeasureRequirement.hpp new file mode 100644 index 00000000..83de255d --- /dev/null +++ b/include/cru/ui/render/MeasureRequirement.hpp @@ -0,0 +1,79 @@ +#pragma once +#include "Base.hpp" + +#include <limits> + +namespace cru::ui::render { +class MeasureLength { + public: + struct tag_infinate_t {}; + constexpr static tag_infinate_t tag_infinate{}; + + constexpr MeasureLength() : MeasureLength(0) {} + constexpr MeasureLength(tag_infinate_t) : length_(-1) {} + constexpr MeasureLength(float length) : length_(length) { + Expects(length >= 0); + } + + MeasureLength(const MeasureLength& other) = default; + MeasureLength& operator=(const MeasureLength& other) = default; + MeasureLength& operator=(float length) { + Expects(length >= 0); + length_ = length; + return *this; + } + + ~MeasureLength() = default; + + constexpr static MeasureLength Infinate() { + return MeasureLength{tag_infinate}; + } + + constexpr bool IsInfinate() const { return length_ < 0; } + constexpr float GetLength() const { + return length_ < 0 ? std::numeric_limits<float>::max() : length_; + } + + constexpr bool operator==(MeasureLength other) const { + return (length_ < 0 && other.length_ < 0) || length_ == other.length_; + } + + constexpr bool operator!=(MeasureLength other) const { + return !operator==(other); + } + + private: + // -1 for infinate + float length_; +}; + +struct MeasureRequirement { + MeasureLength max_width; + MeasureLength max_height; + + constexpr MeasureRequirement() = default; + constexpr MeasureRequirement(MeasureLength max_width, + MeasureLength max_height) + : max_width(max_width), max_height(max_height) {} + + constexpr MeasureRequirement(const Size& max_size) + : max_width(max_size.width), max_height(max_size.height) {} + + constexpr bool Satisfy(const Size& size) const { + if (!max_width.IsInfinate() && max_width.GetLength() < size.width) + return false; + if (!max_height.IsInfinate() && max_height.GetLength() < size.height) + return false; + return true; + } + + constexpr Size GetMaxSize() const { + return Size{max_width.GetLength(), max_height.GetLength()}; + } + + constexpr static MeasureRequirement Infinate() { + return MeasureRequirement{MeasureLength::Infinate(), + MeasureLength::Infinate()}; + } +}; +} // namespace cru::ui::render diff --git a/include/cru/ui/render/RenderObject.hpp b/include/cru/ui/render/RenderObject.hpp index 7cfa3883..9de2cc27 100644 --- a/include/cru/ui/render/RenderObject.hpp +++ b/include/cru/ui/render/RenderObject.hpp @@ -1,12 +1,22 @@ #pragma once #include "Base.hpp" +#include "MeasureRequirement.hpp" #include "cru/common/Event.hpp" namespace cru::ui::render { + // Render object will not destroy its children when destroyed. Control must // manage lifecycle of its render objects. Since control will destroy its // children when destroyed, render objects will be destroyed along with it. +// +// To write a custom RenderObject, override following methods: +// public: +// void Draw(platform::graph::IPainter* painter) override; +// RenderObject* HitTest(const Point& point) override; +// protected: +// Size OnMeasureContent(const MeasureRequirement& requirement) override; +// void OnLayoutContent(const Rect& content_rect) override; class RenderObject : public Object { friend WindowRenderObject; @@ -41,12 +51,12 @@ class RenderObject : public Object { void AddChild(RenderObject* render_object, Index position); void RemoveChild(Index position); + // Offset from parent's lefttop to lefttop of this render object. Margin is + // accounted for. Point GetOffset() const { return offset_; } - void SetOffset(const Point& offset) { offset_ = offset; } + Size GetSize() const { return size_; } Point GetTotalOffset() const; Point FromRootToContent(const Point& point) const; - Size GetSize() const { return size_; } - void SetSize(const Size& size) { size_ = size; } Thickness GetMargin() const { return margin_; } void SetMargin(const Thickness& margin) { margin_ = margin; } @@ -54,16 +64,16 @@ class RenderObject : public Object { Thickness GetPadding() const { return padding_; } void SetPadding(const Thickness& padding) { padding_ = padding; } - Size GetPreferredSize() const { return preferred_size_; } - void SetPreferredSize(const Size& preferred_size) { - preferred_size_ = preferred_size; - } + Size GetMeasuredSize() const { return measured_size_; } - void Measure(const Size& available_size); + void Measure(const MeasureRequirement& requirement); + // Size of rect must not be negative. void Layout(const Rect& rect); virtual void Draw(platform::graph::IPainter* painter) = 0; + // Param point must be relative the lefttop of render object including margin. + // Add offset before pass point to children. virtual RenderObject* HitTest(const Point& point) = 0; public: @@ -82,9 +92,23 @@ class RenderObject : public Object { // default is to invalidate both layout and paint virtual void OnRemoveChild(RenderObject* removed_child, Index position); - virtual void OnMeasureCore(const Size& available_size); - virtual void OnLayoutCore(const Rect& rect); - virtual Size OnMeasureContent(const Size& available_size) = 0; + // Size measure including margin and padding. Please reduce margin and padding + // or other custom things and pass the result content measure requirement to + // OnMeasureContent. + // Return value must not be negative and not bigger than requirement. + virtual Size OnMeasureCore(const MeasureRequirement& requirement); + + // Size including margin and padding. Please reduce margin and padding or + // other custom things and pass the result content rect to OnLayoutContent. + // Parameter size are never negative. + virtual void OnLayoutCore(const Size& size); + + // Do not consider margin or padding in this method because they are already + // considered in OnMeasureCore. Returned size should never be bigger than + // requirement. + virtual Size OnMeasureContent(const MeasureRequirement& requirement) = 0; + + // Lefttop of content_rect should be added when calculated children's offset. virtual void OnLayoutContent(const Rect& content_rect) = 0; virtual void OnAfterLayout(); @@ -113,6 +137,6 @@ class RenderObject : public Object { Thickness margin_{}; Thickness padding_{}; - Size preferred_size_{}; + Size measured_size_{}; }; } // namespace cru::ui::render diff --git a/include/cru/ui/render/ScrollRenderObject.hpp b/include/cru/ui/render/ScrollRenderObject.hpp index dcf6dae6..924b8ca6 100644 --- a/include/cru/ui/render/ScrollRenderObject.hpp +++ b/include/cru/ui/render/ScrollRenderObject.hpp @@ -21,8 +21,12 @@ class ScrollRenderObject : public RenderObject { void SetScrollOffset(const Point& offset); protected: - void OnAddChild(RenderObject* new_child, Index position) override; - void OnRemoveChild(RenderObject* removed_child, Index position) override; + // Logic: + // If available size is bigger than child's preferred size, then child's + // preferred size is taken. + // If not, all available size is taken while forming a scroll area. + Size OnMeasureContent(const MeasureRequirement& requirement) override; + void OnLayoutContent(const Rect& content_rect) override; private: Point scroll_offset_; diff --git a/include/cru/ui/render/StackLayoutRenderObject.hpp b/include/cru/ui/render/StackLayoutRenderObject.hpp index a5bf9335..2320e1ca 100644 --- a/include/cru/ui/render/StackLayoutRenderObject.hpp +++ b/include/cru/ui/render/StackLayoutRenderObject.hpp @@ -11,7 +11,7 @@ class StackLayoutRenderObject ~StackLayoutRenderObject() = default; protected: - Size OnMeasureContent(const Size& available_size) override; + Size OnMeasureContent(const MeasureRequirement& requirement) override; void OnLayoutContent(const Rect& content_rect) override; }; } // namespace cru::ui::render diff --git a/include/cru/ui/render/TextRenderObject.hpp b/include/cru/ui/render/TextRenderObject.hpp index 7a81ba51..96bb5997 100644 --- a/include/cru/ui/render/TextRenderObject.hpp +++ b/include/cru/ui/render/TextRenderObject.hpp @@ -64,7 +64,7 @@ class TextRenderObject : public RenderObject { RenderObject* HitTest(const Point& point) override; protected: - Size OnMeasureContent(const Size& available_size) override; + Size OnMeasureContent(const MeasureRequirement& requirement) override; void OnLayoutContent(const Rect& content_rect) override; void OnAfterLayout() override; diff --git a/include/cru/ui/render/WindowRenderObject.hpp b/include/cru/ui/render/WindowRenderObject.hpp index 00bce29b..d993dc58 100644 --- a/include/cru/ui/render/WindowRenderObject.hpp +++ b/include/cru/ui/render/WindowRenderObject.hpp @@ -16,7 +16,7 @@ class WindowRenderObject : public RenderObject { RenderObject* HitTest(const Point& point) override; protected: - Size OnMeasureContent(const Size& available_size) override; + Size OnMeasureContent(const MeasureRequirement& requirement) override; void OnLayoutContent(const Rect& content_rect) override; private: |