diff options
Diffstat (limited to 'src/ui/controls/Control.cpp')
| -rw-r--r-- | src/ui/controls/Control.cpp | 120 |
1 files changed, 58 insertions, 62 deletions
diff --git a/src/ui/controls/Control.cpp b/src/ui/controls/Control.cpp index 93213ecf..e903b5b3 100644 --- a/src/ui/controls/Control.cpp +++ b/src/ui/controls/Control.cpp @@ -1,10 +1,12 @@ #include "cru/ui/controls/Control.h" +#include "cru/ui/controls/Window.h" #include "cru/platform/gui/Cursor.h" #include "cru/platform/gui/UiApplication.h" -#include "cru/ui/host/WindowHost.h" #include "cru/ui/style/StyleRuleSet.h" +#include <format> + namespace cru::ui::controls { using platform::gui::ICursor; using platform::gui::IUiApplication; @@ -15,32 +17,45 @@ Control::Control() { style_rule_set_bind_ = std::make_unique<style::StyleRuleSetBind>(this, style_rule_set_); - MouseEnterEvent()->Direct()->AddHandler([this](events::MouseEventArgs&) { - this->is_mouse_over_ = true; - this->OnMouseHoverChange(true); - }); + MouseEnterEvent()->Direct()->AddHandler( + [this](events::MouseEventArgs&) { this->is_mouse_over_ = true; }); - MouseLeaveEvent()->Direct()->AddHandler([this](events::MouseEventArgs&) { - this->is_mouse_over_ = false; - this->OnMouseHoverChange(true); - }); + MouseLeaveEvent()->Direct()->AddHandler( + [this](events::MouseEventArgs&) { this->is_mouse_over_ = false; }); } Control::~Control() { - if (host::WindowHost::IsInEventHandling()) { - // Don't delete control during event handling. Use DeleteLater. - std::terminate(); + if (auto window = GetWindow()) { + if (window->IsInEventHandling()) { + // Don't delete control during event handling. Use DeleteLater. + std::terminate(); + } } - in_destruction_ = true; RemoveFromParent(); } +std::string Control::GetDebugId() const { + return std::format("{}({})", GetControlType(), + static_cast<const void*>(this)); +} + +Window* Control::GetWindow() { + auto parent = this; + while (parent) { + if (auto window = dynamic_cast<Window*>(parent)) { + return window; + } + parent = parent->GetParent(); + } + return nullptr; +} + void Control::SetParent(Control* parent) { if (parent_ == parent) return; auto old_parent = parent_; parent_ = parent; - OnParentChangedCore(old_parent, parent); + OnParentChanged(old_parent, parent); } void Control::RemoveFromParent() { @@ -49,39 +64,49 @@ void Control::RemoveFromParent() { } } +controls::Control* Control::HitTest(const Point& point) { + const auto render_object = GetRenderObject()->HitTest(point); + if (render_object) { + const auto control = render_object->GetAttachedControl(); + assert(control); + return control; + } + return nullptr; +} + bool Control::HasFocus() { - auto host = GetWindowHost(); - if (host == nullptr) return false; + auto window = GetWindow(); + if (window == nullptr) return false; - return host->GetFocusControl() == this; + return window->GetFocusControl() == this; } bool Control::CaptureMouse() { - auto host = GetWindowHost(); - if (host == nullptr) return false; + auto window = GetWindow(); + if (window == nullptr) return false; - return host->CaptureMouseFor(this); + return window->SetMouseCaptureControl(this); } void Control::SetFocus() { - auto host = GetWindowHost(); - if (host == nullptr) return; + auto window = GetWindow(); + if (window == nullptr) return; - host->SetFocusControl(this); + window->SetFocusControl(this); } bool Control::ReleaseMouse() { - auto host = GetWindowHost(); - if (host == nullptr) return false; - - return host->CaptureMouseFor(nullptr); + auto window = GetWindow(); + if (window == nullptr) return false; + if (window->GetMouseCaptureControl() != this) return false; + return window->SetMouseCaptureControl(nullptr); } bool Control::IsMouseCaptured() { - auto host = GetWindowHost(); - if (host == nullptr) return false; + auto window = GetWindow(); + if (window == nullptr) return false; - return host->GetMouseCaptureControl() == this; + return window->GetMouseCaptureControl() == this; } std::shared_ptr<ICursor> Control::GetCursor() { return cursor_; } @@ -99,42 +124,13 @@ std::shared_ptr<ICursor> Control::GetInheritedCursor() { void Control::SetCursor(std::shared_ptr<ICursor> cursor) { cursor_ = std::move(cursor); - const auto host = GetWindowHost(); - if (host != nullptr) { - host->UpdateCursor(); + const auto window = GetWindow(); + if (window != nullptr) { + window->UpdateCursor(); } } std::shared_ptr<style::StyleRuleSet> Control::GetStyleRuleSet() { return style_rule_set_; } - -void Control::OnParentChangedCore(Control* old_parent, Control* new_parent) { - auto new_window_host = - new_parent == nullptr ? nullptr : new_parent->GetWindowHost(); - if (window_host_ != new_window_host) { - auto old_host = window_host_; - window_host_ = new_window_host; - OnWindowHostChangedCore(old_host, new_window_host); - } - - if (!in_destruction_) OnParentChanged(old_parent, new_parent); -} - -void Control::OnWindowHostChangedCore(host::WindowHost* old_host, - host::WindowHost* new_host) { - if (old_host != nullptr) { - old_host->OnControlDetach(this); - } - - if (!in_destruction_) { - ForEachChild([old_host, new_host](Control* child) { - child->window_host_ = new_host; - child->OnWindowHostChangedCore(old_host, new_host); - }); - OnWindowHostChanged(old_host, new_host); - } -} - -void Control::OnPrepareDelete() { RemoveFromParent(); } } // namespace cru::ui::controls |
