aboutsummaryrefslogtreecommitdiff
path: root/src/ui/render/render_object.cpp
diff options
context:
space:
mode:
author杨宇千 <crupest@outlook.com>2019-03-28 20:39:36 +0800
committerGitHub <noreply@github.com>2019-03-28 20:39:36 +0800
commitc45a6e62298e972f5945f5f3461ed723aea80317 (patch)
treef46ef303ee87a8e3814ea8743bd7062d432bfee3 /src/ui/render/render_object.cpp
parentb028e74a48de181ca078ad3bf4ababf4fa146cd3 (diff)
parent37216f211b0e22205a3a0d3373d985fc68aea59b (diff)
downloadcru-c45a6e62298e972f5945f5f3461ed723aea80317.tar.gz
cru-c45a6e62298e972f5945f5f3461ed723aea80317.tar.bz2
cru-c45a6e62298e972f5945f5f3461ed723aea80317.zip
Merge pull request #37 from crupest/render
Refactor.
Diffstat (limited to 'src/ui/render/render_object.cpp')
-rw-r--r--src/ui/render/render_object.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/ui/render/render_object.cpp b/src/ui/render/render_object.cpp
new file mode 100644
index 00000000..5c6af580
--- /dev/null
+++ b/src/ui/render/render_object.cpp
@@ -0,0 +1,115 @@
+#include "render_object.hpp"
+
+#include <algorithm>
+
+#include "cru_debug.hpp"
+
+namespace cru::ui::render {
+void RenderObject::AddChild(RenderObject* render_object, const int position) {
+ assert(render_object->GetParent() ==
+ nullptr); // Render object already has a parent.
+ assert(position >= 0); // Position index is less than 0.
+ assert(position <= children_.size()); // 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) {
+ assert(position >= 0); // Position index is less than 0.
+ assert(position < children_.size()); // 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::Measure(const Size& available_size) {
+ OnMeasureCore(available_size);
+}
+
+void RenderObject::Layout(const Rect& rect) {
+ SetOffset(rect.GetLeftTop());
+ SetSize(rect.GetSize());
+ OnLayoutCore(Rect{Point::Zero(), rect.GetSize()});
+}
+
+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::OnSizeChanged(const Size& old_size, const Size& new_size) {}
+
+void RenderObject::OnMeasureCore(const Size& available_size) {
+ Size margin_padding_size{
+ margin_.GetHorizontalTotal() + padding_.GetHorizontalTotal(),
+ margin_.GetVerticalTotal() + padding_.GetVerticalTotal()};
+
+ auto coerced_margin_padding_size = margin_padding_size;
+ if (coerced_margin_padding_size.width > available_size.width) {
+ debug::DebugMessage(
+ L"Measure: horizontal length of padding and margin is bigger than "
+ L"available length.");
+ coerced_margin_padding_size.width = available_size.width;
+ }
+ if (coerced_margin_padding_size.height > available_size.height) {
+ debug::DebugMessage(
+ L"Measure: vertical length of padding and margin is bigger than "
+ L"available length.");
+ coerced_margin_padding_size.height = available_size.height;
+ }
+
+ const auto coerced_content_available_size =
+ available_size - coerced_margin_padding_size;
+ const auto actual_content_size =
+ OnMeasureContent(coerced_content_available_size);
+
+ SetPreferredSize(coerced_margin_padding_size + actual_content_size);
+}
+
+void RenderObject::OnLayoutCore(const Rect& rect) {
+ Size margin_padding_size{
+ margin_.GetHorizontalTotal() + padding_.GetHorizontalTotal(),
+ margin_.GetVerticalTotal() + padding_.GetVerticalTotal()};
+ const auto content_available_size = rect.GetSize() - margin_padding_size;
+ auto coerced_content_available_size = content_available_size;
+
+ if (coerced_content_available_size.width < 0) {
+ debug::DebugMessage(
+ L"Layout: horizontal length of padding and margin is bigger than "
+ L"available length.");
+ coerced_content_available_size.width = 0;
+ }
+ if (coerced_content_available_size.height < 0) {
+ debug::DebugMessage(
+ L"Layout: vertical length of padding and margin is bigger than "
+ L"available length.");
+ coerced_content_available_size.height = 0;
+ }
+
+ OnLayoutContent(Rect{margin_.left + padding_.left, margin_.top + padding_.top,
+ coerced_content_available_size.width,
+ coerced_content_available_size.height});
+}
+
+Rect RenderObject::GetContentRect() const {
+ Rect rect{Point::Zero(), GetSize()};
+ rect = rect.Shrink(GetMargin());
+ rect = rect.Shrink(GetPadding());
+ rect.width = std::max(rect.width, 0.0f);
+ rect.height = std::max(rect.height, 0.0f);
+ return rect;
+}
+
+void RenderObject::SetParent(RenderObject* new_parent) {
+ const auto old_parent = parent_;
+ parent_ = new_parent;
+ OnParentChanged(old_parent, new_parent);
+}
+} // namespace cru::ui::render