diff options
author | crupest <crupest@outlook.com> | 2022-02-08 16:53:51 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-02-08 16:53:51 +0800 |
commit | 74bb9cd27242b9320f99ff4d2b50c3051576cc14 (patch) | |
tree | 744bac5799c593d1d6f81e7b09581bea626f2cde /include/cru/ui/render/RenderObject.hpp | |
parent | b90c398de829d1ba5329651d75bae82f5e4085fe (diff) | |
download | cru-74bb9cd27242b9320f99ff4d2b50c3051576cc14.tar.gz cru-74bb9cd27242b9320f99ff4d2b50c3051576cc14.tar.bz2 cru-74bb9cd27242b9320f99ff4d2b50c3051576cc14.zip |
...
Diffstat (limited to 'include/cru/ui/render/RenderObject.hpp')
-rw-r--r-- | include/cru/ui/render/RenderObject.hpp | 240 |
1 files changed, 0 insertions, 240 deletions
diff --git a/include/cru/ui/render/RenderObject.hpp b/include/cru/ui/render/RenderObject.hpp deleted file mode 100644 index bac97640..00000000 --- a/include/cru/ui/render/RenderObject.hpp +++ /dev/null @@ -1,240 +0,0 @@ -#pragma once -#include "Base.hpp" - -#include "MeasureRequirement.hpp" -#include "cru/common/Base.hpp" -#include "cru/common/Event.hpp" -#include "cru/ui/Base.hpp" - -#include <cstddef> -#include <string> -#include <string_view> - -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. -// -// About layout: -// Render object should be able to deal with arbitrary size as the result of -// measure and layout. -// -// Parent may pass calculated preferred size down. But the preferred size set on -// child itself takes precedence. -// -// Each render object should obey the measure requirement to set size and report -// a warning when that requirement can't be satisfied with probably bigger size -// of children than that of itself and optional visual effect to indicate that. -// -// If size of chilren are less than min size requirement, then render object -// should try to fill the rest area. If size of children are more than max size -// requirement, then render object should display a warning of the layout -// problem and use the max size of itself with children exceeding its bound. -// (Or better you could use some visual effect to indicate that.) -// -// To write a custom RenderObject, override following methods: -// public: -// void Draw(platform::graphics::IPainter* painter) override; -// RenderObject* HitTest(const Point& point) override; -// protected: -// Size OnMeasureContent(const MeasureRequirement& requirement) override; -// void OnLayoutContent(const Rect& content_rect) override; -class CRU_UI_API RenderObject : public Object { - friend host::WindowHost; - - CRU_DEFINE_CLASS_LOG_TAG(u"cru::ui::render::RenderObject") - - protected: - enum class ChildMode { - None, - Single, - Multiple, - }; - - RenderObject() = default; - RenderObject(ChildMode child_mode) : RenderObject() { - SetChildMode(child_mode); - } - - public: - RenderObject(const RenderObject& other) = delete; - RenderObject(RenderObject&& other) = delete; - RenderObject& operator=(const RenderObject& other) = delete; - RenderObject& operator=(RenderObject&& other) = delete; - ~RenderObject() override = default; - - controls::Control* GetAttachedControl() const { return control_; } - void SetAttachedControl(controls::Control* new_control); - - host::WindowHost* GetWindowHost() const { return window_host_; } - - RenderObject* GetParent() const { return parent_; } - - const std::vector<RenderObject*>& GetChildren() const { return children_; } - Index GetChildCount() const { return static_cast<Index>(children_.size()); } - void AddChild(RenderObject* render_object, Index position); - void RemoveChild(Index position); - - RenderObject* GetFirstChild() const; - void TraverseDescendants(const std::function<void(RenderObject*)>& action); - - // Offset from parent's lefttop to lefttop of this render object. Margin is - // accounted for. - Point GetOffset() const { return offset_; } - Size GetSize() const { return size_; } - Point GetTotalOffset() const; - Point FromRootToContent(const Point& point) const; - - Thickness GetMargin() const { return margin_; } - void SetMargin(const Thickness& margin) { - margin_ = margin; - InvalidateLayout(); - } - - Thickness GetPadding() const { return padding_; } - void SetPadding(const Thickness& padding) { - padding_ = padding; - InvalidateLayout(); - } - - MeasureSize GetPreferredSize() const { return preferred_size_; } - void SetPreferredSize(const MeasureSize& preferred_size) { - preferred_size_ = preferred_size; - InvalidateLayout(); - } - - MeasureSize GetMinSize() const { return custom_measure_requirement_.min; } - void SetMinSize(const MeasureSize& min_size) { - custom_measure_requirement_.min = min_size; - InvalidateLayout(); - } - - MeasureSize GetMaxSize() const { return custom_measure_requirement_.max; } - void SetMaxSize(const MeasureSize& max_size) { - custom_measure_requirement_.max = max_size; - InvalidateLayout(); - } - - MeasureRequirement GetCustomMeasureRequirement() const { - return custom_measure_requirement_; - } - - // This method will merge requirement passed by argument and requirement of - // the render object using MeasureRequirement::Merge and then call - // MeasureRequirement::Normalize on it. And it will use preferred size of the - // render object to override the one passed by argument. Then pass the two to - // OnMeasureCore and use the return value of it to set the size of this render - // object. This can be called multiple times on children during measure to - // adjust for better size. - void Measure(const MeasureRequirement& requirement, - const MeasureSize& preferred_size); - // 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; - - void Draw(platform::graphics::IPainter* painter); - - // 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; - - IEvent<host::WindowHost*>* AttachToHostEvent() { - return &attach_to_host_event_; - } - IEvent<std::nullptr_t>* DetachFromHostEvent() { - return &detach_from_host_event_; - } - - public: - void InvalidateLayout(); - void InvalidatePaint(); - - public: - virtual std::u16string_view GetName() const; - std::u16string GetDebugPathInTree() const; - - protected: - void SetChildMode(ChildMode mode) { child_mode_ = mode; } - - protected: - RenderObject* GetSingleChild() const; - - virtual void OnParentChanged(RenderObject* old_parent, - RenderObject* new_parent); - - // default is to invalidate both layout and paint - virtual void OnAddChild(RenderObject* new_child, Index position); - // default is to invalidate both layout and paint - virtual void OnRemoveChild(RenderObject* removed_child, Index position); - - // Draw all children with offset. - void DefaultDrawChildren(platform::graphics::IPainter* painter); - - // Draw all children with translation of content rect lefttop. - void DefaultDrawContent(platform::graphics::IPainter* painter); - - // Call DefaultDrawContent. Then call DefaultDrawChildren. - virtual void OnDrawCore(platform::graphics::IPainter* painter); - - virtual void OnDrawContent(platform::graphics::IPainter* painter); - - // Size measure including margin and padding. Please reduce margin and padding - // or other custom things and pass the result content measure requirement and - // preferred size to OnMeasureContent. Return value must not be negative and - // must obey requirement. - // Note: Implementation should coerce the preferred size into the requirement - // when pass them to OnMeasureContent. - virtual Size OnMeasureCore(const MeasureRequirement& requirement, - const MeasureSize& preferred_size); - - // Please reduce margin and padding or other custom things and pass the result - // content rect to OnLayoutContent. - virtual void OnLayoutCore(); - - // Override this function to measure content and children(Call Measure on - // them). Do not consider margin or padding in this method because they are - // already considered in OnMeasureCore. Returned size must obey requirement. - // Caller should guarantee preferred_size is corerced into required range. - virtual Size OnMeasureContent(const MeasureRequirement& requirement, - const MeasureSize& preferred_size) = 0; - - // Layout all content and children(Call Layout on them). - // Lefttop of content_rect should be added when calculated children's offset. - virtual void OnLayoutContent(const Rect& content_rect) = 0; - - virtual void OnAttachedControlChanged(controls::Control* control) { - CRU_UNUSED(control) - } - - virtual void OnAfterLayout(); - - private: - void SetParent(RenderObject* new_parent); - - void SetWindowHostRecursive(host::WindowHost* host); - - private: - controls::Control* control_ = nullptr; - host::WindowHost* window_host_ = nullptr; - - RenderObject* parent_ = nullptr; - std::vector<RenderObject*> children_{}; - - ChildMode child_mode_ = ChildMode::None; - - Point offset_{}; - Size size_{}; - - MeasureSize preferred_size_; - MeasureRequirement custom_measure_requirement_; - - Thickness margin_{}; - Thickness padding_{}; - - Event<host::WindowHost*> attach_to_host_event_; - Event<std::nullptr_t> detach_from_host_event_; -}; -} // namespace cru::ui::render |