comparison Deprecated/Applications/Generic/GuiAdapter.h @ 1399:ff8d2e46ac63

moved Applications into Deprecated
author Alain Mazy <alain@mazy.be>
date Wed, 29 Apr 2020 20:44:31 +0200
parents Applications/Generic/GuiAdapter.h@f15529add7b0
children b2b0fc4a5596
comparison
equal deleted inserted replaced
1398:c5403d52078c 1399:ff8d2e46ac63
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 "../../Framework/StoneException.h"
45
46 #if ORTHANC_ENABLE_THREADS == 1
47 # include "../../Framework/Deprecated/Messages/LockingEmitter.h"
48 #endif
49
50 #include <vector>
51 #include <boost/shared_ptr.hpp>
52 #include <boost/weak_ptr.hpp>
53
54 namespace OrthancStone
55 {
56 #if ORTHANC_ENABLE_SDL == 1
57 class SdlViewport;
58 #endif
59
60 #if 0
61
62 /**
63 This interface is used to store the widgets that are controlled by the
64 GuiAdapter and receive event callbacks.
65 The callbacks may possibly be downcast (using dynamic_cast, for safety) \
66 to the actual widget type
67 */
68 class IGuiAdapterWidget
69 {
70 public:
71 virtual ~IGuiAdapterWidget() {}
72
73 #if #if ORTHANC_ENABLE_SDL == 1
74 /**
75 Returns the SdlViewport that this widget contains. If the underlying
76 viewport type is *not* SDL, then an error is returned.
77 */
78 virtual SdlViewport& GetSdlViewport() = 0;
79 #endif
80 };
81
82 #endif
83
84 enum GuiAdapterMouseButtonType
85 {
86 GUIADAPTER_MOUSEBUTTON_LEFT = 0,
87 GUIADAPTER_MOUSEBUTTON_MIDDLE = 1,
88 GUIADAPTER_MOUSEBUTTON_RIGHT = 2
89 };
90
91
92 enum GuiAdapterHidEventType
93 {
94 GUIADAPTER_EVENT_MOUSEDOWN = 1973,
95 GUIADAPTER_EVENT_MOUSEMOVE = 1974,
96 GUIADAPTER_EVENT_MOUSEDBLCLICK = 1975,
97 GUIADAPTER_EVENT_MOUSEUP = 1976,
98 GUIADAPTER_EVENT_WHEEL = 1977,
99 GUIADAPTER_EVENT_KEYDOWN = 1978,
100 GUIADAPTER_EVENT_KEYUP = 1979,
101 };
102
103 const unsigned int GUIADAPTER_DELTA_PIXEL = 2973;
104 const unsigned int GUIADAPTER_DELTA_LINE = 2974;
105 const unsigned int GUIADAPTER_DELTA_PAGE = 2975;
106
107 struct GuiAdapterUiEvent;
108 struct GuiAdapterMouseEvent;
109 struct GuiAdapterWheelEvent;
110 struct GuiAdapterKeyboardEvent;
111
112 #if 1
113 typedef bool (*OnMouseEventFunc) (std::string canvasId, const GuiAdapterMouseEvent* mouseEvent, void* userData);
114 typedef bool (*OnMouseWheelFunc) (std::string canvasId, const GuiAdapterWheelEvent* wheelEvent, void* userData);
115 typedef bool (*OnKeyDownFunc) (std::string canvasId, const GuiAdapterKeyboardEvent* keyEvent, void* userData);
116 typedef bool (*OnKeyUpFunc) (std::string canvasId, const GuiAdapterKeyboardEvent* keyEvent, void* userData);
117 typedef bool (*OnAnimationFrameFunc)(double time, void* userData);
118
119 #if ORTHANC_ENABLE_SDL == 1
120 typedef bool (*OnSdlEventCallback) (std::string canvasId, const SDL_Event& sdlEvent, void* userData);
121
122 typedef bool (*OnSdlWindowResizeFunc)(std::string canvasId,
123 const GuiAdapterUiEvent* uiEvent,
124 unsigned int width,
125 unsigned int height,
126 void* userData);
127
128
129 #endif
130
131 #else
132
133 #if ORTHANC_ENABLE_WASM == 1
134 typedef EM_BOOL (*OnMouseEventFunc)(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData);
135 typedef EM_BOOL (*OnMouseWheelFunc)(int eventType, const EmscriptenWheelEvent* wheelEvent, void* userData);
136 typedef EM_BOOL (*OnKeyDownFunc) (int eventType, const EmscriptenKeyboardEvent* keyEvent, void* userData);
137 typedef EM_BOOL (*OnKeyUpFunc) (int eventType, const EmscriptenKeyboardEvent* keyEvent, void* userData);
138
139 typedef EM_BOOL (*OnAnimationFrameFunc)(double time, void* userData);
140 typedef EM_BOOL (*OnWindowResizeFunc)(int eventType, const EmscriptenUiEvent* uiEvent, void* userData);
141 #else
142 typedef bool (*OnMouseEventFunc)(int eventType, const SDL_Event* mouseEvent, void* userData);
143 typedef bool (*OnMouseWheelFunc)(int eventType, const SDL_Event* wheelEvent, void* userData);
144 typedef bool (*OnKeyDownFunc) (int eventType, const SDL_Event* keyEvent, void* userData);
145 typedef bool (*OnKeyUpFunc) (int eventType, const SDL_Event* keyEvent, void* userData);
146
147 typedef bool (*OnAnimationFrameFunc)(double time, void* userData);
148 typedef bool (*OnWindowResizeFunc)(int eventType, const GuiAdapterUiEvent* uiEvent, void* userData);
149 #endif
150
151 #endif
152 struct GuiAdapterMouseEvent
153 {
154 GuiAdapterHidEventType type;
155 //double timestamp;
156 //long screenX;
157 //long screenY;
158 //long clientX;
159 //long clientY;
160 bool ctrlKey;
161 bool shiftKey;
162 bool altKey;
163 //bool metaKey;
164 unsigned short button;
165 //unsigned short buttons;
166 //long movementX;
167 //long movementY;
168 long targetX;
169 long targetY;
170 // 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)
171 //long canvasX;
172 //long canvasY;
173 //long padding;
174
175 public:
176 GuiAdapterMouseEvent()
177 : ctrlKey(false),
178 shiftKey(false),
179 altKey(false)
180 {
181 }
182 };
183
184 struct GuiAdapterWheelEvent {
185 GuiAdapterMouseEvent mouse;
186 double deltaX;
187 double deltaY;
188 unsigned long deltaMode;
189 };
190
191 // we don't use any data now
192 struct GuiAdapterUiEvent {};
193
194 // EmscriptenKeyboardEvent
195 struct GuiAdapterKeyboardEvent
196 {
197 GuiAdapterHidEventType type;
198 char sym[32];
199 bool ctrlKey;
200 bool shiftKey;
201 bool altKey;
202 };
203
204 std::ostream& operator<<(std::ostream& os, const GuiAdapterKeyboardEvent& event);
205 std::ostream& operator<<(std::ostream& os, const GuiAdapterMouseEvent& event);
206
207 /*
208 Mousedown event trigger when either the left or right (or middle) mouse is pressed
209 on the object;
210
211 Mouseup event trigger when either the left or right (or middle) mouse is released
212 above the object after triggered mousedown event and held.
213
214 Click event trigger when the only left mouse button is pressed and released on the
215 same object, requires the Mousedown and Mouseup event happened before Click event.
216
217 The normal expect trigger order: onMousedown >> onMouseup >> onClick
218
219 Testing in Chrome v58, the time between onMouseup and onClick events are around
220 7ms to 15ms
221
222 FROM: https://codingrepo.com/javascript/2017/05/19/javascript-difference-mousedown-mouseup-click-events/
223 */
224 #if ORTHANC_ENABLE_WASM == 1
225 void ConvertFromPlatform(GuiAdapterUiEvent& dest, int eventType, const EmscriptenUiEvent& src);
226
227 void ConvertFromPlatform(GuiAdapterMouseEvent& dest, int eventType, const EmscriptenMouseEvent& src);
228
229 void ConvertFromPlatform(GuiAdapterWheelEvent& dest, int eventType, const EmscriptenWheelEvent& src);
230
231 void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const EmscriptenKeyboardEvent& src);
232 #else
233
234 # if ORTHANC_ENABLE_SDL == 1
235 void ConvertFromPlatform(GuiAdapterMouseEvent& dest, bool ctrlPressed, bool shiftPressed, bool altPressed, const SDL_Event& source);
236
237 void ConvertFromPlatform(GuiAdapterWheelEvent& dest, bool ctrlPressed, bool shiftPressed, bool altPressed, const SDL_Event& source);
238
239 void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const SDL_Event& source);
240
241 # endif
242
243 #endif
244
245 typedef void (*GuiAdapterRunFunc)(void*);
246
247 class GuiAdapter
248 {
249 public:
250 GuiAdapter()
251 {
252 static int instanceCount = 0;
253 ORTHANC_ASSERT(instanceCount == 0);
254 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 }