aboutsummaryrefslogtreecommitdiff
path: root/include/cru/ui/render
diff options
context:
space:
mode:
Diffstat (limited to 'include/cru/ui/render')
-rw-r--r--include/cru/ui/render/BorderRenderObject.h24
-rw-r--r--include/cru/ui/render/CanvasRenderObject.h6
-rw-r--r--include/cru/ui/render/FlexLayoutRenderObject.h7
-rw-r--r--include/cru/ui/render/LayoutRenderObject.h95
-rw-r--r--include/cru/ui/render/RenderObject.h128
-rw-r--r--include/cru/ui/render/ScrollRenderObject.h14
-rw-r--r--include/cru/ui/render/StackLayoutRenderObject.h4
-rw-r--r--include/cru/ui/render/TextRenderObject.h8
-rw-r--r--include/cru/ui/render/TreeRenderObject.h13
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;