comparison Framework/Deprecated/GuiAdapter.h @ 1502:e5729dab3f67

moving Deprecated/Applications/Generic/GuiAdapter.[cpp|h] to Framework/Deprecated/
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 30 Jun 2020 11:37:34 +0200
parents Deprecated/Applications/Generic/GuiAdapter.h@fb8c36073983
children
comparison
equal deleted inserted replaced
1501:1e381f2596d3 1502:e5729dab3f67
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 #pragma once
21
22 #include <string>
23
24 #if ORTHANC_ENABLE_WASM != 1
25 # ifdef __EMSCRIPTEN__
26 # error __EMSCRIPTEN__ is defined and ORTHANC_ENABLE_WASM != 1
27 # endif
28 #endif
29
30 #if ORTHANC_ENABLE_WASM == 1
31 # ifndef __EMSCRIPTEN__
32 # error __EMSCRIPTEN__ is not defined and ORTHANC_ENABLE_WASM == 1
33 # endif
34 #endif
35
36 #if ORTHANC_ENABLE_WASM == 1
37 # include <emscripten/html5.h>
38 #else
39 # if ORTHANC_ENABLE_SDL == 1
40 # include <SDL.h>
41 # endif
42 #endif
43
44 #include "../StoneException.h"
45
46 #include <vector>
47 #include <boost/shared_ptr.hpp>
48 #include <boost/weak_ptr.hpp>
49
50 namespace OrthancStone
51 {
52 #if ORTHANC_ENABLE_SDL == 1
53 class SdlViewport;
54 #endif
55
56 #if 0
57
58 /**
59 This interface is used to store the widgets that are controlled by the
60 GuiAdapter and receive event callbacks.
61 The callbacks may possibly be downcast (using dynamic_cast, for safety) \
62 to the actual widget type
63 */
64 class IGuiAdapterWidget
65 {
66 public:
67 virtual ~IGuiAdapterWidget() {}
68
69 #if #if ORTHANC_ENABLE_SDL == 1
70 /**
71 Returns the SdlViewport that this widget contains. If the underlying
72 viewport type is *not* SDL, then an error is returned.
73 */
74 virtual SdlViewport& GetSdlViewport() = 0;
75 #endif
76 };
77
78 #endif
79
80 enum GuiAdapterMouseButtonType
81 {
82 GUIADAPTER_MOUSEBUTTON_LEFT = 0,
83 GUIADAPTER_MOUSEBUTTON_MIDDLE = 1,
84 GUIADAPTER_MOUSEBUTTON_RIGHT = 2
85 };
86
87
88 enum GuiAdapterHidEventType
89 {
90 GUIADAPTER_EVENT_MOUSEDOWN = 1973,
91 GUIADAPTER_EVENT_MOUSEMOVE = 1974,
92 GUIADAPTER_EVENT_MOUSEDBLCLICK = 1975,
93 GUIADAPTER_EVENT_MOUSEUP = 1976,
94 GUIADAPTER_EVENT_WHEEL = 1977,
95 GUIADAPTER_EVENT_KEYDOWN = 1978,
96 GUIADAPTER_EVENT_KEYUP = 1979,
97 };
98
99 const unsigned int GUIADAPTER_DELTA_PIXEL = 2973;
100 const unsigned int GUIADAPTER_DELTA_LINE = 2974;
101 const unsigned int GUIADAPTER_DELTA_PAGE = 2975;
102
103 struct GuiAdapterUiEvent;
104 struct GuiAdapterMouseEvent;
105 struct GuiAdapterWheelEvent;
106 struct GuiAdapterKeyboardEvent;
107
108 #if 1
109 typedef bool (*OnMouseEventFunc) (std::string canvasId, const GuiAdapterMouseEvent* mouseEvent, void* userData);
110 typedef bool (*OnMouseWheelFunc) (std::string canvasId, const GuiAdapterWheelEvent* wheelEvent, void* userData);
111 typedef bool (*OnKeyDownFunc) (std::string canvasId, const GuiAdapterKeyboardEvent* keyEvent, void* userData);
112 typedef bool (*OnKeyUpFunc) (std::string canvasId, const GuiAdapterKeyboardEvent* keyEvent, void* userData);
113 typedef bool (*OnAnimationFrameFunc)(double time, void* userData);
114
115 #if ORTHANC_ENABLE_SDL == 1
116 typedef bool (*OnSdlEventCallback) (std::string canvasId, const SDL_Event& sdlEvent, void* userData);
117
118 typedef bool (*OnSdlWindowResizeFunc)(std::string canvasId,
119 const GuiAdapterUiEvent* uiEvent,
120 unsigned int width,
121 unsigned int height,
122 void* userData);
123
124
125 #endif
126
127 #else
128
129 #if ORTHANC_ENABLE_WASM == 1
130 typedef EM_BOOL (*OnMouseEventFunc)(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData);
131 typedef EM_BOOL (*OnMouseWheelFunc)(int eventType, const EmscriptenWheelEvent* wheelEvent, void* userData);
132 typedef EM_BOOL (*OnKeyDownFunc) (int eventType, const EmscriptenKeyboardEvent* keyEvent, void* userData);
133 typedef EM_BOOL (*OnKeyUpFunc) (int eventType, const EmscriptenKeyboardEvent* keyEvent, void* userData);
134
135 typedef EM_BOOL (*OnAnimationFrameFunc)(double time, void* userData);
136 typedef EM_BOOL (*OnWindowResizeFunc)(int eventType, const EmscriptenUiEvent* uiEvent, void* userData);
137 #else
138 typedef bool (*OnMouseEventFunc)(int eventType, const SDL_Event* mouseEvent, void* userData);
139 typedef bool (*OnMouseWheelFunc)(int eventType, const SDL_Event* wheelEvent, void* userData);
140 typedef bool (*OnKeyDownFunc) (int eventType, const SDL_Event* keyEvent, void* userData);
141 typedef bool (*OnKeyUpFunc) (int eventType, const SDL_Event* keyEvent, void* userData);
142
143 typedef bool (*OnAnimationFrameFunc)(double time, void* userData);
144 typedef bool (*OnWindowResizeFunc)(int eventType, const GuiAdapterUiEvent* uiEvent, void* userData);
145 #endif
146
147 #endif
148 struct GuiAdapterMouseEvent
149 {
150 GuiAdapterHidEventType type;
151 //double timestamp;
152 //long screenX;
153 //long screenY;
154 //long clientX;
155 //long clientY;
156 bool ctrlKey;
157 bool shiftKey;
158 bool altKey;
159 //bool metaKey;
160 unsigned short button;
161 //unsigned short buttons;
162 //long movementX;
163 //long movementY;
164 long targetX;
165 long targetY;
166 // canvasX and canvasY are deprecated - there no longer exists a Module['canvas'] object, so canvasX/Y are no longer reported (register a listener on canvas directly to get canvas coordinates, or translate manually)
167 //long canvasX;
168 //long canvasY;
169 //long padding;
170
171 public:
172 GuiAdapterMouseEvent()
173 : ctrlKey(false),
174 shiftKey(false),
175 altKey(false)
176 {
177 }
178 };
179
180 struct GuiAdapterWheelEvent {
181 GuiAdapterMouseEvent mouse;
182 double deltaX;
183 double deltaY;
184 unsigned long deltaMode;
185 };
186
187 // we don't use any data now
188 struct GuiAdapterUiEvent {};
189
190 // EmscriptenKeyboardEvent
191 struct GuiAdapterKeyboardEvent
192 {
193 GuiAdapterHidEventType type;
194 char sym[32];
195 bool ctrlKey;
196 bool shiftKey;
197 bool altKey;
198 };
199
200 std::ostream& operator<<(std::ostream& os, const GuiAdapterKeyboardEvent& event);
201 std::ostream& operator<<(std::ostream& os, const GuiAdapterMouseEvent& event);
202
203 /*
204 Mousedown event trigger when either the left or right (or middle) mouse is pressed
205 on the object;
206
207 Mouseup event trigger when either the left or right (or middle) mouse is released
208 above the object after triggered mousedown event and held.
209
210 Click event trigger when the only left mouse button is pressed and released on the
211 same object, requires the Mousedown and Mouseup event happened before Click event.
212
213 The normal expect trigger order: onMousedown >> onMouseup >> onClick
214
215 Testing in Chrome v58, the time between onMouseup and onClick events are around
216 7ms to 15ms
217
218 FROM: https://codingrepo.com/javascript/2017/05/19/javascript-difference-mousedown-mouseup-click-events/
219 */
220 #if ORTHANC_ENABLE_WASM == 1
221 void ConvertFromPlatform(GuiAdapterUiEvent& dest, int eventType, const EmscriptenUiEvent& src);
222
223 void ConvertFromPlatform(GuiAdapterMouseEvent& dest, int eventType, const EmscriptenMouseEvent& src);
224
225 void ConvertFromPlatform(GuiAdapterWheelEvent& dest, int eventType, const EmscriptenWheelEvent& src);
226
227 void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const EmscriptenKeyboardEvent& src);
228 #else
229
230 # if ORTHANC_ENABLE_SDL == 1
231 void ConvertFromPlatform(GuiAdapterMouseEvent& dest, bool ctrlPressed, bool shiftPressed, bool altPressed, const SDL_Event& source);
232
233 void ConvertFromPlatform(GuiAdapterWheelEvent& dest, bool ctrlPressed, bool shiftPressed, bool altPressed, const SDL_Event& source);
234
235 void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const SDL_Event& source);
236
237 # endif
238
239 #endif
240
241 typedef void (*GuiAdapterRunFunc)(void*);
242
243 class GuiAdapter
244 {
245 public:
246 GuiAdapter()
247 {
248 ORTHANC_ASSERT(s_instanceCount == 0);
249 s_instanceCount = 1;
250 }
251
252 ~GuiAdapter()
253 {
254 s_instanceCount -= 1;
255 }
256
257 /**
258 emscripten_set_resize_callback("EMSCRIPTEN_EVENT_TARGET_WINDOW", NULL, false, OnWindowResize);
259
260 emscripten_set_wheel_callback("#mycanvas1", widget1_.get(), false, OnXXXMouseWheel);
261 emscripten_set_wheel_callback("#mycanvas2", widget2_.get(), false, OnXXXMouseWheel);
262 emscripten_set_wheel_callback("#mycanvas3", widget3_.get(), false, OnXXXMouseWheel);
263
264 emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, false, OnKeyDown); ---> NO!
265 emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, false, OnKeyUp);
266
267 emscripten_request_animation_frame_loop(OnAnimationFrame, NULL);
268
269 SDL:
270 see https://wiki.libsdl.org/SDL_CaptureMouse
271
272 */
273
274 void SetMouseDownCallback (std::string canvasId, void* userData, bool capture, OnMouseEventFunc func);
275 void SetMouseDblClickCallback (std::string canvasId, void* userData, bool capture, OnMouseEventFunc func);
276 void SetMouseMoveCallback (std::string canvasId, void* userData, bool capture, OnMouseEventFunc func);
277 void SetMouseUpCallback (std::string canvasId, void* userData, bool capture, OnMouseEventFunc func);
278 void SetWheelCallback (std::string canvasId, void* userData, bool capture, OnMouseWheelFunc func);
279 void SetKeyDownCallback (std::string canvasId, void* userData, bool capture, OnKeyDownFunc func);
280 void SetKeyUpCallback (std::string canvasId, void* userData, bool capture, OnKeyUpFunc func);
281
282 #if ORTHANC_ENABLE_SDL == 1
283
284 void SetGenericSdlEventCallback (std::string canvasId, void* userData, bool capture, OnSdlEventCallback func);
285
286 typedef bool (*OnSdlEventCallback) (std::string canvasId, const SDL_Event& sdlEvent, void* userData);
287
288 // if you pass "#window", then any Window resize will trigger the callback
289 // (this special string is converted to EMSCRIPTEN_EVENT_TARGET_WINDOW in DOM, when DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1)
290 void SetSdlResizeCallback(std::string canvasId,
291 void* userData,
292 bool capture,
293 OnSdlWindowResizeFunc func);
294 #endif
295
296 void RequestAnimationFrame(OnAnimationFrameFunc func, void* userData);
297
298 // TODO: implement and call to remove canvases [in SDL, although code should be generic]
299 void SetOnExitCallback();
300
301 /**
302 Under SDL, this function does NOT return until all windows have been closed.
303 Under wasm, it returns without doing anything, since the event loop is managed
304 by the browser.
305 */
306 void Run(GuiAdapterRunFunc func = NULL, void* cookie = NULL);
307
308 private:
309
310 #if ORTHANC_ENABLE_SDL == 1
311 /**
312 Gives observers a chance to react based on generic event handlers. This
313 is used, for instance, when the viewport lock interface is invalidated.
314 */
315 void OnSdlGenericEvent(const SDL_Event& sdlEvent);
316 #endif
317
318 /**
319 In SDL, this executes all the registered headers
320 */
321 void OnAnimationFrame();
322
323 //void RequestAnimationFrame(OnAnimationFrameFunc func, void* userData);
324 std::vector<std::pair<OnAnimationFrameFunc, void*> >
325 animationFrameHandlers_;
326
327 void OnResize(unsigned int width, unsigned int height);
328
329 #if ORTHANC_ENABLE_SDL == 1
330 template<typename Func>
331 struct EventHandlerData
332 {
333 EventHandlerData(std::string canvasName, Func func, void* userData)
334 : canvasName(canvasName)
335 , func(func)
336 , userData(userData)
337 {
338 }
339
340 std::string canvasName;
341 Func func;
342 void* userData;
343 };
344 std::vector<EventHandlerData<OnSdlWindowResizeFunc> > resizeHandlers_;
345 std::vector<EventHandlerData<OnMouseEventFunc > > mouseDownHandlers_;
346 std::vector<EventHandlerData<OnMouseEventFunc > > mouseDblCickHandlers_;
347 std::vector<EventHandlerData<OnMouseEventFunc > > mouseMoveHandlers_;
348 std::vector<EventHandlerData<OnMouseEventFunc > > mouseUpHandlers_;
349 std::vector<EventHandlerData<OnMouseWheelFunc > > mouseWheelHandlers_;
350 std::vector<EventHandlerData<OnKeyDownFunc > > keyDownHandlers_;
351 std::vector<EventHandlerData<OnKeyUpFunc > > keyUpHandlers_;
352 std::vector<EventHandlerData<OnSdlEventCallback > > sdlEventHandlers_;
353
354 /**
355 This executes all the registered headers if needed (in wasm, the browser
356 deals with this)
357 */
358 void OnMouseEvent(uint32_t windowID, const GuiAdapterMouseEvent& event);
359
360 void OnKeyboardEvent(uint32_t windowID, const GuiAdapterKeyboardEvent& event);
361
362 /**
363 Same remark as OnMouseEvent
364 */
365 void OnMouseWheelEvent(uint32_t windowID, const GuiAdapterWheelEvent& event);
366
367 #endif
368
369 /**
370 This executes all the registered headers if needed (in wasm, the browser
371 deals with this)
372 */
373 void ViewportsUpdateSize();
374
375 static int s_instanceCount;
376 };
377 }