diff options
Diffstat (limited to 'include/cru/ui/render')
-rw-r--r-- | include/cru/ui/render/BorderRenderObject.h | 24 | ||||
-rw-r--r-- | include/cru/ui/render/CanvasRenderObject.h | 6 | ||||
-rw-r--r-- | include/cru/ui/render/FlexLayoutRenderObject.h | 7 | ||||
-rw-r--r-- | include/cru/ui/render/LayoutRenderObject.h | 95 | ||||
-rw-r--r-- | include/cru/ui/render/RenderObject.h | 128 | ||||
-rw-r--r-- | include/cru/ui/render/ScrollRenderObject.h | 14 | ||||
-rw-r--r-- | include/cru/ui/render/StackLayoutRenderObject.h | 4 | ||||
-rw-r--r-- | include/cru/ui/render/TextRenderObject.h | 8 | ||||
-rw-r--r-- | include/cru/ui/render/TreeRenderObject.h | 13 |
9 files changed, 106 insertions, 193 deletions
diff --git a/include/cru/ui/render/BorderRenderObject.h b/include/cru/ui/render/BorderRenderObject.h index d75a979f..1720d680 100644 --- a/include/cru/ui/render/BorderRenderObject.h +++ b/include/cru/ui/render/BorderRenderObject.h @@ -1,9 +1,7 @@ #pragma once -#include <string_view> -#include "../style/ApplyBorderStyleInfo.h" #include "RenderObject.h" -#include "cru/platform/GraphicsBase.h" -#include "cru/ui/Base.h" + +#include "../style/ApplyBorderStyleInfo.h" namespace cru::ui::render { class CRU_UI_API BorderRenderObject : public RenderObject { @@ -11,12 +9,13 @@ class CRU_UI_API BorderRenderObject : public RenderObject { public: BorderRenderObject(); - BorderRenderObject(const BorderRenderObject& other) = delete; - BorderRenderObject(BorderRenderObject&& other) = delete; - BorderRenderObject& operator=(const BorderRenderObject& other) = delete; - BorderRenderObject& operator=(BorderRenderObject&& other) = delete; + CRU_DELETE_COPY(BorderRenderObject) + CRU_DELETE_MOVE(BorderRenderObject) ~BorderRenderObject() override; + RenderObject* GetChild() const { return child_; } + void SetChild(RenderObject* new_child); + bool IsBorderEnabled() const { return is_border_enabled_; } void SetBorderEnabled(bool enabled) { is_border_enabled_ = enabled; } @@ -69,26 +68,27 @@ class CRU_UI_API BorderRenderObject : public RenderObject { void ApplyBorderStyle(const style::ApplyBorderStyleInfo& style); RenderObject* HitTest(const Point& point) override; + void Draw(platform::graphics::IPainter* painter) override; Thickness GetOuterSpaceThickness() const override; Rect GetPaddingRect() const override; Rect GetContentRect() const override; - std::u16string_view GetName() const override { return u"BorderRenderObject"; } + String GetName() const override { return u"BorderRenderObject"; } protected: - void OnDrawCore(platform::graphics::IPainter* painter) override; - Size OnMeasureContent(const MeasureRequirement& requirement, const MeasureSize& preferred_size) override; void OnLayoutContent(const Rect& content_rect) override; - void OnAfterLayout() override; + void OnResize(const Size& new_size) override; private: void RecreateGeometry(); private: + RenderObject* child_ = nullptr; + bool is_border_enabled_ = false; std::shared_ptr<platform::graphics::IBrush> border_brush_; diff --git a/include/cru/ui/render/CanvasRenderObject.h b/include/cru/ui/render/CanvasRenderObject.h index ca55ebc6..8343a5f5 100644 --- a/include/cru/ui/render/CanvasRenderObject.h +++ b/include/cru/ui/render/CanvasRenderObject.h @@ -1,6 +1,8 @@ #pragma once #include "RenderObject.h" +#include "cru/common/Event.h" + namespace cru::ui::render { // Layout logic: // If no preferred size is set. Then (100, 100) is used and then coerced to @@ -21,9 +23,9 @@ class CRU_UI_API CanvasRenderObject : public RenderObject { IEvent<CanvasPaintEventArgs>* PaintEvent() { return &paint_event_; } - protected: - void OnDrawContent(platform::graphics::IPainter* painter) override; + void Draw(platform::graphics::IPainter* painter) override; + protected: Size OnMeasureContent(const MeasureRequirement& requirement, const MeasureSize& preferred_size) override; void OnLayoutContent(const Rect& content_rect) override; diff --git a/include/cru/ui/render/FlexLayoutRenderObject.h b/include/cru/ui/render/FlexLayoutRenderObject.h index 3a8348f6..164bae39 100644 --- a/include/cru/ui/render/FlexLayoutRenderObject.h +++ b/include/cru/ui/render/FlexLayoutRenderObject.h @@ -1,8 +1,6 @@ #pragma once #include "LayoutRenderObject.h" -#include <string_view> - namespace cru::ui::render { // Measure Logic (v0.1): // Cross axis measure logic is the same as stack layout. @@ -75,7 +73,8 @@ namespace cru::ui::render { // (if specified), then coerce the length to the min value but not report error // and just fill the rest space with blank. // -class CRU_UI_API FlexLayoutRenderObject : public LayoutRenderObject<FlexChildLayoutData> { +class CRU_UI_API FlexLayoutRenderObject + : public LayoutRenderObject<FlexChildLayoutData> { CRU_DEFINE_CLASS_LOG_TAG(u"cru::ui::render::FlexLayoutRenderObject") public: @@ -87,7 +86,7 @@ class CRU_UI_API FlexLayoutRenderObject : public LayoutRenderObject<FlexChildLay FlexLayoutRenderObject& operator=(FlexLayoutRenderObject&& other) = delete; ~FlexLayoutRenderObject() override = default; - std::u16string_view GetName() const override; + String GetName() const override; FlexDirection GetFlexDirection() const { return direction_; } void SetFlexDirection(FlexDirection direction) { diff --git a/include/cru/ui/render/LayoutRenderObject.h b/include/cru/ui/render/LayoutRenderObject.h index 42a3aa55..05da1bb8 100644 --- a/include/cru/ui/render/LayoutRenderObject.h +++ b/include/cru/ui/render/LayoutRenderObject.h @@ -9,8 +9,14 @@ class CRU_UI_API LayoutRenderObject : public RenderObject { public: using ChildLayoutData = TChildLayoutData; + private: + struct ChildData { + RenderObject* child; + ChildLayoutData layout_data; + }; + protected: - LayoutRenderObject() : RenderObject(ChildMode::Multiple) {} + LayoutRenderObject() = default; public: CRU_DELETE_COPY(LayoutRenderObject) @@ -18,69 +24,50 @@ class CRU_UI_API LayoutRenderObject : public RenderObject { ~LayoutRenderObject() override = default; - const std::vector<ChildLayoutData>& GetChildLayoutDataList() const { - return this->child_layout_data_; + Index GetChildCount() const { return static_cast<Index>(children_.size()); } + RenderObject* GetChildAt(Index position) { + Expects(position > 0 && position < GetChildCount()); + return children_[position].render_object; + } + void AddChild(RenderObject* render_object, Index position) { + if (position < 0) position = 0; + if (position > GetChildCount()) position = GetChildCount(); + children_.insert(children_.begin() + position, + ChildData{render_object, ChildLayoutData()}); + render_object->SetParent(this); + } + + void RemoveChild(Index position) { + Expects(position > 0 && position < GetChildCount()); + children_[position].render_object->SetParent(nullptr); + children_.erase(children_.begin() + position); } void SetChildLayoutData(Index position, ChildLayoutData data) { - Expects(position >= 0 && - position < static_cast<Index>(this->child_layout_data_.size())); - this->child_layout_data_[position] = std::move(data); - this->InvalidateLayout(); + Expects(position >= 0 && position < GetChildCount()); + children_[position].layout_data = std::move(data); + InvalidateLayout(); } const ChildLayoutData& GetChildLayoutData(Index position) const { - Expects(position >= 0 && - position < static_cast<Index>(this->child_layout_data_.size())); - return this->child_layout_data_[position]; + Expects(position >= 0 && position < GetChildCount()); + return children_[position].layout_data; } - RenderObject* HitTest(const Point& point) override; + RenderObject* HitTest(const Point& point) override { + const auto child_count = GetChildCount(); + for (auto i = child_count - 1; i >= 0; --i) { + const auto child = GetChildAt(i); + const auto result = child->HitTest(point - child->GetOffset()); + if (result != nullptr) { + return result; + } + } - protected: - void OnAddChild(RenderObject* new_child, Index position) override; - void OnRemoveChild(RenderObject* removed_child, Index position) override; + return GetPaddingRect().IsPointInside(point) ? this : nullptr; + } private: - std::vector<ChildLayoutData> child_layout_data_{}; + std::vector<ChildData> children_; }; - -template <typename TChildLayoutData> -RenderObject* LayoutRenderObject<TChildLayoutData>::HitTest( - const Point& point) { - const auto& children = GetChildren(); - for (auto i = children.crbegin(); i != children.crend(); ++i) { - auto offset = (*i)->GetOffset(); - Point p{point.x - offset.x, point.y - offset.y}; - const auto result = (*i)->HitTest(p); - if (result != nullptr) { - return result; - } - } - - const auto margin = GetMargin(); - const auto size = GetSize(); - return Rect{margin.left, margin.top, - std::max(size.width - margin.GetHorizontalTotal(), 0.0f), - std::max(size.height - margin.GetVerticalTotal(), 0.0f)} - .IsPointInside(point) - ? this - : nullptr; -} // namespace cru::ui::render - -template <typename TChildLayoutData> -void LayoutRenderObject<TChildLayoutData>::OnAddChild(RenderObject* new_child, - const Index position) { - CRU_UNUSED(new_child) - - child_layout_data_.emplace(child_layout_data_.cbegin() + position); -} - -template <typename TChildLayoutData> -void LayoutRenderObject<TChildLayoutData>::OnRemoveChild( - RenderObject* removed_child, const Index position) { - CRU_UNUSED(removed_child) - - child_layout_data_.erase(child_layout_data_.cbegin() + position); -} } // namespace cru::ui::render diff --git a/include/cru/ui/render/RenderObject.h b/include/cru/ui/render/RenderObject.h index a4ac0f4b..67ef6162 100644 --- a/include/cru/ui/render/RenderObject.h +++ b/include/cru/ui/render/RenderObject.h @@ -3,13 +3,9 @@ #include "MeasureRequirement.h" #include "cru/common/Base.h" -#include "cru/common/Event.h" +#include "cru/common/String.h" #include "cru/ui/Base.h" -#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 @@ -40,80 +36,46 @@ namespace cru::ui::render { // 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; + CRU_DELETE_COPY(RenderObject) + CRU_DELETE_MOVE(RenderObject) ~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); + void SetParent(RenderObject* new_parent) { parent_ = new_parent; } // 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; + Size GetDesiredSize() const { return desired_size_; } + Thickness GetMargin() const { return margin_; } - void SetMargin(const Thickness& margin) { - margin_ = margin; - InvalidateLayout(); - } + void SetMargin(const Thickness& margin); Thickness GetPadding() const { return padding_; } - void SetPadding(const Thickness& padding) { - padding_ = padding; - InvalidateLayout(); - } + void SetPadding(const Thickness& padding); MeasureSize GetPreferredSize() const { return preferred_size_; } - void SetPreferredSize(const MeasureSize& preferred_size) { - preferred_size_ = preferred_size; - InvalidateLayout(); - } + void SetPreferredSize(const MeasureSize& preferred_size); MeasureSize GetMinSize() const { return custom_measure_requirement_.min; } - void SetMinSize(const MeasureSize& min_size) { - custom_measure_requirement_.min = min_size; - InvalidateLayout(); - } + void SetMinSize(const MeasureSize& min_size); MeasureSize GetMaxSize() const { return custom_measure_requirement_.max; } - void SetMaxSize(const MeasureSize& max_size) { - custom_measure_requirement_.max = max_size; - InvalidateLayout(); - } + void SetMaxSize(const MeasureSize& max_size); MeasureRequirement GetCustomMeasureRequirement() const { return custom_measure_requirement_; @@ -135,56 +97,22 @@ class CRU_UI_API RenderObject : public Object { virtual Rect GetPaddingRect() const; virtual Rect GetContentRect() const; - void Draw(platform::graphics::IPainter* painter); + virtual void Draw(platform::graphics::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; - IEvent<host::WindowHost*>* AttachToHostEvent() { - return &attach_to_host_event_; - } - IEvent<std::nullptr_t>* DetachFromHostEvent() { - return &detach_from_host_event_; - } - public: + host::WindowHost* GetWindowHost(); void InvalidateLayout(); void InvalidatePaint(); public: - virtual std::u16string_view GetName() const; - std::u16string GetDebugPathInTree() const; - - protected: - void SetChildMode(ChildMode mode) { child_mode_ = mode; } + virtual String GetName() const; + String GetDebugPathInTree() const; 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); - - /** - * \brief Draw all children with offset. - */ - void DefaultDrawChildren(platform::graphics::IPainter* painter); - - /** - * \brief Call OnDrawContent 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 @@ -209,36 +137,24 @@ class CRU_UI_API RenderObject : public Object { // 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); + virtual void OnAttachedControlChanged(controls::Control* old_control, + controls::Control* new_control) {} + virtual void OnResize(const Size& new_size) {} 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_; + Size desired_size_{}; Thickness margin_{}; Thickness padding_{}; - Event<host::WindowHost*> attach_to_host_event_; - Event<std::nullptr_t> detach_from_host_event_; + MeasureSize preferred_size_{}; + MeasureRequirement custom_measure_requirement_{}; }; } // namespace cru::ui::render diff --git a/include/cru/ui/render/ScrollRenderObject.h b/include/cru/ui/render/ScrollRenderObject.h index bb282953..0890ec21 100644 --- a/include/cru/ui/render/ScrollRenderObject.h +++ b/include/cru/ui/render/ScrollRenderObject.h @@ -27,6 +27,9 @@ class CRU_UI_API ScrollRenderObject : public RenderObject { ~ScrollRenderObject() override = default; + RenderObject* GetChild() const { return child_; } + void SetChild(RenderObject* new_child); + RenderObject* HitTest(const Point& point) override; // Return the coerced scroll offset. @@ -61,7 +64,7 @@ class CRU_UI_API 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"; } + String GetName() const override { return u"ScrollRenderObject"; } bool IsMouseWheelScrollEnabled() const { return is_mouse_wheel_enabled_; } void SetMouseWheelScrollEnabled(bool enable); @@ -71,9 +74,9 @@ class CRU_UI_API ScrollRenderObject : public RenderObject { bool VerticalCanScrollUp(); bool VerticalCanScrollDown(); - protected: - void OnDrawCore(platform::graphics::IPainter* painter) override; + void Draw(platform::graphics::IPainter* painter) override; + protected: // Logic: // If available size is bigger than child's preferred size, then child's // preferred size is taken. @@ -82,11 +85,14 @@ class CRU_UI_API ScrollRenderObject : public RenderObject { const MeasureSize& preferred_size) override; void OnLayoutContent(const Rect& content_rect) override; - void OnAttachedControlChanged(controls::Control* control) override; + void OnAttachedControlChanged(controls::Control* old_control, + controls::Control* new_control) override; void InstallMouseWheelHandler(controls::Control* control); private: + RenderObject* child_; + Point scroll_offset_; std::unique_ptr<ScrollBarDelegate> scroll_bar_delegate_; diff --git a/include/cru/ui/render/StackLayoutRenderObject.h b/include/cru/ui/render/StackLayoutRenderObject.h index e141d16e..68b5b30c 100644 --- a/include/cru/ui/render/StackLayoutRenderObject.h +++ b/include/cru/ui/render/StackLayoutRenderObject.h @@ -32,9 +32,7 @@ class CRU_UI_API StackLayoutRenderObject CRU_DELETE_MOVE(StackLayoutRenderObject) ~StackLayoutRenderObject() = default; - std::u16string_view GetName() const override { - return u"StackLayoutRenderObject"; - } + String GetName() const override { return u"StackLayoutRenderObject"; } Alignment GetDefaultHorizontalAlignment() const { return default_vertical_alignment_; diff --git a/include/cru/ui/render/TextRenderObject.h b/include/cru/ui/render/TextRenderObject.h index 3b5f581a..f3a7332f 100644 --- a/include/cru/ui/render/TextRenderObject.h +++ b/include/cru/ui/render/TextRenderObject.h @@ -91,17 +91,17 @@ class CRU_UI_API TextRenderObject : public RenderObject { RenderObject* HitTest(const Point& point) override; - std::u16string_view GetName() const override { return u"TextRenderObject"; } + String GetName() const override { return u"TextRenderObject"; } - protected: - void OnDrawContent(platform::graphics::IPainter* painter) override; + void Draw(platform::graphics::IPainter* painter) override; + protected: // See remarks of this class. Size OnMeasureContent(const MeasureRequirement& requirement, const MeasureSize& preferred_size) override; void OnLayoutContent(const Rect& content_rect) override; - void OnAfterLayout() override; + void OnResize(const Size& size) override; private: std::shared_ptr<platform::graphics::IBrush> brush_; diff --git a/include/cru/ui/render/TreeRenderObject.h b/include/cru/ui/render/TreeRenderObject.h index 77ec0cff..4a176926 100644 --- a/include/cru/ui/render/TreeRenderObject.h +++ b/include/cru/ui/render/TreeRenderObject.h @@ -26,7 +26,7 @@ class CRU_UI_API TreeRenderObjectItem : public Object { Index GetChildCount() const { return children_.size(); } - TreeRenderObjectItem* GetChild(Index index) { + TreeRenderObjectItem* GetChildAt(Index index) { Expects(index >= 0 && index < children_.size()); return children_[index]; } @@ -34,6 +34,9 @@ class CRU_UI_API TreeRenderObjectItem : public Object { TreeRenderObjectItem* AddItem(Index position); void RemoveItem(Index position); + void* GetUserData() const { return user_data_; } + void SetUserData(void* user_data) { user_data_ = user_data; } + private: TreeRenderObject* tree_render_object_; @@ -41,6 +44,8 @@ class CRU_UI_API TreeRenderObjectItem : public Object { std::vector<TreeRenderObjectItem*> children_; RenderObject* render_object_; + + void* user_data_; }; class CRU_UI_API TreeRenderObject : public RenderObject { @@ -52,7 +57,7 @@ class CRU_UI_API TreeRenderObject : public RenderObject { CRU_DELETE_MOVE(TreeRenderObject) ~TreeRenderObject() override; - std::u16string_view GetName() const override { return u"TreeRenderObject"; } + String GetName() const override { return u"TreeRenderObject"; } TreeRenderObjectItem* GetRootItem() { return root_item_; } @@ -61,9 +66,9 @@ class CRU_UI_API TreeRenderObject : public RenderObject { RenderObject* HitTest(const Point& point) override; - protected: - void OnDrawCore(platform::graphics::IPainter* painter) override; + void Draw(platform::graphics::IPainter* painter) override; + protected: Size OnMeasureContent(const MeasureRequirement& requirement, const MeasureSize& preferred_size) override; void OnLayoutContent(const Rect& content_rect) override; |