aboutsummaryrefslogtreecommitdiff
path: root/src/ui/controls/Control.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/controls/Control.cpp')
-rw-r--r--src/ui/controls/Control.cpp120
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