diff options
author | crupest <crupest@outlook.com> | 2020-10-29 00:01:26 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-10-29 00:01:26 +0800 |
commit | 52594324b302f6e9da10ac01fe803196371bb2d9 (patch) | |
tree | 38dd36e0bf934b283dd80f808531a2ee862b174b /src/ui/Control.cpp | |
parent | df4df679e157f974773dad7776b204e9d4f3009e (diff) | |
download | cru-52594324b302f6e9da10ac01fe803196371bb2d9.tar.gz cru-52594324b302f6e9da10ac01fe803196371bb2d9.tar.bz2 cru-52594324b302f6e9da10ac01fe803196371bb2d9.zip |
...
Diffstat (limited to 'src/ui/Control.cpp')
-rw-r--r-- | src/ui/Control.cpp | 106 |
1 files changed, 67 insertions, 39 deletions
diff --git a/src/ui/Control.cpp b/src/ui/Control.cpp index cd7ed0dc..13b1c780 100644 --- a/src/ui/Control.cpp +++ b/src/ui/Control.cpp @@ -1,10 +1,12 @@ #include "cru/ui/Control.hpp" +#include "RoutedEventDispatch.hpp" +#include "cru/common/Base.hpp" #include "cru/platform/native/Cursor.hpp" #include "cru/platform/native/UiApplication.hpp" #include "cru/ui/Base.hpp" #include "cru/ui/WindowHost.hpp" -#include "RoutedEventDispatch.hpp" +#include "cru/ui/render/RenderObject.hpp" #include <memory> @@ -25,49 +27,16 @@ Control::Control() { }); } -void Control::_SetParent(Control* parent) { - const auto old_parent = GetParent(); - parent_ = parent; - const auto new_parent = GetParent(); - if (old_parent != new_parent) OnParentChanged(old_parent, new_parent); +Control::~Control() { + for (const auto child : children_) delete child; } -void Control::_SetDescendantWindowHost(WindowHost* host) { - if (host == nullptr && ui_host_ == nullptr) return; - - // You can only attach or detach window. - Expects((host != nullptr && ui_host_ == nullptr) || - (host == nullptr && ui_host_ != nullptr)); - - if (host == nullptr) { - const auto old = ui_host_; - TraverseDescendants([old](Control* control) { - control->ui_host_ = nullptr; - control->OnDetachFromHost(old); - }); - } else - TraverseDescendants([host](Control* control) { - control->ui_host_ = host; - control->OnAttachToHost(host); - }); -} +WindowHost* Control::GetWindowHost() const { return window_host_; } void Control::TraverseDescendants( const std::function<void(Control*)>& predicate) { - _TraverseDescendants(this, predicate); -} - -void Control::_TraverseDescendants( - Control* control, const std::function<void(Control*)>& predicate) { - predicate(control); - for (auto c : control->GetChildren()) _TraverseDescendants(c, predicate); -} - -bool Control::RequestFocus() { - auto host = GetWindowHost(); - if (host == nullptr) return false; - - return host->RequestFocusFor(this); + predicate(this); + for (auto c : GetChildren()) c->TraverseDescendants(predicate); } bool Control::HasFocus() { @@ -84,6 +53,13 @@ bool Control::CaptureMouse() { return host->CaptureMouseFor(this); } +void Control::SetFocus() { + auto host = GetWindowHost(); + if (host == nullptr) return; + + host->SetFocusControl(this); +} + bool Control::ReleaseMouse() { auto host = GetWindowHost(); if (host == nullptr) return false; @@ -119,6 +95,58 @@ void Control::SetCursor(std::shared_ptr<ICursor> cursor) { } } +void Control::AddChild(Control* control, const Index position) { + Expects(control->GetParent() == + nullptr); // The control already has a parent. + Expects(position >= 0); + Expects(position <= static_cast<Index>( + children_.size())); // The position is out of range. + + children_.insert(children_.cbegin() + position, control); + + const auto old_parent = control->parent_; + control->parent_ = this; + + OnAddChild(control, position); + control->OnParentChanged(old_parent, this); + + if (window_host_) + control->TraverseDescendants([this](Control* control) { + control->window_host_ = window_host_; + control->OnAttachToHost(window_host_); + }); +} + +void Control::RemoveChild(const Index position) { + Expects(position >= 0); + Expects(position < static_cast<Index>( + children_.size())); // The position is out of range. + + const auto i = children_.cbegin() + position; + const auto control = *i; + + children_.erase(i); + control->parent_ = nullptr; + + OnRemoveChild(control, position); + control->OnParentChanged(this, nullptr); + + if (window_host_) + control->TraverseDescendants([this](Control* control) { + control->window_host_ = nullptr; + control->OnDetachFromHost(window_host_); + }); +} + +void Control::OnAddChild(Control* child, Index position) { + CRU_UNUSED(child) + CRU_UNUSED(position) +} +void Control::OnRemoveChild(Control* child, Index position) { + CRU_UNUSED(child) + CRU_UNUSED(position) +} + void Control::OnParentChanged(Control* old_parent, Control* new_parent) { CRU_UNUSED(old_parent) CRU_UNUSED(new_parent) |