diff options
author | crupest <crupest@outlook.com> | 2020-06-28 00:03:11 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-06-28 00:03:11 +0800 |
commit | 06d1d0442276a05b6caad6e3468f4afb1e8ee5df (patch) | |
tree | ebd46f0fb7343dc57bf947b7b5fffc139c3ddeac /src/ui/Control.cpp | |
parent | e11be6caa9ef9b2b198ca61846e32f469627556e (diff) | |
download | cru-06d1d0442276a05b6caad6e3468f4afb1e8ee5df.tar.gz cru-06d1d0442276a05b6caad6e3468f4afb1e8ee5df.tar.bz2 cru-06d1d0442276a05b6caad6e3468f4afb1e8ee5df.zip |
...
Diffstat (limited to 'src/ui/Control.cpp')
-rw-r--r-- | src/ui/Control.cpp | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/src/ui/Control.cpp b/src/ui/Control.cpp new file mode 100644 index 00000000..cd1367fe --- /dev/null +++ b/src/ui/Control.cpp @@ -0,0 +1,130 @@ +#include "cru/ui/Control.hpp" + +#include "cru/platform/native/Cursor.hpp" +#include "cru/platform/native/UiApplication.hpp" +#include "cru/ui/Base.hpp" +#include "cru/ui/UiHost.hpp" +#include "RoutedEventDispatch.hpp" + +#include <memory> + +namespace cru::ui { +using platform::native::ICursor; +using platform::native::IUiApplication; +using platform::native::SystemCursorType; + +Control::Control() { + MouseEnterEvent()->Direct()->AddHandler([this](event::MouseEventArgs&) { + this->is_mouse_over_ = true; + this->OnMouseHoverChange(true); + }); + + MouseLeaveEvent()->Direct()->AddHandler([this](event::MouseEventArgs&) { + this->is_mouse_over_ = false; + this->OnMouseHoverChange(true); + }); +} + +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); +} + +void Control::_SetDescendantUiHost(UiHost* 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); + }); +} + +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 = GetUiHost(); + if (host == nullptr) return false; + + return host->RequestFocusFor(this); +} + +bool Control::HasFocus() { + auto host = GetUiHost(); + if (host == nullptr) return false; + + return host->GetFocusControl() == this; +} + +bool Control::CaptureMouse() { + auto host = GetUiHost(); + if (host == nullptr) return false; + + return host->CaptureMouseFor(this); +} + +bool Control::ReleaseMouse() { + auto host = GetUiHost(); + if (host == nullptr) return false; + + return host->CaptureMouseFor(nullptr); +} + +bool Control::IsMouseCaptured() { + auto host = GetUiHost(); + if (host == nullptr) return false; + + return host->GetMouseCaptureControl() == this; +} + +std::shared_ptr<ICursor> Control::GetCursor() { return cursor_; } + +std::shared_ptr<ICursor> Control::GetInheritedCursor() { + Control* control = this; + while (control != nullptr) { + const auto cursor = control->GetCursor(); + if (cursor != nullptr) return cursor; + control = control->GetParent(); + } + return IUiApplication::GetInstance()->GetCursorManager()->GetSystemCursor( + SystemCursorType::Arrow); +} + +void Control::SetCursor(std::shared_ptr<ICursor> cursor) { + cursor_ = std::move(cursor); + const auto host = GetUiHost(); + if (host != nullptr) { + host->UpdateCursor(); + } +} + +void Control::OnParentChanged(Control* old_parent, Control* new_parent) { + CRU_UNUSED(old_parent) + CRU_UNUSED(new_parent) +} + +void Control::OnAttachToHost(UiHost* host) { CRU_UNUSED(host) } + +void Control::OnDetachFromHost(UiHost* host) { CRU_UNUSED(host) } +} // namespace cru::ui |