blob: 8ea7ca790b510060b1af497293e00f67611f4feb (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
#pragma once
#include "cru/common/base.hpp"
#include "../base.hpp"
#include <vector>
// forward declarations
namespace cru::ui {
class Control;
}
namespace cru::platform::graph {
class Painter;
}
namespace cru::ui::render {
struct IRenderHost : Interface {
// Mark the layout as invalid, and arrange a re-layout later.
// Note this method might be called more than one times in a message cycle. So
// implementation should merge multiple request into once.
virtual void InvalidateLayout() = 0;
// Mark the paint as invalid, and arrange a re-paint later.
// Note this method might be called more than one times in a message cycle. So
// implementation should merge multiple request into once.
virtual void InvalidatePaint() = 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;
Control* GetAttachedControl() const { return control_; }
void SetAttachedControl(Control* new_control) { control_ = new_control; }
IRenderHost* GetRenderHost() const { return render_host_; }
void SetRenderHost(IRenderHost* render_host) { render_host_ = render_host; }
RenderObject* GetParent() const { return parent_; }
const std::vector<RenderObject*>& GetChildren() const { return children_; }
void AddChild(RenderObject* render_object, int position);
void RemoveChild(int position);
Point GetOffset() const { return offset_; }
void SetOffset(const Point& offset) { offset_ = offset; }
Size GetSize() const { return size_; }
void SetSize(const Size& size) {
const auto old_size = size_;
size_ = size;
OnSizeChanged(old_size, size);
}
Thickness GetMargin() const { return margin_; }
void SetMargin(const Thickness& margin) { margin_ = margin; }
Thickness GetPadding() const { return padding_; }
void SetPadding(const Thickness& padding) { padding_ = padding; }
Size GetPreferredSize() const { return preferred_size_; }
void SetPreferredSize(const Size& preferred_size) {
preferred_size_ = preferred_size;
}
void Measure(const Size& available_size);
void Layout(const Rect& rect);
virtual void Draw(platform::graph::Painter* painter) = 0;
virtual RenderObject* HitTest(const Point& point) = 0;
protected:
enum class ChildMode {
None,
Single,
Multiple,
};
void SetChildMode(ChildMode mode) { child_mode_ = mode; }
void InvalidateLayout() const {
if (render_host_ != nullptr) render_host_->InvalidateLayout();
}
void InvalidatePaint() const {
if (render_host_ != nullptr) render_host_->InvalidatePaint();
}
protected:
virtual void OnParentChanged(RenderObject* old_parent,
RenderObject* new_parent);
// default is to invalidate both layout and paint
virtual void OnAddChild(RenderObject* new_child, int position);
// default is to invalidate both layout and paint
virtual void OnRemoveChild(RenderObject* removed_child, int position);
virtual void OnSizeChanged(const Size& old_size, const Size& new_size);
virtual void OnMeasureCore(const Size& available_size);
virtual void OnLayoutCore(const Rect& rect);
virtual Size OnMeasureContent(const Size& available_size) = 0;
virtual void OnLayoutContent(const Rect& content_rect) = 0;
Rect GetContentRect() const;
private:
void SetParent(RenderObject* new_parent);
private:
Control* control_ = nullptr;
IRenderHost* render_host_ = nullptr;
RenderObject* parent_ = nullptr;
std::vector<RenderObject*> children_{};
ChildMode child_mode_ = ChildMode::None;
Point offset_{};
Size size_{};
Thickness margin_{};
Thickness padding_{};
Size preferred_size_{};
};
} // namespace cru::ui::render
|