aboutsummaryrefslogtreecommitdiff
path: root/include/cru/ui/render/LayoutRenderObject.h
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-02-08 16:53:51 +0800
committercrupest <crupest@outlook.com>2022-02-08 16:53:51 +0800
commit74bb9cd27242b9320f99ff4d2b50c3051576cc14 (patch)
tree744bac5799c593d1d6f81e7b09581bea626f2cde /include/cru/ui/render/LayoutRenderObject.h
parentb90c398de829d1ba5329651d75bae82f5e4085fe (diff)
downloadcru-74bb9cd27242b9320f99ff4d2b50c3051576cc14.tar.gz
cru-74bb9cd27242b9320f99ff4d2b50c3051576cc14.tar.bz2
cru-74bb9cd27242b9320f99ff4d2b50c3051576cc14.zip
...
Diffstat (limited to 'include/cru/ui/render/LayoutRenderObject.h')
-rw-r--r--include/cru/ui/render/LayoutRenderObject.h86
1 files changed, 86 insertions, 0 deletions
diff --git a/include/cru/ui/render/LayoutRenderObject.h b/include/cru/ui/render/LayoutRenderObject.h
new file mode 100644
index 00000000..42a3aa55
--- /dev/null
+++ b/include/cru/ui/render/LayoutRenderObject.h
@@ -0,0 +1,86 @@
+#pragma once
+#include "RenderObject.h"
+
+#include "cru/platform/graphics/util/Painter.h"
+
+namespace cru::ui::render {
+template <typename TChildLayoutData>
+class CRU_UI_API LayoutRenderObject : public RenderObject {
+ public:
+ using ChildLayoutData = TChildLayoutData;
+
+ protected:
+ LayoutRenderObject() : RenderObject(ChildMode::Multiple) {}
+
+ public:
+ CRU_DELETE_COPY(LayoutRenderObject)
+ CRU_DELETE_MOVE(LayoutRenderObject)
+
+ ~LayoutRenderObject() override = default;
+
+ const std::vector<ChildLayoutData>& GetChildLayoutDataList() const {
+ return this->child_layout_data_;
+ }
+
+ 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();
+ }
+
+ const ChildLayoutData& GetChildLayoutData(Index position) const {
+ Expects(position >= 0 &&
+ position < static_cast<Index>(this->child_layout_data_.size()));
+ return this->child_layout_data_[position];
+ }
+
+ RenderObject* HitTest(const Point& point) override;
+
+ protected:
+ void OnAddChild(RenderObject* new_child, Index position) override;
+ void OnRemoveChild(RenderObject* removed_child, Index position) override;
+
+ private:
+ std::vector<ChildLayoutData> child_layout_data_{};
+};
+
+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