reflexion 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.doc/ext/reflex/key_event.cpp +20 -0
- data/.doc/ext/reflex/reflex.cpp +23 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +12 -0
- data/CONTRIBUTING.md +7 -0
- data/ChangeLog.md +21 -0
- data/README.md +46 -2
- data/VERSION +1 -1
- data/ext/reflex/extconf.rb +3 -3
- data/ext/reflex/key_event.cpp +20 -0
- data/ext/reflex/reflex.cpp +23 -0
- data/include/reflex/defs.h +23 -0
- data/include/reflex/view.h +10 -10
- data/lib/reflex/application.rb +2 -2
- data/lib/reflex/helper.rb +0 -12
- data/lib/reflex/shape.rb +2 -1
- data/lib/reflex/view.rb +10 -3
- data/lib/reflex/window.rb +2 -1
- data/reflex.gemspec +3 -3
- data/src/body.cpp +15 -5
- data/src/ios/event.h +5 -0
- data/src/ios/event.mm +84 -1
- data/src/ios/reflex.mm +5 -0
- data/src/ios/view_controller.mm +1 -7
- data/src/osx/event.h +5 -0
- data/src/osx/event.mm +87 -2
- data/src/osx/native_window.mm +1 -7
- data/src/osx/reflex.mm +5 -0
- data/src/view.cpp +56 -20
- data/src/win32/event.cpp +85 -1
- data/src/win32/event.h +3 -0
- data/src/win32/window.cpp +8 -7
- data/src/window.cpp +84 -34
- data/src/window.h +12 -1
- data/test/test_view.rb +51 -0
- metadata +16 -14
data/src/osx/event.mm
CHANGED
@@ -5,6 +5,9 @@
|
|
5
5
|
#include <assert.h>
|
6
6
|
#include <Carbon/Carbon.h>
|
7
7
|
#import <Cocoa/Cocoa.h>
|
8
|
+
#import <GameController/GameController.h>
|
9
|
+
#include "reflex/debug.h"
|
10
|
+
#include "window.h"
|
8
11
|
|
9
12
|
|
10
13
|
namespace Reflex
|
@@ -12,9 +15,9 @@ namespace Reflex
|
|
12
15
|
|
13
16
|
|
14
17
|
static uint
|
15
|
-
get_modifiers (const NSEvent*
|
18
|
+
get_modifiers (const NSEvent* event = nil)
|
16
19
|
{
|
17
|
-
NSUInteger flags =
|
20
|
+
NSUInteger flags = event ? event.modifierFlags : NSEvent.modifierFlags;
|
18
21
|
return
|
19
22
|
(flags & NSAlphaShiftKeyMask) ? MOD_CAPS : 0 |
|
20
23
|
(flags & NSShiftKeyMask) ? MOD_SHIFT : 0 |
|
@@ -161,4 +164,86 @@ namespace Reflex
|
|
161
164
|
}
|
162
165
|
|
163
166
|
|
167
|
+
static void
|
168
|
+
call_gamepad_event (int code, bool pressed)
|
169
|
+
{
|
170
|
+
Window* win = Window_get_active();
|
171
|
+
if (!win) return;
|
172
|
+
|
173
|
+
auto action = pressed ? KeyEvent::DOWN : KeyEvent::UP;
|
174
|
+
KeyEvent e(action, NULL, code, get_modifiers(), 0);
|
175
|
+
Window_call_key_event(win, &e);
|
176
|
+
}
|
177
|
+
|
178
|
+
static void
|
179
|
+
handle_gamepad_event (GCControllerButtonInput* input, int code)
|
180
|
+
{
|
181
|
+
[input setPressedChangedHandler:
|
182
|
+
^(GCControllerButtonInput* button, float value, BOOL pressed) {
|
183
|
+
call_gamepad_event(code, pressed);
|
184
|
+
}];
|
185
|
+
}
|
186
|
+
|
187
|
+
static void
|
188
|
+
handle_gamepad_events (GCController* controller)
|
189
|
+
{
|
190
|
+
GCExtendedGamepad* gamepad = controller.extendedGamepad;
|
191
|
+
if (!gamepad) return;
|
192
|
+
|
193
|
+
handle_gamepad_event(gamepad.dpad.left, KEY_GAMEPAD_LEFT);
|
194
|
+
handle_gamepad_event(gamepad.dpad.right, KEY_GAMEPAD_RIGHT);
|
195
|
+
handle_gamepad_event(gamepad.dpad.up, KEY_GAMEPAD_UP);
|
196
|
+
handle_gamepad_event(gamepad.dpad.down, KEY_GAMEPAD_DOWN);
|
197
|
+
|
198
|
+
handle_gamepad_event(gamepad.buttonA, KEY_GAMEPAD_A);
|
199
|
+
handle_gamepad_event(gamepad.buttonB, KEY_GAMEPAD_B);
|
200
|
+
handle_gamepad_event(gamepad.buttonX, KEY_GAMEPAD_X);
|
201
|
+
handle_gamepad_event(gamepad.buttonY, KEY_GAMEPAD_Y);
|
202
|
+
|
203
|
+
handle_gamepad_event(gamepad. leftShoulder, KEY_GAMEPAD_SHOULDER_LEFT);
|
204
|
+
handle_gamepad_event(gamepad.rightShoulder, KEY_GAMEPAD_SHOULDER_RIGHT);
|
205
|
+
handle_gamepad_event(gamepad. leftTrigger, KEY_GAMEPAD_TRIGGER_LEFT);
|
206
|
+
handle_gamepad_event(gamepad.rightTrigger, KEY_GAMEPAD_TRIGGER_RIGHT);
|
207
|
+
|
208
|
+
if (@available(macOS 10.14.1, *))
|
209
|
+
{
|
210
|
+
handle_gamepad_event(gamepad. leftThumbstickButton, KEY_GAMEPAD_THUMB_LEFT);
|
211
|
+
handle_gamepad_event(gamepad.rightThumbstickButton, KEY_GAMEPAD_THUMB_RIGHT);
|
212
|
+
}
|
213
|
+
|
214
|
+
if (@available(macOS 10.15, *))
|
215
|
+
{
|
216
|
+
handle_gamepad_event(gamepad.buttonMenu, KEY_GAMEPAD_MENU);
|
217
|
+
handle_gamepad_event(gamepad.buttonOptions, KEY_GAMEPAD_OPTION);
|
218
|
+
}
|
219
|
+
|
220
|
+
if (@available(macOS 11.0, *))
|
221
|
+
handle_gamepad_event(gamepad.buttonHome, KEY_GAMEPAD_HOME);
|
222
|
+
}
|
223
|
+
|
224
|
+
static id game_controllers_observer = nil;
|
225
|
+
|
226
|
+
void
|
227
|
+
init_game_controllers ()
|
228
|
+
{
|
229
|
+
for (GCController* c in GCController.controllers)
|
230
|
+
handle_gamepad_events(c);
|
231
|
+
|
232
|
+
game_controllers_observer = [NSNotificationCenter.defaultCenter
|
233
|
+
addObserverForName: GCControllerDidConnectNotification
|
234
|
+
object: nil
|
235
|
+
queue: NSOperationQueue.mainQueue
|
236
|
+
usingBlock: ^(NSNotification* n) {handle_gamepad_events(n.object);}];
|
237
|
+
}
|
238
|
+
|
239
|
+
void
|
240
|
+
fin_game_controllers ()
|
241
|
+
{
|
242
|
+
if (!game_controllers_observer) return;
|
243
|
+
|
244
|
+
[NSNotificationCenter.defaultCenter
|
245
|
+
removeObserver: game_controllers_observer];
|
246
|
+
}
|
247
|
+
|
248
|
+
|
164
249
|
};// Reflex
|
data/src/osx/native_window.mm
CHANGED
@@ -201,13 +201,7 @@ move_to_main_screen_origin (NativeWindow* window)
|
|
201
201
|
|
202
202
|
++update_count;
|
203
203
|
|
204
|
-
|
205
|
-
Reflex::UpdateEvent e(now, now - win->self->prev_time_update);
|
206
|
-
win->self->prev_time_update = now;
|
207
|
-
|
208
|
-
win->on_update(&e);
|
209
|
-
if (!e.is_blocked())
|
210
|
-
Reflex::View_update_tree(win->root(), e);
|
204
|
+
Window_call_update_event(win);
|
211
205
|
|
212
206
|
if (win->self->redraw)
|
213
207
|
{
|
data/src/osx/reflex.mm
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
#import <Cocoa/Cocoa.h>
|
6
6
|
#include "reflex/exception.h"
|
7
|
+
#include "event.h"
|
7
8
|
|
8
9
|
|
9
10
|
namespace Reflex
|
@@ -25,6 +26,8 @@ namespace Reflex
|
|
25
26
|
reflex_error(__FILE__, __LINE__, "already initialized.");
|
26
27
|
|
27
28
|
global::pool = [[NSAutoreleasePool alloc] init];
|
29
|
+
|
30
|
+
init_game_controllers();
|
28
31
|
}
|
29
32
|
|
30
33
|
void
|
@@ -33,6 +36,8 @@ namespace Reflex
|
|
33
36
|
if (!global::pool)
|
34
37
|
reflex_error(__FILE__, __LINE__, "not initialized.");
|
35
38
|
|
39
|
+
fin_game_controllers();
|
40
|
+
|
36
41
|
[global::pool release];
|
37
42
|
global::pool = nil;
|
38
43
|
}
|
data/src/view.cpp
CHANGED
@@ -39,23 +39,29 @@ namespace Reflex
|
|
39
39
|
enum Flag
|
40
40
|
{
|
41
41
|
|
42
|
-
|
42
|
+
UPDATING = Xot::bit(1, FLAG_LAST),
|
43
43
|
|
44
|
-
|
44
|
+
NO_SHAPE = Xot::bit(2, FLAG_LAST),
|
45
45
|
|
46
|
-
|
46
|
+
HAS_VARIABLE_LENGTHS = Xot::bit(3, FLAG_LAST),
|
47
47
|
|
48
|
-
|
48
|
+
HAS_CHILDREN_TO_REMOVE = Xot::bit(4, FLAG_LAST),
|
49
49
|
|
50
|
-
|
50
|
+
REMOVE_FROM_PARENT = Xot::bit(5, FLAG_LAST),
|
51
51
|
|
52
|
-
|
52
|
+
REDRAW = Xot::bit(6, FLAG_LAST),
|
53
53
|
|
54
|
-
|
54
|
+
APPLY_STYLE = Xot::bit(7, FLAG_LAST),
|
55
55
|
|
56
|
-
|
56
|
+
UPDATE_STYLE = Xot::bit(8, FLAG_LAST),
|
57
57
|
|
58
|
-
|
58
|
+
UPDATE_SHAPES = Xot::bit(9, FLAG_LAST),
|
59
|
+
|
60
|
+
UPDATE_LAYOUT = Xot::bit(10, FLAG_LAST),
|
61
|
+
|
62
|
+
SORT_CHILDREN = Xot::bit(11, FLAG_LAST),
|
63
|
+
|
64
|
+
FIT_TO_CONTENT = Xot::bit(12, FLAG_LAST),
|
59
65
|
|
60
66
|
};// Flag
|
61
67
|
|
@@ -235,6 +241,8 @@ namespace Reflex
|
|
235
241
|
}
|
236
242
|
else
|
237
243
|
pbody->set_transform(frame.x, frame.y, angle);
|
244
|
+
|
245
|
+
pbody->awake();
|
238
246
|
}
|
239
247
|
|
240
248
|
void update_body_states ()
|
@@ -1043,6 +1051,20 @@ namespace Reflex
|
|
1043
1051
|
}
|
1044
1052
|
}
|
1045
1053
|
|
1054
|
+
static void
|
1055
|
+
remove_children (View* view, View::ChildList* children)
|
1056
|
+
{
|
1057
|
+
assert(children);
|
1058
|
+
|
1059
|
+
int size = (int) children->size();
|
1060
|
+
for (int i = size - 1; i >= 0; --i)
|
1061
|
+
{
|
1062
|
+
View* child = (*children)[i].get();
|
1063
|
+
if (child->self->check_and_remove_flag(View::Data::REMOVE_FROM_PARENT))
|
1064
|
+
view->remove_child(child);
|
1065
|
+
}
|
1066
|
+
}
|
1067
|
+
|
1046
1068
|
void
|
1047
1069
|
View_update_tree (View* view, const UpdateEvent& event)
|
1048
1070
|
{
|
@@ -1051,13 +1073,16 @@ namespace Reflex
|
|
1051
1073
|
|
1052
1074
|
View::Data* self = view->self.get();
|
1053
1075
|
|
1076
|
+
self->add_flag(View::Data::UPDATING);
|
1077
|
+
|
1054
1078
|
fire_timers(view, event.now());
|
1055
1079
|
|
1056
1080
|
View::ChildList* children = self->children();
|
1057
1081
|
if (children)
|
1058
1082
|
{
|
1059
|
-
|
1060
|
-
|
1083
|
+
size_t size = children->size();
|
1084
|
+
for (size_t i = 0; i < size; ++i)
|
1085
|
+
View_update_tree((*children)[i].get(), event);
|
1061
1086
|
}
|
1062
1087
|
|
1063
1088
|
update_view_shapes(view);
|
@@ -1079,6 +1104,11 @@ namespace Reflex
|
|
1079
1104
|
|
1080
1105
|
if (self->check_and_remove_flag(View::Data::FIT_TO_CONTENT))
|
1081
1106
|
fit_view_to_content(view);
|
1107
|
+
|
1108
|
+
self->remove_flag(View::Data::UPDATING);
|
1109
|
+
|
1110
|
+
if (self->check_and_remove_flag(View::Data::HAS_CHILDREN_TO_REMOVE))
|
1111
|
+
remove_children(view, children);
|
1082
1112
|
}
|
1083
1113
|
|
1084
1114
|
static bool
|
@@ -1790,13 +1820,19 @@ namespace Reflex
|
|
1790
1820
|
else if (found != belong)
|
1791
1821
|
invalid_state_error(__FILE__, __LINE__);
|
1792
1822
|
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1823
|
+
if (self->has_flag(Data::UPDATING))
|
1824
|
+
{
|
1825
|
+
// delay removing child to avoid breaking child list looped on View_update_tree()
|
1826
|
+
self->add_flag(Data::HAS_CHILDREN_TO_REMOVE);
|
1827
|
+
child->self->add_flag(Data::REMOVE_FROM_PARENT);
|
1828
|
+
}
|
1829
|
+
else
|
1830
|
+
{
|
1831
|
+
set_parent(child, NULL);
|
1832
|
+
erase_child_from_children(this, child);
|
1833
|
+
self->sort_children();
|
1834
|
+
update_view_layout(this);
|
1835
|
+
}
|
1800
1836
|
}
|
1801
1837
|
|
1802
1838
|
void
|
@@ -2295,9 +2331,9 @@ namespace Reflex
|
|
2295
2331
|
bool capture = types != CAPTURE_NONE;
|
2296
2332
|
|
2297
2333
|
if (capture && !registered)
|
2298
|
-
Window_register_capture(w, this,
|
2334
|
+
Window_register_capture(w, this, CAPTURE_ALL_EVENTS);
|
2299
2335
|
else if (!capture && registered)
|
2300
|
-
Window_unregister_capture(w, this,
|
2336
|
+
Window_unregister_capture(w, this, CAPTURE_ALL_EVENTS);
|
2301
2337
|
|
2302
2338
|
CaptureEvent e(~old & types, old & ~types);
|
2303
2339
|
on_capture(&e);
|
data/src/win32/event.cpp
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
#include "event.h"
|
2
2
|
|
3
3
|
|
4
|
+
#include <xinput.h>
|
4
5
|
#include <xot/time.h>
|
5
6
|
#include "reflex/exception.h"
|
6
|
-
#include "
|
7
|
+
#include "reflex/debug.h"
|
8
|
+
#include "window.h"
|
7
9
|
|
8
10
|
|
9
11
|
namespace Reflex
|
@@ -216,4 +218,86 @@ namespace Reflex
|
|
216
218
|
}
|
217
219
|
|
218
220
|
|
221
|
+
static void
|
222
|
+
call_gamepad_event (Window* win, int code, bool pressed)
|
223
|
+
{
|
224
|
+
auto action = pressed ? KeyEvent::DOWN : KeyEvent::UP;
|
225
|
+
KeyEvent e(action, NULL, code, get_modifiers(), 0);
|
226
|
+
Window_call_key_event(win, &e);
|
227
|
+
}
|
228
|
+
|
229
|
+
static void
|
230
|
+
handle_gamepad_button_event (
|
231
|
+
Window* win, const XINPUT_STATE& state, const XINPUT_STATE& prev_state,
|
232
|
+
WORD mask, int code)
|
233
|
+
{
|
234
|
+
WORD pressed = state.Gamepad.wButtons & mask;
|
235
|
+
WORD prev = prev_state.Gamepad.wButtons & mask;
|
236
|
+
if (pressed == prev) return;
|
237
|
+
|
238
|
+
call_gamepad_event(win, code, pressed);
|
239
|
+
}
|
240
|
+
|
241
|
+
static void
|
242
|
+
handle_gamepad_trigger_event (Window* win, BYTE value, BYTE prev_value, int code)
|
243
|
+
{
|
244
|
+
WORD pressed = value > XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
|
245
|
+
WORD prev = prev_value > XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
|
246
|
+
if (pressed == prev) return;
|
247
|
+
|
248
|
+
call_gamepad_event(win, code, pressed);
|
249
|
+
}
|
250
|
+
|
251
|
+
static void
|
252
|
+
handle_gamepad_events (const XINPUT_STATE& state, const XINPUT_STATE& prev_state)
|
253
|
+
{
|
254
|
+
Window* win = Window_get_active();
|
255
|
+
if (!win) return;
|
256
|
+
|
257
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_DPAD_LEFT, KEY_GAMEPAD_LEFT);
|
258
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_DPAD_RIGHT, KEY_GAMEPAD_RIGHT);
|
259
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_DPAD_UP, KEY_GAMEPAD_UP);
|
260
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_DPAD_DOWN, KEY_GAMEPAD_DOWN);
|
261
|
+
|
262
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_A, KEY_GAMEPAD_A);
|
263
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_B, KEY_GAMEPAD_B);
|
264
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_X, KEY_GAMEPAD_X);
|
265
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_Y, KEY_GAMEPAD_Y);
|
266
|
+
|
267
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_LEFT_SHOULDER, KEY_GAMEPAD_SHOULDER_LEFT);
|
268
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_RIGHT_SHOULDER, KEY_GAMEPAD_SHOULDER_RIGHT);
|
269
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_LEFT_THUMB, KEY_GAMEPAD_THUMB_LEFT);
|
270
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_RIGHT_THUMB, KEY_GAMEPAD_THUMB_RIGHT);
|
271
|
+
|
272
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_START, KEY_GAMEPAD_START);
|
273
|
+
handle_gamepad_button_event(win, state, prev_state, XINPUT_GAMEPAD_BACK, KEY_GAMEPAD_SELECT);
|
274
|
+
|
275
|
+
handle_gamepad_trigger_event(win, state.Gamepad.bLeftTrigger, prev_state.Gamepad.bLeftTrigger, KEY_GAMEPAD_TRIGGER_LEFT);
|
276
|
+
handle_gamepad_trigger_event(win, state.Gamepad.bRightTrigger, prev_state.Gamepad.bRightTrigger, KEY_GAMEPAD_TRIGGER_RIGHT);
|
277
|
+
}
|
278
|
+
|
279
|
+
void
|
280
|
+
poll_gamepads ()
|
281
|
+
{
|
282
|
+
static XINPUT_STATE prev_state;
|
283
|
+
static bool prev_detected = false;
|
284
|
+
|
285
|
+
XINPUT_STATE state = {0};
|
286
|
+
bool detected = XInputGetState(0, &state) == ERROR_SUCCESS;
|
287
|
+
|
288
|
+
if (detected != prev_detected)
|
289
|
+
{
|
290
|
+
prev_detected = detected;
|
291
|
+
if (detected) prev_state = {0};
|
292
|
+
}
|
293
|
+
|
294
|
+
if (!detected) return;
|
295
|
+
|
296
|
+
if (state.dwPacketNumber != prev_state.dwPacketNumber)
|
297
|
+
handle_gamepad_events(state, prev_state);
|
298
|
+
|
299
|
+
prev_state = state;
|
300
|
+
}
|
301
|
+
|
302
|
+
|
219
303
|
}// Reflex
|
data/src/win32/event.h
CHANGED
data/src/win32/window.cpp
CHANGED
@@ -154,13 +154,9 @@ namespace Reflex
|
|
154
154
|
{
|
155
155
|
WindowData* self = get_data(win);
|
156
156
|
|
157
|
-
|
158
|
-
Reflex::UpdateEvent e(now, now - self->prev_time_update);
|
159
|
-
self->prev_time_update = now;
|
157
|
+
poll_gamepads();
|
160
158
|
|
161
|
-
win
|
162
|
-
if (!e.is_blocked())
|
163
|
-
Reflex::View_update_tree(win->root(), e);
|
159
|
+
Window_call_update_event(win);
|
164
160
|
|
165
161
|
if (self->redraw)
|
166
162
|
{
|
@@ -347,8 +343,13 @@ namespace Reflex
|
|
347
343
|
{
|
348
344
|
case WM_ACTIVATE:
|
349
345
|
{
|
350
|
-
if ((wp
|
346
|
+
if (LOWORD(wp) == WA_INACTIVE)
|
347
|
+
{
|
348
|
+
Window_call_deactivate_event(win);
|
351
349
|
self->pressing_keys.clear();
|
350
|
+
}
|
351
|
+
else
|
352
|
+
Window_call_activate_event(win);
|
352
353
|
break;
|
353
354
|
}
|
354
355
|
|
data/src/window.cpp
CHANGED
@@ -52,6 +52,17 @@ namespace Reflex
|
|
52
52
|
return windows;
|
53
53
|
}
|
54
54
|
|
55
|
+
Window*
|
56
|
+
Window_get_active ()
|
57
|
+
{
|
58
|
+
for (auto& w : Window_all())
|
59
|
+
{
|
60
|
+
if (Xot::has_flag(w->self->flags, Window::Data::ACTIVE))
|
61
|
+
return w;
|
62
|
+
}
|
63
|
+
return NULL;
|
64
|
+
}
|
65
|
+
|
55
66
|
|
56
67
|
Window::Data::Data ()
|
57
68
|
: flags(Window_default_flags())
|
@@ -129,7 +140,7 @@ namespace Reflex
|
|
129
140
|
return;
|
130
141
|
|
131
142
|
targets.insert(
|
132
|
-
target ==
|
143
|
+
target == CAPTURE_ALL_EVENTS ? targets.begin() : targets.end(),
|
133
144
|
target);
|
134
145
|
}
|
135
146
|
|
@@ -163,21 +174,40 @@ namespace Reflex
|
|
163
174
|
}
|
164
175
|
|
165
176
|
void
|
166
|
-
Window_call_activate_event (
|
177
|
+
Window_call_activate_event (Window* window)
|
167
178
|
{
|
168
179
|
if (!window) return;
|
169
180
|
|
170
|
-
|
181
|
+
Xot::add_flag(&window->self->flags, Window::Data::ACTIVE);
|
182
|
+
|
183
|
+
Event e;
|
171
184
|
window->on_activate(&e);
|
172
185
|
}
|
173
186
|
|
174
187
|
void
|
175
|
-
Window_call_deactivate_event (
|
188
|
+
Window_call_deactivate_event (Window* window)
|
176
189
|
{
|
177
190
|
if (!window) return;
|
178
191
|
|
179
|
-
|
192
|
+
Event e;
|
180
193
|
window->on_deactivate(&e);
|
194
|
+
|
195
|
+
Xot::remove_flag(&window->self->flags, Window::Data::ACTIVE);
|
196
|
+
}
|
197
|
+
|
198
|
+
void
|
199
|
+
Window_call_update_event (Window* window)
|
200
|
+
{
|
201
|
+
Window::Data* self = window->self.get();
|
202
|
+
|
203
|
+
double now = Xot::time();
|
204
|
+
UpdateEvent e(now, now - self->prev_time_update);
|
205
|
+
self->prev_time_update = now;
|
206
|
+
|
207
|
+
window->on_update(&e);
|
208
|
+
if (e.is_blocked()) return;
|
209
|
+
|
210
|
+
View_update_tree(window->root(), e);
|
181
211
|
}
|
182
212
|
|
183
213
|
void
|
@@ -203,19 +233,19 @@ namespace Reflex
|
|
203
233
|
|
204
234
|
window->on_draw(event);
|
205
235
|
if (!event->is_blocked())
|
206
|
-
|
236
|
+
View_draw_tree(window->root(), event, 0, frame.move_to(0));
|
207
237
|
|
208
238
|
painter->pop_state();
|
209
239
|
painter->end();
|
210
240
|
}
|
211
241
|
|
212
242
|
static bool
|
213
|
-
|
243
|
+
is_capturing (
|
214
244
|
const View* view, const CaptureTargetIDList& targets, View::Capture type)
|
215
245
|
{
|
216
246
|
return
|
217
247
|
!targets.empty() &&
|
218
|
-
targets[0] ==
|
248
|
+
targets[0] == CAPTURE_ALL_EVENTS &&
|
219
249
|
(view->capture() & type) == type;
|
220
250
|
}
|
221
251
|
|
@@ -227,20 +257,11 @@ namespace Reflex
|
|
227
257
|
if (!event)
|
228
258
|
argument_error(__FILE__, __LINE__);
|
229
259
|
|
230
|
-
window->on_key(event);
|
231
|
-
|
232
|
-
switch (event->action())
|
233
|
-
{
|
234
|
-
case KeyEvent::DOWN: window->on_key_down(event); break;
|
235
|
-
case KeyEvent::UP: window->on_key_up(event); break;
|
236
|
-
default: break;
|
237
|
-
}
|
238
|
-
|
239
260
|
for (auto& [view, targets] : window->self->captures)
|
240
261
|
{
|
241
262
|
if (
|
242
263
|
!view->window() ||
|
243
|
-
!
|
264
|
+
!is_capturing(view.get(), targets, View::CAPTURE_KEY))
|
244
265
|
{
|
245
266
|
continue;
|
246
267
|
}
|
@@ -248,9 +269,24 @@ namespace Reflex
|
|
248
269
|
KeyEvent e = event->dup();
|
249
270
|
KeyEvent_set_captured(&e, true);
|
250
271
|
View_call_key_event(const_cast<View*>(view.get()), &e);
|
272
|
+
|
273
|
+
if (e.is_blocked()) event->block();
|
274
|
+
}
|
275
|
+
|
276
|
+
if (!event->is_blocked())
|
277
|
+
window->on_key(event);
|
278
|
+
|
279
|
+
if (!event->is_blocked())
|
280
|
+
{
|
281
|
+
switch (event->action())
|
282
|
+
{
|
283
|
+
case KeyEvent::DOWN: window->on_key_down(event); break;
|
284
|
+
case KeyEvent::UP: window->on_key_up(event); break;
|
285
|
+
default: break;
|
286
|
+
}
|
251
287
|
}
|
252
288
|
|
253
|
-
if (window->self->focus)
|
289
|
+
if (!event->is_blocked() && window->self->focus)
|
254
290
|
View_call_key_event(window->self->focus.get(), event);
|
255
291
|
|
256
292
|
cleanup_captures(window);
|
@@ -367,7 +403,7 @@ namespace Reflex
|
|
367
403
|
result->clear();
|
368
404
|
for (const auto& [view, targets] : window->self->captures)
|
369
405
|
{
|
370
|
-
if (
|
406
|
+
if (is_capturing(view.get(), targets, View::CAPTURE_POINTER))
|
371
407
|
result->emplace_back(view);
|
372
408
|
}
|
373
409
|
}
|
@@ -416,7 +452,7 @@ namespace Reflex
|
|
416
452
|
|
417
453
|
static void
|
418
454
|
capture_targeted_pointers_and_call_events (
|
419
|
-
ExtractedPointerIDSet* extracteds,
|
455
|
+
ExtractedPointerIDSet* extracteds, bool* blocked,
|
420
456
|
Window* window, const PointerMap& pointers)
|
421
457
|
{
|
422
458
|
for (auto& [view, targets] : window->self->captures)
|
@@ -430,6 +466,8 @@ namespace Reflex
|
|
430
466
|
|
431
467
|
PointerEvent_update_for_capturing_view(&event, view);
|
432
468
|
View_call_pointer_event(const_cast<View*>(view.get()), &event);
|
469
|
+
|
470
|
+
if (event.is_blocked()) *blocked = true;
|
433
471
|
}
|
434
472
|
}
|
435
473
|
|
@@ -451,7 +489,7 @@ namespace Reflex
|
|
451
489
|
|
452
490
|
static void
|
453
491
|
capture_hovering_pointers_and_call_events (
|
454
|
-
ExtractedPointerIDSet* extracteds,
|
492
|
+
ExtractedPointerIDSet* extracteds, bool* blocked,
|
455
493
|
const ViewList& views_capturing_all, const PointerMap& pointers)
|
456
494
|
{
|
457
495
|
assert(extracteds);
|
@@ -470,6 +508,8 @@ namespace Reflex
|
|
470
508
|
PointerEvent e = event.dup();
|
471
509
|
PointerEvent_update_for_capturing_view(&e, view);
|
472
510
|
View_call_pointer_event(const_cast<View*>(view.get()), &e);
|
511
|
+
|
512
|
+
if (e.is_blocked()) *blocked = true;
|
473
513
|
}
|
474
514
|
}
|
475
515
|
|
@@ -512,11 +552,17 @@ namespace Reflex
|
|
512
552
|
});
|
513
553
|
|
514
554
|
ExtractedPointerIDSet extracteds;
|
515
|
-
|
555
|
+
bool blocked = false;
|
556
|
+
|
557
|
+
capture_targeted_pointers_and_call_events(
|
558
|
+
&extracteds, &blocked, window, pointers);
|
516
559
|
erase_extracted_pointers(&pointers, extracteds);
|
517
560
|
|
518
|
-
capture_hovering_pointers_and_call_events(
|
561
|
+
capture_hovering_pointers_and_call_events(
|
562
|
+
&extracteds, &blocked, views_capturing_all, pointers);
|
519
563
|
erase_extracted_pointers(event, extracteds);
|
564
|
+
|
565
|
+
if (blocked) event->block();
|
520
566
|
}
|
521
567
|
|
522
568
|
void
|
@@ -529,20 +575,24 @@ namespace Reflex
|
|
529
575
|
|
530
576
|
setup_pointer_event(window, event);
|
531
577
|
|
532
|
-
window
|
578
|
+
call_captured_pointer_events(window, event);
|
579
|
+
|
580
|
+
if (!event->is_blocked() && !event->empty())
|
581
|
+
window->on_pointer(event);
|
533
582
|
|
534
|
-
|
583
|
+
if (!event->is_blocked() && !event->empty())
|
535
584
|
{
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
585
|
+
switch ((*event)[0].action())
|
586
|
+
{
|
587
|
+
case Pointer::DOWN: window->on_pointer_down(event); break;
|
588
|
+
case Pointer::UP: window->on_pointer_up(event); break;
|
589
|
+
case Pointer::MOVE: window->on_pointer_move(event); break;
|
590
|
+
case Pointer::CANCEL: window->on_pointer_cancel(event); break;
|
591
|
+
default: break;
|
592
|
+
}
|
541
593
|
}
|
542
594
|
|
543
|
-
|
544
|
-
|
545
|
-
if (!event->empty())
|
595
|
+
if (!event->is_blocked() && !event->empty())
|
546
596
|
{
|
547
597
|
PointerEvent_update_for_child_view(event, window->root());
|
548
598
|
View_call_pointer_event(window->root(), event);
|