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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//! Macros for implementing event handling in widgets.
/// Generates internal binding method and public on_* methods for window events
#[macro_export]
macro_rules! implement_window_event_handlers {
($widget:ident,
$($event_variant:ident => $method_name:ident, $event_type:expr, $event_data:ident),+) => {
impl $widget {
// Internal binding method
#[doc(hidden)]
pub(crate) fn bind_window_event<F>(&self, event_type: $crate::event::WindowEvent, mut callback: F) -> $crate::event::EventToken
where
F: FnMut($crate::event::WindowEventData) + 'static
{
// Map WindowEvent to appropriate EventType
let event_type_ffi = match event_type {
$($crate::event::WindowEvent::$event_variant => $event_type,)*
};
// Convert raw event to typed event
let wrapper = move |event: $crate::event::Event| {
let typed_event = match event_type {
$($crate::event::WindowEvent::$event_variant =>
$crate::event::WindowEventData::$event_data($crate::event::$event_data::new(event)),)*
_ => $crate::event::WindowEventData::General(event),
};
callback(typed_event);
};
// Use internal bind method and return token
$crate::event::WxEvtHandler::bind_internal(self, event_type_ffi, wrapper)
}
// Generate public on_* methods
$(
paste::paste! {
/// Binds a handler to a window event.
/// Returns an EventToken that can be used to unbind the handler later.
pub fn [<on_ $method_name>]<F>(&self, mut callback: F) -> $crate::event::EventToken
where
F: FnMut($crate::event::[<$event_data Event>]) + 'static
{
self.bind_window_event($crate::event::WindowEvent::$event_variant, move |event| {
if let $crate::event::WindowEventData::$event_data(typed_event) = event {
callback(typed_event);
}
})
}
}
)*
}
}
}
/// Generates internal binding method and public on_* methods for category-specific events
#[macro_export]
macro_rules! implement_category_event_handlers {
// Generic implementation for category event traits
($trait_name:ident, $event_enum:ident, $event_data:ident,
$($variant:ident => $method_name:ident, $event_type:expr),+) => {
pub trait $trait_name: $crate::event::WxEvtHandler {
// Internal binding method
#[doc(hidden)]
fn bind_category_event<F>(&self, event: $crate::event::$event_enum, mut callback: F) -> $crate::event::EventToken
where
F: FnMut($crate::event::$event_data) + 'static
{
// Map enum variant to EventType
let event_type = match event {
$($crate::event::$event_enum::$variant => $event_type,)*
};
// Create wrapper
let wrapper = move |event: $crate::event::Event| {
let typed_event = $crate::event::$event_data::new(event);
callback(typed_event);
};
// Use internal bind method and return token
$crate::event::WxEvtHandler::bind_internal(self, event_type, wrapper)
}
// Public helper methods
$(
paste::paste! {
/// Binds a handler to a category-specific event.
/// Returns an EventToken that can be used to unbind the handler later.
fn [<on_ $method_name>]<F>(&self, callback: F) -> $crate::event::EventToken
where
F: FnMut($crate::event::$event_data) + 'static
{
self.bind_category_event($crate::event::$event_enum::$variant, callback)
}
}
)*
}
}
}
/// Generates internal binding method and public on_* methods for widget-specific events defined in the same module
#[macro_export]
macro_rules! implement_widget_local_event_handlers {
($widget:ident, $event_enum:ident, $event_data:ident,
$($variant:ident => $method_name:ident, $event_type:expr),+) => {
impl $widget {
// Internal binding method
#[doc(hidden)]
pub(crate) fn bind_widget_event<F>(&self, event: $event_enum, mut callback: F) -> $crate::event::EventToken
where
F: FnMut($event_data) + 'static
{
// Map enum variant to EventType
let event_type = match event {
$($event_enum::$variant => $event_type,)*
};
// Create wrapper
let wrapper = move |event: $crate::event::Event| {
let typed_event = $event_data::new(event);
callback(typed_event);
};
// Use internal bind method and return token
$crate::event::WxEvtHandler::bind_internal(self, event_type, wrapper)
}
// Public helper methods
$(
paste::paste! {
/// Binds a handler to a widget-specific event.
/// Returns an EventToken that can be used to unbind the handler later.
pub fn [<on_ $method_name>]<F>(&self, callback: F) -> $crate::event::EventToken
where
F: FnMut($event_data) + 'static
{
self.bind_widget_event($event_enum::$variant, callback)
}
}
)*
}
}
}