diff options
Diffstat (limited to 'src/ui/render')
-rw-r--r-- | src/ui/render/linear_layout_render_object.cpp | 0 | ||||
-rw-r--r-- | src/ui/render/linear_layout_render_object.hpp | 1 | ||||
-rw-r--r-- | src/ui/render/render_object.cpp | 176 | ||||
-rw-r--r-- | src/ui/render/render_object.hpp | 302 |
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 |