aboutsummaryrefslogtreecommitdiff
path: root/src/ui/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/render')
-rw-r--r--src/ui/render/flex_layout_render_object.cpp2
-rw-r--r--src/ui/render/render_object.cpp5
-rw-r--r--src/ui/render/render_object.hpp8
-rw-r--r--src/ui/render/text_render_object.cpp6
-rw-r--r--src/ui/render/text_render_object.hpp2
-rw-r--r--src/ui/render/window_render_object.cpp48
-rw-r--r--src/ui/render/window_render_object.hpp40
7 files changed, 108 insertions, 3 deletions
diff --git a/src/ui/render/flex_layout_render_object.cpp b/src/ui/render/flex_layout_render_object.cpp
index 58e7e338..7891906d 100644
--- a/src/ui/render/flex_layout_render_object.cpp
+++ b/src/ui/render/flex_layout_render_object.cpp
@@ -162,6 +162,8 @@ void FlexLayoutRenderObject::OnLayoutContent(const Rect& content_rect) {
return start_point + (total_length - content_length) / 2.0f;
case Alignment::End:
return start_point + total_length - content_length;
+ default:
+ UnreachableCode();
}
};
diff --git a/src/ui/render/render_object.cpp b/src/ui/render/render_object.cpp
index 0a0e693c..0be44c1e 100644
--- a/src/ui/render/render_object.cpp
+++ b/src/ui/render/render_object.cpp
@@ -51,6 +51,8 @@ void RenderObject::OnAddChild(RenderObject* new_child, int position) {}
void RenderObject::OnRemoveChild(RenderObject* removed_child, int position) {}
+void RenderObject::OnSizeChanged(const Size& old_size, const Size& new_size) {}
+
void RenderObject::SetParent(RenderObject* new_parent) {
const auto old_parent = parent_;
parent_ = new_parent;
@@ -80,8 +82,7 @@ void RenderObject::OnMeasureCore(const Size& available_size) {
const auto actual_content_size =
OnMeasureContent(coerced_content_available_size);
- SetPreferredSize(margin_padding_size + content_available_size +
- actual_content_size);
+ SetPreferredSize(margin_padding_size + actual_content_size);
}
void RenderObject::OnLayoutCore(const Rect& rect) {
diff --git a/src/ui/render/render_object.hpp b/src/ui/render/render_object.hpp
index 34f5dcee..a9950198 100644
--- a/src/ui/render/render_object.hpp
+++ b/src/ui/render/render_object.hpp
@@ -37,7 +37,11 @@ class RenderObject : public Object {
Point GetOffset() const { return offset_; }
void SetOffset(const Point& offset) { offset_ = offset; }
Size GetSize() const { return size_; }
- void SetSize(const Size& size) { size_ = 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; }
@@ -64,6 +68,8 @@ class RenderObject : public Object {
virtual void OnAddChild(RenderObject* new_child, int position);
virtual void OnRemoveChild(RenderObject* removed_child, int position);
+ virtual void OnSizeChanged(const Size& old_size, const Size& new_size);
+
virtual Size OnMeasureContent(const Size& available_size) = 0;
virtual void OnLayoutContent(const Rect& content_rect) = 0;
diff --git a/src/ui/render/text_render_object.cpp b/src/ui/render/text_render_object.cpp
index 43724e9f..e8032f78 100644
--- a/src/ui/render/text_render_object.cpp
+++ b/src/ui/render/text_render_object.cpp
@@ -62,6 +62,12 @@ RenderObject* TextRenderObject::HitTest(const Point& point) {
return Rect{Point::Zero(), GetSize()}.IsPointInside(point) ? this : nullptr;
}
+void TextRenderObject::OnSizeChanged(const Size& old_size,
+ const Size& new_size) {
+ ThrowIfFailed(text_layout_->SetMaxWidth(new_size.width));
+ ThrowIfFailed(text_layout_->SetMaxHeight(new_size.height));
+}
+
Size TextRenderObject::OnMeasureContent(const Size& available_size) {
ThrowIfFailed(text_layout_->SetMaxWidth(available_size.width));
ThrowIfFailed(text_layout_->SetMaxHeight(available_size.height));
diff --git a/src/ui/render/text_render_object.hpp b/src/ui/render/text_render_object.hpp
index d1d91034..4361b9c0 100644
--- a/src/ui/render/text_render_object.hpp
+++ b/src/ui/render/text_render_object.hpp
@@ -56,6 +56,8 @@ class TextRenderObject : public RenderObject {
RenderObject* HitTest(const Point& point) override;
protected:
+ void OnSizeChanged(const Size& old_size, const Size& new_size) override;
+
Size OnMeasureContent(const Size& available_size) override;
void OnLayoutContent(const Rect& content_rect) override;
diff --git a/src/ui/render/window_render_object.cpp b/src/ui/render/window_render_object.cpp
new file mode 100644
index 00000000..52452bd4
--- /dev/null
+++ b/src/ui/render/window_render_object.cpp
@@ -0,0 +1,48 @@
+#include "window_render_object.hpp"
+
+#include <cassert>
+
+#include "graph/graph.hpp"
+#include "ui/window.hpp"
+
+namespace cru::ui::render {
+void WindowRenderObject::MeasureAndLayout() {
+ const auto client_size = window_->GetClientSize();
+ Measure(client_size);
+ Layout(Rect{Point::Zero(), client_size});
+}
+
+void WindowRenderObject::Draw(ID2D1RenderTarget* render_target) {
+ if (const auto child = GetChild()) {
+ auto offset = child->GetOffset();
+ graph::WithTransform(render_target,
+ D2D1::Matrix3x2F::Translation(offset.x, offset.y),
+ [child](auto rt) { child->Draw(rt); });
+ }
+}
+
+RenderObject* WindowRenderObject::HitTest(const Point& point) {
+ if (const auto child = GetChild()) {
+ auto offset = child->GetOffset();
+ Point p{point.x - offset.x, point.y - offset.y};
+ const auto result = child->HitTest(point);
+ if (result != nullptr) {
+ return result;
+ }
+ }
+ return Rect{Point::Zero(), GetSize()}.IsPointInside(point) ? this : nullptr;
+}
+
+void WindowRenderObject::OnAddChild(RenderObject* new_child, int position) {
+ assert(GetChildren().size() == 1);
+}
+
+Size WindowRenderObject::OnMeasureContent(const Size& available_size) {
+ if (const auto child = GetChild()) child->Measure(available_size);
+ return available_size;
+}
+
+void WindowRenderObject::OnLayoutContent(const Rect& content_rect) {
+ if (const auto child = GetChild()) child->Layout(content_rect);
+}
+} // namespace cru::ui::render
diff --git a/src/ui/render/window_render_object.hpp b/src/ui/render/window_render_object.hpp
new file mode 100644
index 00000000..63eb8588
--- /dev/null
+++ b/src/ui/render/window_render_object.hpp
@@ -0,0 +1,40 @@
+#pragma once
+#include "pre.hpp"
+
+#include "render_object.hpp"
+
+namespace cru::ui {
+class Window;
+}
+
+namespace cru::ui::render {
+class WindowRenderObject : public RenderObject {
+ public:
+ WindowRenderObject(Window* window) : window_(window) {}
+ WindowRenderObject(const WindowRenderObject& other) = delete;
+ WindowRenderObject(WindowRenderObject&& other) = delete;
+ WindowRenderObject& operator=(const WindowRenderObject& other) = delete;
+ WindowRenderObject& operator=(WindowRenderObject&& other) = delete;
+ ~WindowRenderObject() override = default;
+
+ void MeasureAndLayout();
+
+ void Draw(ID2D1RenderTarget* render_target) override;
+
+ RenderObject* HitTest(const Point& point) override;
+
+ protected:
+ void OnAddChild(RenderObject* new_child, int position) override;
+
+ Size OnMeasureContent(const Size& available_size) override;
+ void OnLayoutContent(const Rect& content_rect) override;
+
+ private:
+ RenderObject* GetChild() const {
+ return GetChildren().empty() ? nullptr : GetChildren()[0];
+ }
+
+ private:
+ Window* window_;
+};
+} // namespace cru::ui::render