diff options
author | crupest <crupest@outlook.com> | 2019-03-20 17:08:57 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2019-03-20 17:08:57 +0800 |
commit | 1e3cad155a234d2e3e9b6aca650d4d1c4c9e8d4e (patch) | |
tree | 3fc01db4d6d36ed9f6e7795d2b87da96b4412f5f /src/ui/render/render_object.cpp | |
parent | 5dc738a57930271194bd86673eb86f149096a7b2 (diff) | |
download | cru-1e3cad155a234d2e3e9b6aca650d4d1c4c9e8d4e.tar.gz cru-1e3cad155a234d2e3e9b6aca650d4d1c4c9e8d4e.tar.bz2 cru-1e3cad155a234d2e3e9b6aca650d4d1c4c9e8d4e.zip |
...
Diffstat (limited to 'src/ui/render/render_object.cpp')
-rw-r--r-- | src/ui/render/render_object.cpp | 158 |
1 files changed, 99 insertions, 59 deletions
diff --git a/src/ui/render/render_object.cpp b/src/ui/render/render_object.cpp index c2aaeb62..0035d1be 100644 --- a/src/ui/render/render_object.cpp +++ b/src/ui/render/render_object.cpp @@ -1,90 +1,130 @@ #include "render_object.hpp" -#include <utility> -namespace cru::ui::render -{ -void RenderObject::SetRenderHost(IRenderHost* new_render_host) -{ - if (new_render_host == render_host_) return; +#include "cru_debug.hpp" - const auto old = render_host_; - render_host_ = new_render_host; - OnRenderHostChanged(old, new_render_host); +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::AddChild(RenderObject* render_object, const int position) -{ - if (render_object->GetParent() != nullptr) - throw std::invalid_argument("Render object already has a parent."); +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 (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."); + 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); + 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."); +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."); + 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); + 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::OnRenderHostChanged(IRenderHost* old_render_host, - IRenderHost* new_render_host) -{ +void RenderObject::Layout(const Rect& rect) { + SetOffset(rect.GetLeftTop()); + SetSize(rect.GetSize()); + OnLayoutCore(Rect{Point::Zero(), rect.GetSize()}); } -void RenderObject::InvalidateRenderHostPaint() const -{ - if (render_host_ != nullptr) render_host_->InvalidatePaint(); +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::InvalidateRenderHostLayout() const { + if (render_host_ != nullptr) render_host_->InvalidateLayout(); } void RenderObject::OnParentChanged(RenderObject* old_parent, - RenderObject* new_parent) -{ -} + RenderObject* new_parent) {} +void RenderObject::OnAddChild(RenderObject* new_child, int position) {} -void RenderObject::OnAddChild(RenderObject* new_child, int position) -{ -} +void RenderObject::OnRemoveChild(RenderObject* removed_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 RenderObject::SetParent(RenderObject* new_parent) -{ - const auto old_parent = parent_; - parent_ = new_parent; - OnParentChanged(old_parent, new_parent); +void RenderObject::OnMeasureCore(const Size& available_size) { + Size margin_padding_size{ + margin_.GetHorizontalTotal() + padding_.GetHorizontalTotal(), + margin_.GetVerticalTotal() + padding_.GetVerticalTotal()}; + const auto content_available_size = available_size - margin_padding_size; + auto coerced_content_available_size = content_available_size; + + if (coerced_content_available_size.width < 0) { + debug::DebugMessage( + L"Measure: 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"Measure: vertical length of padding and margin is bigger than " + L"available length."); + coerced_content_available_size.height = 0; + } + + const auto actual_content_size = + OnMeasureContent(coerced_content_available_size); + + SetPreferredSize(margin_padding_size + content_available_size + + actual_content_size); } - -void LinearLayoutRenderObject::Measure(const MeasureConstraint& constraint) -{ - +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}); } } // namespace cru::ui::render |