Mercurial > hg > orthanc-stone
comparison OrthancStone/Sources/Deprecated/GuiAdapter.cpp @ 1512:244ad1e4e76a
reorganization of folders
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 07 Jul 2020 16:21:02 +0200 |
parents | Framework/Deprecated/GuiAdapter.cpp@e5729dab3f67 |
children |
comparison
equal
deleted
inserted
replaced
1511:9dfeee74c1e6 | 1512:244ad1e4e76a |
---|---|
1 /** | |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 #include "GuiAdapter.h" | |
22 | |
23 #if ORTHANC_ENABLE_OPENGL == 1 | |
24 # include "../OpenGL/OpenGLIncludes.h" | |
25 #endif | |
26 | |
27 #if ORTHANC_ENABLE_SDL == 1 | |
28 # include <SDL_video.h> | |
29 # include <SDL_render.h> | |
30 # include <SDL.h> | |
31 #endif | |
32 | |
33 #include <Compatibility.h> | |
34 | |
35 namespace OrthancStone | |
36 { | |
37 std::ostream& operator<<( | |
38 std::ostream& os, const GuiAdapterKeyboardEvent& event) | |
39 { | |
40 os << "sym: " << event.sym << " (" << (int)(event.sym[0]) << ") ctrl: " << event.ctrlKey << ", " << | |
41 "shift: " << event.shiftKey << ", " << | |
42 "alt: " << event.altKey; | |
43 return os; | |
44 } | |
45 | |
46 std::ostream& operator<<( | |
47 std::ostream& os, const GuiAdapterMouseEvent& event) | |
48 { | |
49 os << "targetX: " << event.targetX << " targetY: " << event.targetY << " button: " << event.button | |
50 << "ctrlKey: " << event.ctrlKey << "shiftKey: " << event.shiftKey << "altKey: " << event.altKey; | |
51 | |
52 return os; | |
53 } | |
54 | |
55 int GuiAdapter::s_instanceCount = 0; | |
56 | |
57 #if ORTHANC_ENABLE_WASM == 1 | |
58 void GuiAdapter::Run(GuiAdapterRunFunc /*func*/, void* /*cookie*/) | |
59 { | |
60 } | |
61 | |
62 void ConvertFromPlatform( | |
63 GuiAdapterUiEvent& dest, | |
64 int eventType, | |
65 const EmscriptenUiEvent& src) | |
66 { | |
67 // no data for now | |
68 } | |
69 | |
70 void ConvertFromPlatform( | |
71 GuiAdapterMouseEvent& dest, | |
72 int eventType, | |
73 const EmscriptenMouseEvent& src) | |
74 { | |
75 memset(&dest, 0, sizeof(GuiAdapterMouseEvent)); | |
76 switch (eventType) | |
77 { | |
78 case EMSCRIPTEN_EVENT_CLICK: | |
79 LOG(ERROR) << "Emscripten EMSCRIPTEN_EVENT_CLICK is not supported"; | |
80 ORTHANC_ASSERT(false, "Not supported"); | |
81 break; | |
82 case EMSCRIPTEN_EVENT_MOUSEDOWN: | |
83 dest.type = GUIADAPTER_EVENT_MOUSEDOWN; | |
84 break; | |
85 case EMSCRIPTEN_EVENT_DBLCLICK: | |
86 dest.type = GUIADAPTER_EVENT_MOUSEDBLCLICK; | |
87 break; | |
88 case EMSCRIPTEN_EVENT_MOUSEMOVE: | |
89 dest.type = GUIADAPTER_EVENT_MOUSEMOVE; | |
90 break; | |
91 case EMSCRIPTEN_EVENT_MOUSEUP: | |
92 dest.type = GUIADAPTER_EVENT_MOUSEUP; | |
93 break; | |
94 case EMSCRIPTEN_EVENT_WHEEL: | |
95 dest.type = GUIADAPTER_EVENT_WHEEL; | |
96 break; | |
97 | |
98 default: | |
99 LOG(ERROR) << "Emscripten event: " << eventType << " is not supported"; | |
100 ORTHANC_ASSERT(false, "Not supported"); | |
101 } | |
102 //dest.timestamp = src.timestamp; | |
103 //dest.screenX = src.screenX; | |
104 //dest.screenY = src.screenY; | |
105 //dest.clientX = src.clientX; | |
106 //dest.clientY = src.clientY; | |
107 dest.ctrlKey = src.ctrlKey; | |
108 dest.shiftKey = src.shiftKey; | |
109 dest.altKey = src.altKey; | |
110 //dest.metaKey = src.metaKey; | |
111 dest.button = src.button; | |
112 //dest.buttons = src.buttons; | |
113 //dest.movementX = src.movementX; | |
114 //dest.movementY = src.movementY; | |
115 dest.targetX = src.targetX; | |
116 dest.targetY = src.targetY; | |
117 //dest.canvasX = src.canvasX; | |
118 //dest.canvasY = src.canvasY; | |
119 //dest.padding = src.padding; | |
120 } | |
121 | |
122 void ConvertFromPlatform( GuiAdapterWheelEvent& dest, int eventType, const EmscriptenWheelEvent& src) | |
123 { | |
124 ConvertFromPlatform(dest.mouse, eventType, src.mouse); | |
125 dest.deltaX = src.deltaX; | |
126 dest.deltaY = src.deltaY; | |
127 switch (src.deltaMode) | |
128 { | |
129 case DOM_DELTA_PIXEL: | |
130 dest.deltaMode = GUIADAPTER_DELTA_PIXEL; | |
131 break; | |
132 case DOM_DELTA_LINE: | |
133 dest.deltaMode = GUIADAPTER_DELTA_LINE; | |
134 break; | |
135 case DOM_DELTA_PAGE: | |
136 dest.deltaMode = GUIADAPTER_DELTA_PAGE; | |
137 break; | |
138 default: | |
139 ORTHANC_ASSERT(false, "Unknown deltaMode: " << src.deltaMode << | |
140 " in wheel event..."); | |
141 } | |
142 dest.deltaMode = src.deltaMode; | |
143 } | |
144 | |
145 void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const EmscriptenKeyboardEvent& src) | |
146 { | |
147 dest.sym[0] = src.key[0]; | |
148 dest.sym[1] = 0; | |
149 dest.ctrlKey = src.ctrlKey; | |
150 dest.shiftKey = src.shiftKey; | |
151 dest.altKey = src.altKey; | |
152 } | |
153 | |
154 template<typename GenericFunc> | |
155 struct FuncAdapterPayload | |
156 { | |
157 std::string canvasCssSelector; | |
158 void* userData; | |
159 GenericFunc callback; | |
160 }; | |
161 | |
162 template<typename GenericFunc, | |
163 typename GuiAdapterEvent, | |
164 typename EmscriptenEvent> | |
165 EM_BOOL OnEventAdapterFunc( | |
166 int eventType, const EmscriptenEvent* emEvent, void* userData) | |
167 { | |
168 // userData is OnMouseWheelFuncAdapterPayload | |
169 FuncAdapterPayload<GenericFunc>* payload = | |
170 reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData); | |
171 // LOG(INFO) << "OnEventAdapterFunc"; | |
172 // LOG(INFO) << "------------------"; | |
173 // LOG(INFO) << "eventType: " << eventType << " wheelEvent: " << | |
174 // (int)wheelEvent << " userData: " << userData << | |
175 // " payload->userData: " << payload->userData; | |
176 | |
177 GuiAdapterEvent guiEvent; | |
178 ConvertFromPlatform(guiEvent, eventType, *emEvent); | |
179 bool ret = (*(payload->callback))(payload->canvasCssSelector, &guiEvent, payload->userData); | |
180 return static_cast<EM_BOOL>(ret); | |
181 } | |
182 | |
183 template<typename GenericFunc, | |
184 typename GuiAdapterEvent, | |
185 typename EmscriptenEvent> | |
186 EM_BOOL OnEventAdapterFunc2( | |
187 int /*eventType*/, const EmscriptenEvent* wheelEvent, void* userData) | |
188 { | |
189 // userData is OnMouseWheelFuncAdapterPayload | |
190 FuncAdapterPayload<GenericFunc>* payload = | |
191 reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData); | |
192 | |
193 GuiAdapterEvent guiEvent; | |
194 ConvertFromPlatform(guiEvent, *wheelEvent); | |
195 bool ret = (*(payload->callback))(payload->canvasCssSelector, &guiEvent, payload->userData); | |
196 return static_cast<EM_BOOL>(ret); | |
197 } | |
198 | |
199 template<typename GenericFunc> | |
200 EM_BOOL OnEventAdapterFunc3( | |
201 double time, void* userData) | |
202 { | |
203 // userData is OnMouseWheelFuncAdapterPayload | |
204 FuncAdapterPayload<GenericFunc>* payload = | |
205 reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData); | |
206 //std::unique_ptr< FuncAdapterPayload<GenericFunc> > deleter(payload); | |
207 bool ret = (*(payload->callback))(time, payload->userData); | |
208 return static_cast<EM_BOOL>(ret); | |
209 } | |
210 | |
211 /* | |
212 | |
213 Explanation | |
214 =========== | |
215 | |
216 - in "older" Emscripten, where DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR doesn't exist or is set to 0, | |
217 the following strings need to be used to register events: | |
218 - for canvas, the canvas DOM id. In case of <canvas id="mycanvas1" width='640' ...></canvas>", the string needs | |
219 to be "mycanvas" | |
220 - for the window (for key events), the string needs to be "#window" | |
221 - in newer Emscripten where DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR==1 (or maybe is not there anymore, in the | |
222 future as of 2020-04-20) | |
223 - for canvas, the canvas DOM id. In case of <canvas id="mycanvas1" width='640' ...></canvas>", the string needs | |
224 to be "#mycanvas" (notice the "number sign", aka "hash", NOT AKA "sharp", as can be read on https://en.wikipedia.org/wiki/Number_sign) | |
225 - for the window (for key events), the string needs to be EMSCRIPTEN_EVENT_TARGET_WINDOW. I do not mean | |
226 "EMSCRIPTEN_EVENT_TARGET_WINDOW", but the #define EMSCRIPTEN_EVENT_TARGET_WINDOW ((const char*)2) that | |
227 can be found in emscripten/html5.h | |
228 | |
229 The code below converts the input canvasId (as in the old emscripten) to the emscripten-compliant one, with the | |
230 following compile condition : #if DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR == 1 | |
231 | |
232 If the DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR build parameter disappears, you might want to refactor this code | |
233 or continue to pass the DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR compile macro (which is different from the CMake | |
234 variable) | |
235 | |
236 What we are doing below: | |
237 - in older Emscripten, the registration functions will receive "mycanvas" and "#window" and the callbacks will receive | |
238 the same std::string in their payload ("mycanvas" and "#window") | |
239 | |
240 - in newer Emscripten, the registration functions will receive "#mycanvas" and EMSCRIPTEN_EVENT_TARGET_WINDOW, but | |
241 the callbacks will receive "#mycanvas" and "#window" (since it is not possible to store the EMSCRIPTEN_EVENT_TARGET_WINDOW | |
242 magic value in an std::string, while we still want the callback to be able to change its behavior according to the | |
243 target element. | |
244 | |
245 */ | |
246 | |
247 void convertElementTarget(const char*& outCanvasCssSelectorSz, std::string& outCanvasCssSelector, const std::string& canvasId) | |
248 { | |
249 // only "#window" can start with a # | |
250 if (canvasId[0] == '#') | |
251 { | |
252 ORTHANC_ASSERT(canvasId == "#window"); | |
253 } | |
254 #if DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR == 1 | |
255 if (canvasId == "#window") | |
256 { | |
257 // we store this in the payload so that the callback can | |
258 outCanvasCssSelector = "#window"; | |
259 outCanvasCssSelectorSz = EMSCRIPTEN_EVENT_TARGET_WINDOW; | |
260 } | |
261 else | |
262 { | |
263 outCanvasCssSelector = "#" + canvasId; | |
264 outCanvasCssSelectorSz = outCanvasCssSelector.c_str(); | |
265 } | |
266 #else | |
267 if (canvasId == "#window") | |
268 { | |
269 // we store this in the payload so that the callback can | |
270 outCanvasCssSelector = "#window"; | |
271 outCanvasCssSelectorSz = outCanvasCssSelector.c_str();; | |
272 } | |
273 else | |
274 { | |
275 outCanvasCssSelector = canvasId; | |
276 outCanvasCssSelectorSz = outCanvasCssSelector.c_str();; | |
277 } | |
278 #endif | |
279 } | |
280 | |
281 // resize: (const char* target, void* userData, EM_BOOL useCapture, em_ui_callback_func callback) | |
282 template< | |
283 typename GenericFunc, | |
284 typename GuiAdapterEvent, | |
285 typename EmscriptenEvent, | |
286 typename EmscriptenSetCallbackFunc> | |
287 static void SetCallback( | |
288 EmscriptenSetCallbackFunc emFunc, | |
289 std::string canvasId, void* userData, bool capture, GenericFunc func) | |
290 { | |
291 std::string canvasCssSelector; | |
292 const char* canvasCssSelectorSz = NULL; | |
293 convertElementTarget(canvasCssSelectorSz, canvasCssSelector, canvasId); | |
294 | |
295 // TODO: write RemoveCallback with an int id that gets returned from here | |
296 | |
297 // create userdata payload | |
298 std::unique_ptr<FuncAdapterPayload<GenericFunc> > payload(new FuncAdapterPayload<GenericFunc>()); | |
299 payload->canvasCssSelector = canvasCssSelector; | |
300 payload->callback = func; | |
301 payload->userData = userData; | |
302 void* userDataRaw = reinterpret_cast<void*>(payload.release()); | |
303 | |
304 // call the registration function | |
305 (*emFunc)( | |
306 canvasCssSelectorSz, | |
307 userDataRaw, | |
308 static_cast<EM_BOOL>(capture), | |
309 &OnEventAdapterFunc<GenericFunc, GuiAdapterEvent, EmscriptenEvent>, | |
310 EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD); | |
311 } | |
312 | |
313 template< | |
314 typename GenericFunc, | |
315 typename GuiAdapterEvent, | |
316 typename EmscriptenEvent, | |
317 typename EmscriptenSetCallbackFunc> | |
318 static void SetCallback2( | |
319 EmscriptenSetCallbackFunc emFunc, | |
320 std::string canvasId, void* userData, bool capture, GenericFunc func) | |
321 { | |
322 std::string canvasCssSelector; | |
323 const char* canvasCssSelectorSz = NULL; | |
324 convertElementTarget(canvasCssSelectorSz, canvasCssSelector, canvasId); | |
325 | |
326 // TODO: write RemoveCallback with an int id that gets returned from here | |
327 | |
328 // create userdata payload | |
329 std::unique_ptr<FuncAdapterPayload<GenericFunc> > payload(new FuncAdapterPayload<GenericFunc>()); | |
330 payload->canvasCssSelector = canvasCssSelector; | |
331 payload->callback = func; | |
332 payload->userData = userData; | |
333 void* userDataRaw = reinterpret_cast<void*>(payload.release()); | |
334 | |
335 // call the registration function | |
336 (*emFunc)( | |
337 canvasCssSelectorSz, | |
338 userDataRaw, | |
339 static_cast<EM_BOOL>(capture), | |
340 &OnEventAdapterFunc2<GenericFunc, GuiAdapterEvent, EmscriptenEvent>, | |
341 EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD); | |
342 } | |
343 | |
344 template< | |
345 typename GenericFunc, | |
346 typename EmscriptenSetCallbackFunc> | |
347 static void SetAnimationFrameCallback( | |
348 EmscriptenSetCallbackFunc emFunc, | |
349 void* userData, GenericFunc func) | |
350 { | |
351 std::unique_ptr<FuncAdapterPayload<GenericFunc> > payload( | |
352 new FuncAdapterPayload<GenericFunc>() | |
353 ); | |
354 payload->canvasCssSelector = "UNDEFINED"; | |
355 payload->callback = func; | |
356 payload->userData = userData; | |
357 void* userDataRaw = reinterpret_cast<void*>(payload.release()); | |
358 (*emFunc)( | |
359 &OnEventAdapterFunc3<GenericFunc>, | |
360 userDataRaw); | |
361 } | |
362 | |
363 void GuiAdapter::SetWheelCallback( | |
364 std::string canvasId, void* userData, bool capture, OnMouseWheelFunc func) | |
365 { | |
366 SetCallback<OnMouseWheelFunc, GuiAdapterWheelEvent, EmscriptenWheelEvent>( | |
367 &emscripten_set_wheel_callback_on_thread, | |
368 canvasId, | |
369 userData, | |
370 capture, | |
371 func); | |
372 } | |
373 | |
374 | |
375 void GuiAdapter::SetMouseDblClickCallback( | |
376 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) | |
377 { | |
378 SetCallback<OnMouseEventFunc, GuiAdapterMouseEvent, EmscriptenMouseEvent>( | |
379 &emscripten_set_dblclick_callback_on_thread, | |
380 canvasId, | |
381 userData, | |
382 capture, | |
383 func); | |
384 } | |
385 | |
386 | |
387 void GuiAdapter::SetMouseDownCallback( | |
388 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) | |
389 { | |
390 SetCallback<OnMouseEventFunc, GuiAdapterMouseEvent, EmscriptenMouseEvent>( | |
391 &emscripten_set_mousedown_callback_on_thread, | |
392 canvasId, | |
393 userData, | |
394 capture, | |
395 func); | |
396 } | |
397 | |
398 void GuiAdapter::SetMouseMoveCallback( | |
399 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) | |
400 { | |
401 // LOG(INFO) << "SetMouseMoveCallback -- " << "supplied userData: " << | |
402 // userData; | |
403 | |
404 SetCallback<OnMouseEventFunc, GuiAdapterMouseEvent, EmscriptenMouseEvent>( | |
405 &emscripten_set_mousemove_callback_on_thread, | |
406 canvasId, | |
407 userData, | |
408 capture, | |
409 func); | |
410 } | |
411 | |
412 void GuiAdapter::SetMouseUpCallback( | |
413 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) | |
414 { | |
415 SetCallback<OnMouseEventFunc, GuiAdapterMouseEvent, EmscriptenMouseEvent>( | |
416 &emscripten_set_mouseup_callback_on_thread, | |
417 canvasId, | |
418 userData, | |
419 capture, | |
420 func); | |
421 } | |
422 | |
423 void GuiAdapter::SetKeyDownCallback( | |
424 std::string canvasId, void* userData, bool capture, OnKeyDownFunc func) | |
425 { | |
426 SetCallback2<OnKeyDownFunc, GuiAdapterKeyboardEvent, EmscriptenKeyboardEvent>( | |
427 &emscripten_set_keydown_callback_on_thread, | |
428 canvasId, | |
429 userData, | |
430 capture, | |
431 func); | |
432 } | |
433 | |
434 void GuiAdapter::SetKeyUpCallback( | |
435 std::string canvasId, void* userData, bool capture, OnKeyUpFunc func) | |
436 { | |
437 SetCallback2<OnKeyUpFunc, GuiAdapterKeyboardEvent, EmscriptenKeyboardEvent>( | |
438 &emscripten_set_keyup_callback_on_thread, | |
439 canvasId, | |
440 userData, | |
441 capture, | |
442 func); | |
443 } | |
444 | |
445 #if 0 | |
446 // useless under Wasm where canvas resize is handled automatically | |
447 void GuiAdapter::SetResizeCallback( | |
448 std::string canvasId, void* userData, bool capture, OnWindowResizeFunc func) | |
449 { | |
450 SetCallback<OnWindowResizeFunc, GuiAdapterUiEvent, EmscriptenUiEvent>( | |
451 &emscripten_set_resize_callback_on_thread, | |
452 canvasId, | |
453 userData, | |
454 capture, | |
455 func); | |
456 } | |
457 #endif | |
458 | |
459 void GuiAdapter::RequestAnimationFrame( | |
460 OnAnimationFrameFunc func, void* userData) | |
461 { | |
462 SetAnimationFrameCallback<OnAnimationFrameFunc>( | |
463 &emscripten_request_animation_frame_loop, | |
464 userData, | |
465 func); | |
466 } | |
467 | |
468 #if 0 | |
469 void GuiAdapter::SetKeyDownCallback( | |
470 std::string canvasId, void* userData, bool capture, OnKeyDownFunc func) | |
471 { | |
472 emscripten_set_keydown_callback(canvasId.c_str(), userData, static_cast<EM_BOOL>(capture), func); | |
473 } | |
474 void GuiAdapter::SetKeyUpCallback( | |
475 std::string canvasId, void* userData, bool capture, OnKeyUpFunc func) | |
476 { | |
477 emscripten_set_keyup_callback(canvasId.c_str(), userData, static_cast<EM_BOOL>(capture), func); | |
478 } | |
479 | |
480 // handled from within WebAssemblyViewport | |
481 //void GuiAdapter::SetResizeCallback(std::string canvasId, void* userData, bool capture, OnWindowResizeFunc func) | |
482 //{ | |
483 // emscripten_set_resize_callback(canvasId.c_str(), userData, static_cast<EM_BOOL>(capture), func); | |
484 //} | |
485 | |
486 void GuiAdapter::RequestAnimationFrame(OnAnimationFrameFunc func, void* userData) | |
487 { | |
488 emscripten_request_animation_frame_loop(func, userData); | |
489 } | |
490 #endif | |
491 | |
492 | |
493 #else | |
494 | |
495 // SDL ONLY | |
496 void ConvertFromPlatform(GuiAdapterMouseEvent& dest, bool ctrlPressed, bool shiftPressed, bool altPressed, const SDL_Event& source) | |
497 { | |
498 memset(&dest, 0, sizeof(GuiAdapterMouseEvent)); | |
499 switch (source.type) | |
500 { | |
501 case SDL_MOUSEBUTTONDOWN: | |
502 if (source.button.clicks == 1) { | |
503 dest.type = GUIADAPTER_EVENT_MOUSEDOWN; | |
504 } else if (source.button.clicks == 2) { | |
505 dest.type = GUIADAPTER_EVENT_MOUSEDBLCLICK; | |
506 } else { | |
507 dest.type = GUIADAPTER_EVENT_MOUSEDBLCLICK; | |
508 LOG(WARNING) << "Multiple-click ignored."; | |
509 } | |
510 break; | |
511 case SDL_MOUSEMOTION: | |
512 dest.type = GUIADAPTER_EVENT_MOUSEMOVE; | |
513 break; | |
514 case SDL_MOUSEBUTTONUP: | |
515 dest.type = GUIADAPTER_EVENT_MOUSEUP; | |
516 break; | |
517 case SDL_MOUSEWHEEL: | |
518 dest.type = GUIADAPTER_EVENT_WHEEL; | |
519 break; | |
520 default: | |
521 LOG(ERROR) << "SDL event: " << source.type << " is not supported"; | |
522 ORTHANC_ASSERT(false, "Not supported"); | |
523 } | |
524 //dest.timestamp = src.timestamp; | |
525 //dest.screenX = src.screenX; | |
526 //dest.screenY = src.screenY; | |
527 //dest.clientX = src.clientX; | |
528 //dest.clientY = src.clientY; | |
529 dest.ctrlKey = ctrlPressed; | |
530 dest.shiftKey = shiftPressed; | |
531 dest.altKey = altPressed; | |
532 //dest.metaKey = src.metaKey; | |
533 switch (source.button.button) | |
534 { | |
535 case SDL_BUTTON_MIDDLE: | |
536 dest.button =GUIADAPTER_MOUSEBUTTON_MIDDLE; | |
537 break; | |
538 | |
539 case SDL_BUTTON_RIGHT: | |
540 dest.button = GUIADAPTER_MOUSEBUTTON_RIGHT; | |
541 break; | |
542 | |
543 case SDL_BUTTON_LEFT: | |
544 dest.button = GUIADAPTER_MOUSEBUTTON_LEFT; | |
545 break; | |
546 | |
547 default: | |
548 break; | |
549 } | |
550 //dest.buttons = src.buttons; | |
551 //dest.movementX = src.movementX; | |
552 //dest.movementY = src.movementY; | |
553 dest.targetX = source.button.x; | |
554 dest.targetY = source.button.y; | |
555 //dest.canvasX = src.canvasX; | |
556 //dest.canvasY = src.canvasY; | |
557 //dest.padding = src.padding; | |
558 } | |
559 | |
560 void ConvertFromPlatform( | |
561 GuiAdapterWheelEvent& dest, | |
562 bool ctrlPressed, bool shiftPressed, bool altPressed, | |
563 const SDL_Event& source) | |
564 { | |
565 ConvertFromPlatform(dest.mouse, ctrlPressed, shiftPressed, altPressed, source); | |
566 dest.deltaX = source.wheel.x; | |
567 dest.deltaY = source.wheel.y; | |
568 } | |
569 | |
570 void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const SDL_Event& src) | |
571 { | |
572 memset(&dest, 0, sizeof(GuiAdapterMouseEvent)); | |
573 switch (src.type) | |
574 { | |
575 case SDL_KEYDOWN: | |
576 dest.type = GUIADAPTER_EVENT_KEYDOWN; | |
577 break; | |
578 case SDL_KEYUP: | |
579 dest.type = GUIADAPTER_EVENT_KEYUP; | |
580 break; | |
581 default: | |
582 LOG(ERROR) << "SDL event: " << src.type << " is not supported"; | |
583 ORTHANC_ASSERT(false, "Not supported"); | |
584 } | |
585 dest.sym[0] = src.key.keysym.sym; | |
586 dest.sym[1] = 0; | |
587 | |
588 if (src.key.keysym.mod & KMOD_CTRL) | |
589 dest.ctrlKey = true; | |
590 else | |
591 dest.ctrlKey = false; | |
592 | |
593 if (src.key.keysym.mod & KMOD_SHIFT) | |
594 dest.shiftKey = true; | |
595 else | |
596 dest.shiftKey = false; | |
597 | |
598 if (src.key.keysym.mod & KMOD_ALT) | |
599 dest.altKey = true; | |
600 else | |
601 dest.altKey = false; | |
602 } | |
603 | |
604 // SDL ONLY | |
605 void GuiAdapter::SetSdlResizeCallback( | |
606 std::string canvasId, void* userData, bool capture, OnSdlWindowResizeFunc func) | |
607 { | |
608 resizeHandlers_.push_back(EventHandlerData<OnSdlWindowResizeFunc>(canvasId, func, userData)); | |
609 } | |
610 | |
611 // SDL ONLY | |
612 void GuiAdapter::SetMouseDownCallback( | |
613 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) | |
614 { | |
615 mouseDownHandlers_.push_back(EventHandlerData<OnMouseEventFunc>(canvasId, func, userData)); | |
616 } | |
617 | |
618 // SDL ONLY | |
619 void GuiAdapter::SetMouseDblClickCallback( | |
620 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) | |
621 { | |
622 mouseDblCickHandlers_.push_back(EventHandlerData<OnMouseEventFunc>(canvasId, func, userData)); | |
623 } | |
624 | |
625 // SDL ONLY | |
626 void GuiAdapter::SetMouseMoveCallback( | |
627 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) | |
628 { | |
629 mouseMoveHandlers_.push_back(EventHandlerData<OnMouseEventFunc>(canvasId, func, userData)); | |
630 } | |
631 | |
632 // SDL ONLY | |
633 void GuiAdapter::SetMouseUpCallback( | |
634 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) | |
635 { | |
636 mouseUpHandlers_.push_back(EventHandlerData<OnMouseEventFunc>(canvasId, func, userData)); | |
637 } | |
638 | |
639 // SDL ONLY | |
640 void GuiAdapter::SetWheelCallback( | |
641 std::string canvasId, void* userData, bool capture, OnMouseWheelFunc func) | |
642 { | |
643 mouseWheelHandlers_.push_back(EventHandlerData<OnMouseWheelFunc>(canvasId, func, userData)); | |
644 } | |
645 | |
646 // SDL ONLY | |
647 void GuiAdapter::SetKeyDownCallback( | |
648 std::string canvasId, void* userData, bool capture, OnKeyDownFunc func) | |
649 { | |
650 keyDownHandlers_.push_back(EventHandlerData<OnKeyDownFunc>(canvasId, func, userData)); | |
651 } | |
652 | |
653 // SDL ONLY | |
654 void GuiAdapter::SetKeyUpCallback( | |
655 std::string canvasId, void* userData, bool capture, OnKeyUpFunc func) | |
656 { | |
657 keyUpHandlers_.push_back(EventHandlerData<OnKeyUpFunc>(canvasId, func, userData)); | |
658 } | |
659 | |
660 // SDL ONLY | |
661 void GuiAdapter::SetGenericSdlEventCallback( | |
662 std::string canvasId, void* userData, bool capture, OnSdlEventCallback func) | |
663 { | |
664 sdlEventHandlers_.push_back(EventHandlerData<OnSdlEventCallback>(canvasId, func, userData)); | |
665 } | |
666 | |
667 // SDL ONLY | |
668 void GuiAdapter::OnAnimationFrame() | |
669 { | |
670 std::vector<size_t> disabledAnimationHandlers; | |
671 for (size_t i = 0; i < animationFrameHandlers_.size(); i++) | |
672 { | |
673 // TODO: fix time | |
674 bool goOn = (*(animationFrameHandlers_[i].first))(0, animationFrameHandlers_[i].second); | |
675 | |
676 // If the function returns false, we need to emulate what happens in Web | |
677 // and remove the function from the handlers... | |
678 if (!goOn) | |
679 disabledAnimationHandlers.push_back(i); | |
680 } | |
681 for (size_t i = 0; i < disabledAnimationHandlers.size(); i++) | |
682 { | |
683 ORTHANC_ASSERT(animationFrameHandlers_.begin() + disabledAnimationHandlers[i] < animationFrameHandlers_.end()); | |
684 animationFrameHandlers_.erase(animationFrameHandlers_.begin() + disabledAnimationHandlers[i]); | |
685 } | |
686 } | |
687 | |
688 // SDL ONLY | |
689 void GuiAdapter::OnResize(unsigned int width, unsigned int height) | |
690 { | |
691 for (size_t i = 0; i < resizeHandlers_.size(); i++) | |
692 { | |
693 (*(resizeHandlers_[i].func))( | |
694 resizeHandlers_[i].canvasName, NULL, width, height, resizeHandlers_[i].userData); | |
695 } | |
696 } | |
697 | |
698 | |
699 | |
700 void GuiAdapter::OnSdlGenericEvent(const SDL_Event& sdlEvent) | |
701 { | |
702 // Events related to a window are only sent to the related canvas | |
703 // User events are sent to everyone (we can't filter them here) | |
704 | |
705 /* | |
706 SDL_WindowEvent SDL_WINDOWEVENT | |
707 SDL_KeyboardEvent SDL_KEYDOWN | |
708 SDL_KEYUP | |
709 SDL_TextEditingEvent SDL_TEXTEDITING | |
710 SDL_TextInputEvent SDL_TEXTINPUT | |
711 SDL_MouseMotionEvent SDL_MOUSEMOTION | |
712 SDL_MouseButtonEvent SDL_MOUSEBUTTONDOWN | |
713 SDL_MOUSEBUTTONUP | |
714 SDL_MouseWheelEvent SDL_MOUSEWHEEL | |
715 SDL_UserEvent SDL_USEREVENT through ::SDL_LASTEVENT-1 | |
716 */ | |
717 | |
718 // if this string is left empty, it means the message will be sent to | |
719 // all widgets. | |
720 // otherwise, it contains the originating message window title | |
721 | |
722 std::string windowTitle; | |
723 uint32_t windowId = 0; | |
724 | |
725 if (sdlEvent.type == SDL_WINDOWEVENT) | |
726 windowId = sdlEvent.window.windowID; | |
727 else if (sdlEvent.type == SDL_KEYDOWN || sdlEvent.type == SDL_KEYUP) | |
728 windowId = sdlEvent.key.windowID; | |
729 else if (sdlEvent.type == SDL_TEXTEDITING) | |
730 windowId = sdlEvent.edit.windowID; | |
731 else if (sdlEvent.type == SDL_TEXTINPUT) | |
732 windowId = sdlEvent.text.windowID; | |
733 else if (sdlEvent.type == SDL_MOUSEMOTION) | |
734 windowId = sdlEvent.motion.windowID; | |
735 else if (sdlEvent.type == SDL_MOUSEBUTTONDOWN || sdlEvent.type == SDL_MOUSEBUTTONUP) | |
736 windowId = sdlEvent.button.windowID; | |
737 else if (sdlEvent.type == SDL_MOUSEWHEEL) | |
738 windowId = sdlEvent.wheel.windowID; | |
739 else if (sdlEvent.type >= SDL_USEREVENT && sdlEvent.type <= (SDL_LASTEVENT-1)) | |
740 windowId = sdlEvent.user.windowID; | |
741 | |
742 if (windowId != 0) | |
743 { | |
744 SDL_Window* sdlWindow = SDL_GetWindowFromID(windowId); | |
745 ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << windowId << "\" is not a valid SDL window ID!"); | |
746 const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow); | |
747 ORTHANC_ASSERT(windowTitleSz != NULL, "Window ID \"" << windowId << "\" has a NULL window title!"); | |
748 windowTitle = windowTitleSz; | |
749 ORTHANC_ASSERT(windowTitle != "", "Window ID \"" << windowId << "\" has an empty window title!"); | |
750 } | |
751 | |
752 for (size_t i = 0; i < sdlEventHandlers_.size(); i++) | |
753 { | |
754 // normally, the handlers return a bool indicating whether they | |
755 // have handled the event or not, but we don't really care about this | |
756 std::string& canvasName = sdlEventHandlers_[i].canvasName; | |
757 | |
758 bool sendEvent = true; | |
759 | |
760 if (windowTitle != "" && (canvasName != windowTitle)) | |
761 sendEvent = false; | |
762 | |
763 if (sendEvent) | |
764 { | |
765 OnSdlEventCallback func = sdlEventHandlers_[i].func; | |
766 (*func)(canvasName, sdlEvent, sdlEventHandlers_[i].userData); | |
767 } | |
768 } | |
769 } | |
770 | |
771 // SDL ONLY | |
772 void GuiAdapter::OnMouseWheelEvent(uint32_t windowID, const GuiAdapterWheelEvent& event) | |
773 { | |
774 // the SDL window name IS the canvas name ("canvas" is used because this lib | |
775 // is designed for Wasm | |
776 SDL_Window* sdlWindow = SDL_GetWindowFromID(windowID); | |
777 ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << windowID << "\" is not a valid SDL window ID!"); | |
778 | |
779 const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow); | |
780 ORTHANC_ASSERT(windowTitleSz != NULL, "Window ID \"" << windowID << "\" has a NULL window title!"); | |
781 | |
782 std::string windowTitle(windowTitleSz); | |
783 ORTHANC_ASSERT(windowTitle != "", "Window ID \"" << windowID << "\" has an empty window title!"); | |
784 | |
785 switch (event.mouse.type) | |
786 { | |
787 case GUIADAPTER_EVENT_WHEEL: | |
788 for (size_t i = 0; i < mouseWheelHandlers_.size(); i++) | |
789 { | |
790 if (mouseWheelHandlers_[i].canvasName == windowTitle) | |
791 (*(mouseWheelHandlers_[i].func))(windowTitle, &event, mouseWheelHandlers_[i].userData); | |
792 } | |
793 break; | |
794 default: | |
795 ORTHANC_ASSERT(false, "Wrong event.type: " << event.mouse.type << " in GuiAdapter::OnMouseWheelEvent(...)"); | |
796 break; | |
797 } | |
798 } | |
799 | |
800 | |
801 void GuiAdapter::OnKeyboardEvent(uint32_t windowID, const GuiAdapterKeyboardEvent& event) | |
802 { | |
803 // only one-letter (ascii) keyboard events supported for now | |
804 ORTHANC_ASSERT(event.sym[0] != 0); | |
805 ORTHANC_ASSERT(event.sym[1] == 0); | |
806 | |
807 SDL_Window* sdlWindow = SDL_GetWindowFromID(windowID); | |
808 ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << windowID << "\" is not a valid SDL window ID!"); | |
809 | |
810 const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow); | |
811 ORTHANC_ASSERT(windowTitleSz != NULL, "Window ID \"" << windowID << "\" has a NULL window title!"); | |
812 | |
813 std::string windowTitle(windowTitleSz); | |
814 ORTHANC_ASSERT(windowTitle != "", "Window ID \"" << windowID << "\" has an empty window title!"); | |
815 | |
816 switch (event.type) | |
817 { | |
818 case GUIADAPTER_EVENT_KEYDOWN: | |
819 for (size_t i = 0; i < keyDownHandlers_.size(); i++) | |
820 { | |
821 (*(keyDownHandlers_[i].func))(windowTitle, &event, keyDownHandlers_[i].userData); | |
822 } | |
823 break; | |
824 case GUIADAPTER_EVENT_KEYUP: | |
825 for (size_t i = 0; i < keyUpHandlers_.size(); i++) | |
826 { | |
827 (*(keyUpHandlers_[i].func))(windowTitle, &event, keyUpHandlers_[i].userData); | |
828 } | |
829 break; | |
830 default: | |
831 ORTHANC_ASSERT(false, "Wrong event.type: " << event.type << " in GuiAdapter::OnKeyboardEvent(...)"); | |
832 break; | |
833 } | |
834 } | |
835 | |
836 // SDL ONLY | |
837 void GuiAdapter::OnMouseEvent(uint32_t windowID, const GuiAdapterMouseEvent& event) | |
838 { | |
839 if (windowID == 0) | |
840 { | |
841 LOG(WARNING) << "GuiAdapter::OnMouseEvent -- windowID == 0 and event won't be routed!"; | |
842 } | |
843 else | |
844 { | |
845 // the SDL window name IS the canvas name ("canvas" is used because this lib | |
846 // is designed for Wasm | |
847 SDL_Window* sdlWindow = SDL_GetWindowFromID(windowID); | |
848 | |
849 ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << windowID << "\" is not a valid SDL window ID!"); | |
850 | |
851 const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow); | |
852 ORTHANC_ASSERT(windowTitleSz != NULL, "Window ID \"" << windowID << "\" has a NULL window title!"); | |
853 | |
854 std::string windowTitle(windowTitleSz); | |
855 ORTHANC_ASSERT(windowTitle != "", "Window ID \"" << windowID << "\" has an empty window title!"); | |
856 | |
857 switch (event.type) | |
858 { | |
859 case GUIADAPTER_EVENT_MOUSEDOWN: | |
860 for (size_t i = 0; i < mouseDownHandlers_.size(); i++) | |
861 { | |
862 if (mouseDownHandlers_[i].canvasName == windowTitle) | |
863 (*(mouseDownHandlers_[i].func))(windowTitle, &event, mouseDownHandlers_[i].userData); | |
864 } | |
865 break; | |
866 case GUIADAPTER_EVENT_MOUSEDBLCLICK: | |
867 for (size_t i = 0; i < mouseDblCickHandlers_.size(); i++) | |
868 { | |
869 if (mouseDblCickHandlers_[i].canvasName == windowTitle) | |
870 (*(mouseDblCickHandlers_[i].func))(windowTitle, &event, mouseDblCickHandlers_[i].userData); | |
871 } | |
872 break; | |
873 case GUIADAPTER_EVENT_MOUSEMOVE: | |
874 for (size_t i = 0; i < mouseMoveHandlers_.size(); i++) | |
875 { | |
876 if (mouseMoveHandlers_[i].canvasName == windowTitle) | |
877 (*(mouseMoveHandlers_[i].func))(windowTitle, &event, mouseMoveHandlers_[i].userData); | |
878 } | |
879 break; | |
880 case GUIADAPTER_EVENT_MOUSEUP: | |
881 for (size_t i = 0; i < mouseUpHandlers_.size(); i++) | |
882 { | |
883 if (mouseUpHandlers_[i].canvasName == windowTitle) | |
884 (*(mouseUpHandlers_[i].func))(windowTitle, &event, mouseUpHandlers_[i].userData); | |
885 } | |
886 break; | |
887 default: | |
888 ORTHANC_ASSERT(false, "Wrong event.type: " << event.type << " in GuiAdapter::OnMouseEvent(...)"); | |
889 break; | |
890 } | |
891 } | |
892 } | |
893 | |
894 | |
895 // extern void Debug_SetContextToBeKilled(std::string title); | |
896 // extern void Debug_SetContextToBeRestored(std::string title); | |
897 | |
898 // SDL ONLY | |
899 void GuiAdapter::RequestAnimationFrame(OnAnimationFrameFunc func, void* userData) | |
900 { | |
901 animationFrameHandlers_.push_back(std::make_pair(func, userData)); | |
902 } | |
903 | |
904 # if ORTHANC_ENABLE_OPENGL == 1 && !defined(__APPLE__) /* OpenGL debug is not available on OS X */ | |
905 | |
906 // SDL ONLY | |
907 static void GLAPIENTRY | |
908 OpenGLMessageCallback(GLenum source, | |
909 GLenum type, | |
910 GLuint id, | |
911 GLenum severity, | |
912 GLsizei length, | |
913 const GLchar * message, | |
914 const void* userParam) | |
915 { | |
916 if (severity != GL_DEBUG_SEVERITY_NOTIFICATION) | |
917 { | |
918 fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n", | |
919 (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), | |
920 type, severity, message); | |
921 } | |
922 } | |
923 # endif | |
924 | |
925 #if 0 | |
926 // TODO: remove this when generic sdl event handlers are implemented in | |
927 // the DoseView | |
928 // SDL ONLY | |
929 bool GuiAdapter::IsSdlViewPortRefreshEvent(const SDL_Event& event) const | |
930 { | |
931 SDL_Window* sdlWindow = SDL_GetWindowFromID(event.window.windowID); | |
932 | |
933 ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << event.window.windowID << "\" is not a valid SDL window ID!"); | |
934 | |
935 const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow); | |
936 | |
937 // now we need to find the DoseView from from the canvas name! | |
938 // (and retrieve the SdlViewport) | |
939 boost::shared_ptr<IGuiAdapterWidget> foundWidget; | |
940 VisitWidgets([&foundWidget, windowTitleSz](auto widget) | |
941 { | |
942 if (widget->GetCanvasIdentifier() == std::string(windowTitleSz)) | |
943 foundWidget = widget; | |
944 }); | |
945 ORTHANC_ASSERT(foundWidget, "The window named: \"" << windowTitleSz << "\" was not found in the registered widgets!"); | |
946 return foundWidget->GetSdlViewport().IsRefreshEvent(event); | |
947 } | |
948 #endif | |
949 | |
950 // SDL ONLY | |
951 void GuiAdapter::Run(GuiAdapterRunFunc func, void* cookie) | |
952 { | |
953 #if 1 | |
954 // TODO: MAKE THIS DYNAMIC !!! See SdlOpenGLViewport vs Cairo in ViewportWrapper | |
955 # if ORTHANC_ENABLE_OPENGL == 1 && !defined(__APPLE__) | |
956 glEnable(GL_DEBUG_OUTPUT); | |
957 glDebugMessageCallback(OpenGLMessageCallback, 0); | |
958 # endif | |
959 #endif | |
960 | |
961 // Uint32 SDL_GetWindowID(SDL_Window* window) | |
962 // SDL_Window* SDL_GetWindowFromID(Uint32 id) // may return NULL | |
963 | |
964 bool stop = false; | |
965 while (!stop) | |
966 { | |
967 { | |
968 // TODO: lock all viewports here! (use a scoped object) | |
969 if(func != NULL) | |
970 (*func)(cookie); | |
971 OnAnimationFrame(); // in SDL we must call it | |
972 } | |
973 | |
974 while (!stop) | |
975 { | |
976 std::vector<SDL_Event> sdlEvents; | |
977 std::map<Uint32,SDL_Event> userEventsMap; | |
978 | |
979 SDL_Event sdlEvent; | |
980 | |
981 // FIRST: collect all pending events | |
982 while (SDL_PollEvent(&sdlEvent) != 0) | |
983 { | |
984 if ( (sdlEvent.type >= SDL_USEREVENT) && | |
985 (sdlEvent.type < SDL_LASTEVENT) ) | |
986 { | |
987 // we don't want to have multiple events with the same event.type | |
988 userEventsMap[sdlEvent.type] = sdlEvent; | |
989 } | |
990 else | |
991 { | |
992 sdlEvents.push_back(sdlEvent); | |
993 } | |
994 } | |
995 | |
996 // SECOND: collect all user events | |
997 for (std::map<Uint32,SDL_Event>::const_iterator it = userEventsMap.begin(); it != userEventsMap.end(); ++it) | |
998 sdlEvents.push_back(it->second); | |
999 | |
1000 // now process the events | |
1001 for (std::vector<SDL_Event>::const_iterator it = sdlEvents.begin(); it != sdlEvents.end(); ++it) | |
1002 { | |
1003 const SDL_Event& sdlEvent = *it; | |
1004 // TODO: lock all viewports here! (use a scoped object) | |
1005 | |
1006 if (sdlEvent.type == SDL_QUIT) | |
1007 { | |
1008 // TODO: call exit callbacks here | |
1009 stop = true; | |
1010 break; | |
1011 } | |
1012 else if ((sdlEvent.type == SDL_MOUSEMOTION) || | |
1013 (sdlEvent.type == SDL_MOUSEBUTTONDOWN) || | |
1014 (sdlEvent.type == SDL_MOUSEBUTTONUP)) | |
1015 { | |
1016 int scancodeCount = 0; | |
1017 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); | |
1018 bool ctrlPressed(false); | |
1019 bool shiftPressed(false); | |
1020 bool altPressed(false); | |
1021 | |
1022 if (SDL_SCANCODE_LCTRL < scancodeCount && keyboardState[SDL_SCANCODE_LCTRL]) | |
1023 ctrlPressed = true; | |
1024 if (SDL_SCANCODE_RCTRL < scancodeCount && keyboardState[SDL_SCANCODE_RCTRL]) | |
1025 ctrlPressed = true; | |
1026 if (SDL_SCANCODE_LSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_LSHIFT]) | |
1027 shiftPressed = true; | |
1028 if (SDL_SCANCODE_RSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_RSHIFT]) | |
1029 shiftPressed = true; | |
1030 if (SDL_SCANCODE_LALT < scancodeCount && keyboardState[SDL_SCANCODE_LALT]) | |
1031 altPressed = true; | |
1032 | |
1033 GuiAdapterMouseEvent dest; | |
1034 ConvertFromPlatform(dest, ctrlPressed, shiftPressed, altPressed, sdlEvent); | |
1035 OnMouseEvent(sdlEvent.window.windowID, dest); | |
1036 #if 0 | |
1037 // for reference, how to create trackers | |
1038 if (tracker) | |
1039 { | |
1040 PointerEvent e; | |
1041 e.AddPosition(compositor.GetPixelCenterCoordinates( | |
1042 sdlEvent.button.x, sdlEvent.button.y)); | |
1043 tracker->PointerMove(e); | |
1044 } | |
1045 #endif | |
1046 } | |
1047 else if (sdlEvent.type == SDL_MOUSEWHEEL) | |
1048 { | |
1049 | |
1050 int scancodeCount = 0; | |
1051 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); | |
1052 bool ctrlPressed(false); | |
1053 bool shiftPressed(false); | |
1054 bool altPressed(false); | |
1055 | |
1056 if (SDL_SCANCODE_LCTRL < scancodeCount && keyboardState[SDL_SCANCODE_LCTRL]) | |
1057 ctrlPressed = true; | |
1058 if (SDL_SCANCODE_RCTRL < scancodeCount && keyboardState[SDL_SCANCODE_RCTRL]) | |
1059 ctrlPressed = true; | |
1060 if (SDL_SCANCODE_LSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_LSHIFT]) | |
1061 shiftPressed = true; | |
1062 if (SDL_SCANCODE_RSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_RSHIFT]) | |
1063 shiftPressed = true; | |
1064 if (SDL_SCANCODE_LALT < scancodeCount && keyboardState[SDL_SCANCODE_LALT]) | |
1065 altPressed = true; | |
1066 | |
1067 GuiAdapterWheelEvent dest; | |
1068 ConvertFromPlatform(dest, ctrlPressed, shiftPressed, altPressed, sdlEvent); | |
1069 OnMouseWheelEvent(sdlEvent.window.windowID, dest); | |
1070 | |
1071 //KeyboardModifiers modifiers = GetKeyboardModifiers(keyboardState, scancodeCount); | |
1072 | |
1073 //int x, y; | |
1074 //SDL_GetMouseState(&x, &y); | |
1075 | |
1076 //if (sdlEvent.wheel.y > 0) | |
1077 //{ | |
1078 // locker.GetCentralViewport().MouseWheel(MouseWheelDirection_Up, x, y, modifiers); | |
1079 //} | |
1080 //else if (sdlEvent.wheel.y < 0) | |
1081 //{ | |
1082 // locker.GetCentralViewport().MouseWheel(MouseWheelDirection_Down, x, y, modifiers); | |
1083 //} | |
1084 } | |
1085 else if (sdlEvent.type == SDL_WINDOWEVENT && | |
1086 (sdlEvent.window.event == SDL_WINDOWEVENT_RESIZED || | |
1087 sdlEvent.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)) | |
1088 { | |
1089 #if 0 | |
1090 tracker.reset(); | |
1091 #endif | |
1092 OnResize(sdlEvent.window.data1, sdlEvent.window.data2); | |
1093 } | |
1094 else if (sdlEvent.type == SDL_KEYDOWN && sdlEvent.key.repeat == 0 /* Ignore key bounce */) | |
1095 { | |
1096 switch (sdlEvent.key.keysym.sym) | |
1097 { | |
1098 case SDLK_f: | |
1099 // window.GetWindow().ToggleMaximize(); //TODO: move to particular handler | |
1100 break; | |
1101 | |
1102 // This commented out code was used to debug the context | |
1103 // loss/restoring code (2019-08-10) | |
1104 // case SDLK_k: | |
1105 // { | |
1106 // SDL_Window* window = SDL_GetWindowFromID(sdlEvent.window.windowID); | |
1107 // std::string windowTitle(SDL_GetWindowTitle(window)); | |
1108 // Debug_SetContextToBeKilled(windowTitle); | |
1109 // } | |
1110 // break; | |
1111 // case SDLK_l: | |
1112 // { | |
1113 // SDL_Window* window = SDL_GetWindowFromID(sdlEvent.window.windowID); | |
1114 // std::string windowTitle(SDL_GetWindowTitle(window)); | |
1115 // Debug_SetContextToBeRestored(windowTitle); | |
1116 // } | |
1117 // break; | |
1118 | |
1119 case SDLK_q: | |
1120 stop = true; | |
1121 break; | |
1122 | |
1123 default: | |
1124 GuiAdapterKeyboardEvent dest; | |
1125 ConvertFromPlatform(dest, sdlEvent); | |
1126 OnKeyboardEvent(sdlEvent.window.windowID, dest); | |
1127 break; | |
1128 } | |
1129 } | |
1130 | |
1131 OnSdlGenericEvent(sdlEvent); | |
1132 } | |
1133 SDL_Delay(1); | |
1134 } | |
1135 } | |
1136 } | |
1137 #endif | |
1138 } | |
1139 |