blob: 180ba476a926f2c9a9e932074dc94a7c895c988b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#include "cru/ui/control.hpp"
#include "cru/platform/native/cursor.hpp"
#include "cru/platform/native/ui_application.hpp"
#include "cru/platform/native/window.hpp"
#include "cru/ui/base.hpp"
#include "cru/ui/window.hpp"
#include "routed_event_dispatch.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::_SetDescendantWindow(Window* window) {
if (window == nullptr && window_ == nullptr) return;
// You can only attach or detach window.
Expects((window != nullptr && window_ == nullptr) ||
(window == nullptr && window_ != nullptr));
if (window == nullptr) {
const auto old = window_;
TraverseDescendants([old](Control* control) {
control->window_ = nullptr;
control->OnDetachToWindow(old);
});
} else
TraverseDescendants([window](Control* control) {
control->window_ = window;
control->OnAttachToWindow(window);
});
}
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 window = GetWindow();
if (window == nullptr) return false;
return window->RequestFocusFor(this);
}
bool Control::HasFocus() {
auto window = GetWindow();
if (window == nullptr) return false;
return window->GetFocusControl() == this;
}
bool Control::CaptureMouse() { return GetWindow()->CaptureMouseFor(this); }
bool Control::ReleaseMouse() { return GetWindow()->CaptureMouseFor(nullptr); }
bool Control::IsMouseCaptured() {
return GetWindow()->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 window = GetWindow();
if (window != nullptr) {
window->UpdateCursor();
}
}
void Control::OnParentChanged(Control* old_parent, Control* new_parent) {
CRU_UNUSED(old_parent)
CRU_UNUSED(new_parent)
}
void Control::OnAttachToWindow(Window* window) { CRU_UNUSED(window) }
void Control::OnDetachToWindow(Window* window) { CRU_UNUSED(window) }
} // namespace cru::ui
|