aboutsummaryrefslogtreecommitdiff
path: root/src/ui/Control.cpp
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2020-06-28 00:03:11 +0800
committercrupest <crupest@outlook.com>2020-06-28 00:03:11 +0800
commit06d1d0442276a05b6caad6e3468f4afb1e8ee5df (patch)
treeebd46f0fb7343dc57bf947b7b5fffc139c3ddeac /src/ui/Control.cpp
parente11be6caa9ef9b2b198ca61846e32f469627556e (diff)
downloadcru-06d1d0442276a05b6caad6e3468f4afb1e8ee5df.tar.gz
cru-06d1d0442276a05b6caad6e3468f4afb1e8ee5df.tar.bz2
cru-06d1d0442276a05b6caad6e3468f4afb1e8ee5df.zip
...
Diffstat (limited to 'src/ui/Control.cpp')
-rw-r--r--src/ui/Control.cpp130
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