aboutsummaryrefslogtreecommitdiff
path: root/src/ui/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/render')
-rw-r--r--src/ui/render/linear_layout_render_object.cpp0
-rw-r--r--src/ui/render/linear_layout_render_object.hpp1
-rw-r--r--src/ui/render/render_object.cpp176
-rw-r--r--src/ui/render/render_object.hpp302
4 files changed, 162 insertions, 317 deletions
diff --git a/src/ui/render/linear_layout_render_object.cpp b/src/ui/render/linear_layout_render_object.cpp
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/ui/render/linear_layout_render_object.cpp
diff --git a/src/ui/render/linear_layout_render_object.hpp b/src/ui/render/linear_layout_render_object.hpp
new file mode 100644
index 00000000..6f70f09b
--- /dev/null
+++ b/src/ui/render/linear_layout_render_object.hpp
@@ -0,0 +1 @@
+#pragma once
diff --git a/src/ui/render/render_object.cpp b/src/ui/render/render_object.cpp
index 0828fc9c..c2aaeb62 100644
--- a/src/ui/render/render_object.cpp
+++ b/src/ui/render/render_object.cpp
@@ -3,96 +3,88 @@
namespace cru::ui::render
{
- void RenderObject::SetRenderHost(IRenderHost* new_render_host)
- {
- if (new_render_host == render_host_)
- return;
-
- const auto old = render_host_;
- render_host_ = new_render_host;
- OnRenderHostChanged(old, new_render_host);
- }
-
- void RenderObject::OnRenderHostChanged(IRenderHost* old_render_host, IRenderHost* new_render_host)
- {
-
- }
-
- void RenderObject::InvalidateRenderHost()
- {
- if (render_host_ != nullptr)
- render_host_->InvalidateRender();
- }
-
- void StrokeRenderObject::SetStrokeWidth(const float new_stroke_width)
- {
- if (stroke_width_ == new_stroke_width)
- return;
-
- stroke_width_ = new_stroke_width;
- InvalidateRenderHost();
- }
-
- void StrokeRenderObject::SetBrush(Microsoft::WRL::ComPtr<ID2D1Brush> new_brush)
- {
- if (brush_ == new_brush)
- return;
-
- brush_ = std::move(new_brush);
- InvalidateRenderHost();
- }
-
- void StrokeRenderObject::SetStrokeStyle(Microsoft::WRL::ComPtr<ID2D1StrokeStyle> new_stroke_style)
- {
- if (stroke_style_ == new_stroke_style)
- return;
-
- stroke_style_ = std::move(new_stroke_style);
- InvalidateRenderHost();
- }
-
- void FillRenderObject::SetBrush(Microsoft::WRL::ComPtr<ID2D1Brush> new_brush)
- {
- if (brush_ == new_brush)
- return;
-
- brush_ = std::move(new_brush);
- InvalidateRenderHost();
- }
-
- namespace details
- {
- template class ShapeRenderObject<Rect>;
- template class ShapeRenderObject<RoundedRect>;
- template class ShapeRenderObject<Ellipse>;
- }
-
- namespace details
- {
- template ShapeStrokeRenderObject<Rect, D2D1_RECT_F, &ID2D1RenderTarget::DrawRectangle>;
- template ShapeStrokeRenderObject<RoundedRect, D2D1_ROUNDED_RECT, &ID2D1RenderTarget::DrawRoundedRectangle>;
- template ShapeStrokeRenderObject<Ellipse, D2D1_ELLIPSE, &ID2D1RenderTarget::DrawEllipse>;
- }
-
- namespace details
- {
- template ShapeFillRenderObject<Rect, D2D1_RECT_F, &ID2D1RenderTarget::FillRectangle>;
- template ShapeFillRenderObject<RoundedRect, D2D1_ROUNDED_RECT, &ID2D1RenderTarget::FillRoundedRectangle>;
- template ShapeFillRenderObject<Ellipse, D2D1_ELLIPSE, &ID2D1RenderTarget::FillEllipse>;
- }
-
- void CustomDrawHandlerRenderObject::SetDrawHandler(DrawHandler new_draw_handler)
- {
- if (draw_handler_ == nullptr && new_draw_handler == nullptr)
- return;
-
- draw_handler_ = std::move(new_draw_handler);
- InvalidateRenderHost();
- }
-
- void CustomDrawHandlerRenderObject::Draw(ID2D1RenderTarget* render_target)
- {
- if (draw_handler_ != nullptr)
- draw_handler_(render_target);
- }
+void RenderObject::SetRenderHost(IRenderHost* new_render_host)
+{
+ if (new_render_host == render_host_) return;
+
+ const auto old = render_host_;
+ render_host_ = new_render_host;
+ OnRenderHostChanged(old, new_render_host);
+}
+
+void RenderObject::AddChild(RenderObject* render_object, const int position)
+{
+ if (render_object->GetParent() != nullptr)
+ throw std::invalid_argument("Render object already has a parent.");
+
+ if (position < 0)
+ throw std::invalid_argument("Position index is less than 0.");
+
+ if (static_cast<std::vector<RenderObject*>::size_type>(position) >
+ children_.size())
+ throw std::invalid_argument("Position index is out of bound.");
+
+ children_.insert(children_.cbegin() + position, render_object);
+ render_object->SetParent(this);
+ OnAddChild(render_object, position);
+}
+
+void RenderObject::RemoveChild(const int position)
+{
+ if (position < 0)
+ throw std::invalid_argument("Position index is less than 0.");
+
+ if (static_cast<std::vector<RenderObject*>::size_type>(position) >=
+ children_.size())
+ throw std::invalid_argument("Position index is out of bound.");
+
+ const auto i = children_.cbegin() + position;
+ const auto removed_child = *i;
+ children_.erase(i);
+ removed_child->SetParent(nullptr);
+ OnRemoveChild(removed_child, position);
+}
+
+
+void RenderObject::OnRenderHostChanged(IRenderHost* old_render_host,
+ IRenderHost* new_render_host)
+{
+}
+
+void RenderObject::InvalidateRenderHostPaint() const
+{
+ if (render_host_ != nullptr) render_host_->InvalidatePaint();
+}
+
+void RenderObject::InvalidateRenderHostLayout() const
+{
+ if (render_host_ != nullptr) render_host_->InvalidateLayout();
+}
+
+void RenderObject::OnParentChanged(RenderObject* old_parent,
+ RenderObject* new_parent)
+{
+}
+
+
+void RenderObject::OnAddChild(RenderObject* new_child, int position)
+{
+}
+
+void RenderObject::OnRemoveChild(RenderObject* removed_child, int position)
+{
+}
+
+void RenderObject::SetParent(RenderObject* new_parent)
+{
+ const auto old_parent = parent_;
+ parent_ = new_parent;
+ OnParentChanged(old_parent, new_parent);
+}
+
+
+void LinearLayoutRenderObject::Measure(const MeasureConstraint& constraint)
+{
+
}
+} // namespace cru::ui::render
diff --git a/src/ui/render/render_object.hpp b/src/ui/render/render_object.hpp
index 31745be5..00f761d1 100644
--- a/src/ui/render/render_object.hpp
+++ b/src/ui/render/render_object.hpp
@@ -2,256 +2,108 @@
#include "pre.hpp"
+#include <optional>
+#include <vector>
#include "system_headers.hpp"
-#include <functional>
-#include <cassert>
#include "base.hpp"
#include "ui/ui_base.hpp"
-#include "ui/d2d_util.hpp"
namespace cru::ui::render
{
- /* About Render Object
- *
- * Render object is a concrete subclass of RenderObject class.
- * It represents a painting action on a d2d render target. By
- * overriding "Draw" virtual method, it can customize its painting
- * action.
- */
-
-
- struct IRenderHost : Interface
- {
- virtual void InvalidateRender() = 0;
- };
-
-
- class RenderObject : public Object
- {
- protected:
- RenderObject() = default;
- public:
- RenderObject(const RenderObject& other) = delete;
- RenderObject(RenderObject&& other) = delete;
- RenderObject& operator=(const RenderObject& other) = delete;
- RenderObject& operator=(RenderObject&& other) = delete;
- ~RenderObject() override = default;
-
- virtual void Draw(ID2D1RenderTarget* render_target) = 0;
-
- IRenderHost* GetRenderHost() const
- {
- return render_host_;
- }
-
- void SetRenderHost(IRenderHost* new_render_host);
-
- protected:
- virtual void OnRenderHostChanged(IRenderHost* old_render_host, IRenderHost* new_render_host);
-
- void InvalidateRenderHost();
-
- private:
- IRenderHost* render_host_ = nullptr;
- };
-
-
- class StrokeRenderObject : public virtual RenderObject
- {
- protected:
- StrokeRenderObject() = default;
- public:
- StrokeRenderObject(const StrokeRenderObject& other) = delete;
- StrokeRenderObject(StrokeRenderObject&& other) = delete;
- StrokeRenderObject& operator=(const StrokeRenderObject& other) = delete;
- StrokeRenderObject& operator=(StrokeRenderObject&& other) = delete;
- ~StrokeRenderObject() override = default;
-
- float GetStrokeWidth() const
- {
- return stroke_width_;
- }
-
- void SetStrokeWidth(float new_stroke_width);
-
- Microsoft::WRL::ComPtr<ID2D1Brush> GetBrush() const
- {
- return brush_;
- }
-
- void SetBrush(Microsoft::WRL::ComPtr<ID2D1Brush> new_brush);
-
- Microsoft::WRL::ComPtr<ID2D1StrokeStyle> GetStrokeStyle() const
- {
- return stroke_style_;
- }
-
- void SetStrokeStyle(Microsoft::WRL::ComPtr<ID2D1StrokeStyle> new_stroke_style);
-
- private:
- float stroke_width_ = 1.0f;
- Microsoft::WRL::ComPtr<ID2D1Brush> brush_ = nullptr;
- Microsoft::WRL::ComPtr<ID2D1StrokeStyle> stroke_style_ = nullptr;
- };
-
-
- class FillRenderObject : public virtual RenderObject
- {
- protected:
- FillRenderObject() = default;
- public:
- FillRenderObject(const FillRenderObject& other) = delete;
- FillRenderObject(FillRenderObject&& other) = delete;
- FillRenderObject& operator=(const FillRenderObject& other) = delete;
- FillRenderObject& operator=(FillRenderObject&& other) = delete;
- ~FillRenderObject() override = default;
-
- Microsoft::WRL::ComPtr<ID2D1Brush> GetBrush() const
- {
- return brush_;
- }
-
- void SetBrush(Microsoft::WRL::ComPtr<ID2D1Brush> new_brush);
-
- private:
- Microsoft::WRL::ComPtr<ID2D1Brush> brush_ = nullptr;
- };
-
-
- namespace details
- {
- template <typename TShapeType>
- class ShapeRenderObject : public virtual RenderObject
- {
- public:
- using ShapeType = TShapeType;
- protected:
- ShapeRenderObject() = default;
- public:
- ShapeRenderObject(const ShapeRenderObject& other) = delete;
- ShapeRenderObject& operator=(const ShapeRenderObject& other) = delete;
- ShapeRenderObject(ShapeRenderObject&& other) = delete;
- ShapeRenderObject& operator=(ShapeRenderObject&& other) = delete;
- ~ShapeRenderObject() override = default;
-
- ShapeType GetShape() const
- {
- return shape_;
- }
-
- void SetShape(const ShapeType& new_shape)
- {
- if (new_shape == shape_)
- return;
-
- shape_ = new_shape;
- InvalidateRenderHost();
- }
-
- private:
- ShapeType shape_;
- };
+struct MeasureConstraint
+{
+ std::optional<float> min_width;
+ std::optional<float> min_height;
+ std::optional<float> max_width;
+ std::optional<float> max_height;
+};
- extern template class ShapeRenderObject<Rect>;
- extern template class ShapeRenderObject<RoundedRect>;
- extern template class ShapeRenderObject<Ellipse>;
- }
+struct LayoutConstraint
+{
+ float preferred_width;
+ float preferred_height;
+};
- using RectangleRenderObject = details::ShapeRenderObject<Rect>;
- using RoundedRectangleRenderObject = details::ShapeRenderObject<RoundedRect>;
- using EllipseRenderObject = details::ShapeRenderObject<Ellipse>;
+struct IRenderHost : Interface
+{
+ virtual void InvalidatePaint() = 0;
+ virtual void InvalidateLayout() = 0;
+};
- namespace details
- {
- template<typename TShapeType, typename TD2D1ShapeType, void (ID2D1RenderTarget::*draw_function)(const TD2D1ShapeType&, ID2D1Brush*, float, ID2D1StrokeStyle*)>
- class ShapeStrokeRenderObject : public ShapeRenderObject<TShapeType>, public StrokeRenderObject
- {
- public:
- ShapeStrokeRenderObject() = default;
- ShapeStrokeRenderObject(const ShapeStrokeRenderObject& other) = delete;
- ShapeStrokeRenderObject& operator=(const ShapeStrokeRenderObject& other) = delete;
- ShapeStrokeRenderObject(ShapeStrokeRenderObject&& other) = delete;
- ShapeStrokeRenderObject& operator=(ShapeStrokeRenderObject&& other) = delete;
- ~ShapeStrokeRenderObject() = default;
+// features:
+// 1. tree
+// 2. layout
+// 3. paint
+// 3. hit test
+class RenderObject : public Object
+{
+protected:
+ RenderObject() = default;
- protected:
- void Draw(ID2D1RenderTarget* render_target) override
- {
- const auto brush = GetBrush();
- if (brush != nullptr)
- (render_target->*draw_function)(Convert(GetShape()), brush.Get(), GetStrokeWidth(), GetStrokeStyle().Get());
- }
- };
+public:
+ RenderObject(const RenderObject& other) = delete;
+ RenderObject(RenderObject&& other) = delete;
+ RenderObject& operator=(const RenderObject& other) = delete;
+ RenderObject& operator=(RenderObject&& other) = delete;
+ ~RenderObject() override = default;
- extern template ShapeStrokeRenderObject<Rect, D2D1_RECT_F, &ID2D1RenderTarget::DrawRectangle>;
- extern template ShapeStrokeRenderObject<RoundedRect, D2D1_ROUNDED_RECT, &ID2D1RenderTarget::DrawRoundedRectangle>;
- extern template ShapeStrokeRenderObject<Ellipse, D2D1_ELLIPSE, &ID2D1RenderTarget::DrawEllipse>;
- }
+ IRenderHost* GetRenderHost() const { return render_host_; }
+ void SetRenderHost(IRenderHost* new_render_host);
- using RectangleStrokeRenderObject = details::ShapeStrokeRenderObject<Rect, D2D1_RECT_F, &ID2D1RenderTarget::DrawRectangle>;
- using RoundedRectangleStrokeRenderObject = details::ShapeStrokeRenderObject<RoundedRect, D2D1_ROUNDED_RECT, &ID2D1RenderTarget::DrawRoundedRectangle>;
- using EllipseStrokeRenderObject = details::ShapeStrokeRenderObject<Ellipse, D2D1_ELLIPSE, &ID2D1RenderTarget::DrawEllipse>;
+ RenderObject* GetParent() const { return parent_; }
+ const std::vector<RenderObject*>& GetChildren() const { return children_; }
+ void AddChild(RenderObject* render_object, int position);
+ void RemoveChild(int position);
- namespace details
- {
- template<typename TShapeType, typename TD2D1ShapeType, void (ID2D1RenderTarget::*fill_function)(const TD2D1ShapeType&, ID2D1Brush*)>
- class ShapeFillRenderObject : public ShapeRenderObject<TShapeType>, public StrokeRenderObject
- {
- public:
- ShapeFillRenderObject() = default;
- ShapeFillRenderObject(const ShapeFillRenderObject& other) = delete;
- ShapeFillRenderObject& operator=(const ShapeFillRenderObject& other) = delete;
- ShapeFillRenderObject(ShapeFillRenderObject&& other) = delete;
- ShapeFillRenderObject& operator=(ShapeFillRenderObject&& other) = delete;
- ~ShapeFillRenderObject() = default;
+ virtual void Measure(const MeasureConstraint& constraint) = 0;
+ virtual void Layout(const LayoutConstraint& constraint) = 0;
- protected:
- void Draw(ID2D1RenderTarget* render_target) override
- {
- const auto brush = GetBrush();
- if (brush != nullptr)
- (render_target->*fill_function)(Convert(GetShape()), brush.Get());
- }
- };
+ virtual void Draw(ID2D1RenderTarget* render_target) = 0;
- extern template ShapeFillRenderObject<Rect, D2D1_RECT_F, &ID2D1RenderTarget::FillRectangle>;
- extern template ShapeFillRenderObject<RoundedRect, D2D1_ROUNDED_RECT, &ID2D1RenderTarget::FillRoundedRectangle>;
- extern template ShapeFillRenderObject<Ellipse, D2D1_ELLIPSE, &ID2D1RenderTarget::FillEllipse>;
- }
+ virtual void HitTest(const Point& point) = 0;
- using RectangleFillRenderObject = details::ShapeFillRenderObject<Rect, D2D1_RECT_F, &ID2D1RenderTarget::FillRectangle>;
- using RoundedRectangleFillRenderObject = details::ShapeFillRenderObject<RoundedRect, D2D1_ROUNDED_RECT, &ID2D1RenderTarget::FillRoundedRectangle>;
- using EllipseFillRenderObject = details::ShapeFillRenderObject<Ellipse, D2D1_ELLIPSE, &ID2D1RenderTarget::FillEllipse>;
+protected:
+ virtual void OnRenderHostChanged(IRenderHost* old_render_host,
+ IRenderHost* new_render_host);
+ void InvalidateRenderHostPaint() const;
+ void InvalidateRenderHostLayout() const;
- class CustomDrawHandlerRenderObject : public RenderObject
- {
- public:
- using DrawHandler = std::function<void(ID2D1RenderTarget*)>;
+ virtual void OnParentChanged(RenderObject* old_parent,
+ RenderObject* new_parent);
- CustomDrawHandlerRenderObject() = default;
- CustomDrawHandlerRenderObject(const CustomDrawHandlerRenderObject& other) = delete;
- CustomDrawHandlerRenderObject& operator=(const CustomDrawHandlerRenderObject& other) = delete;
- CustomDrawHandlerRenderObject(CustomDrawHandlerRenderObject&& other) = delete;
- CustomDrawHandlerRenderObject& operator=(CustomDrawHandlerRenderObject&& other) = delete;
- ~CustomDrawHandlerRenderObject() override = default;
+ virtual void OnAddChild(RenderObject* new_child, int position);
+ virtual void OnRemoveChild(RenderObject* removed_child, int position);
- DrawHandler GetDrawHandler() const
- {
- return draw_handler_;
- }
+private:
+ void SetParent(RenderObject* new_parent);
- void SetDrawHandler(DrawHandler new_draw_handler);
+private:
+ IRenderHost* render_host_ = nullptr;
+ RenderObject* parent_ = nullptr;
+ std::vector<RenderObject*> children_;
+};
- protected:
- void Draw(ID2D1RenderTarget* render_target) override;
- private:
- DrawHandler draw_handler_{};
- };
-}
+class LinearLayoutRenderObject : public RenderObject
+{
+public:
+ LinearLayoutRenderObject() = default;
+ LinearLayoutRenderObject(const LinearLayoutRenderObject& other) = delete;
+ LinearLayoutRenderObject& operator=(const LinearLayoutRenderObject& other) =
+ delete;
+ LinearLayoutRenderObject(LinearLayoutRenderObject&& other) = delete;
+ LinearLayoutRenderObject& operator=(LinearLayoutRenderObject&& other) =
+ delete;
+ ~LinearLayoutRenderObject() = default;
+
+ void Measure(const MeasureConstraint& constraint) override;
+
+private:
+};
+} // namespace cru::ui::render