Mercurial > hg > orthanc-stone
comparison Applications/Generic/GuiAdapter.cpp @ 1370:28eb7106ef44 broker
Changes to GuiAdapter to allow it to work correctly with both new and old
Emscripten event selection rules that are defined by the DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR linker flag.
Doc has been added to GuiAdapter.cpp, should you require more info on
what has been done.
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Mon, 20 Apr 2020 13:08:43 +0200 |
parents | d80a3e3cc800 |
children | f15529add7b0 |
comparison
equal
deleted
inserted
replaced
1369:aadc374bc006 | 1370:28eb7106ef44 |
---|---|
145 } | 145 } |
146 | 146 |
147 template<typename GenericFunc> | 147 template<typename GenericFunc> |
148 struct FuncAdapterPayload | 148 struct FuncAdapterPayload |
149 { | 149 { |
150 std::string canvasId; | 150 std::string canvasCssSelector; |
151 void* userData; | 151 void* userData; |
152 GenericFunc callback; | 152 GenericFunc callback; |
153 }; | 153 }; |
154 | 154 |
155 template<typename GenericFunc, | 155 template<typename GenericFunc, |
156 typename GuiAdapterEvent, | 156 typename GuiAdapterEvent, |
157 typename EmscriptenEvent> | 157 typename EmscriptenEvent> |
158 EM_BOOL OnEventAdapterFunc( | 158 EM_BOOL OnEventAdapterFunc( |
159 int eventType, const EmscriptenEvent* emEvent, void* userData) | 159 int eventType, const EmscriptenEvent* emEvent, void* userData) |
160 { | 160 { |
161 | |
162 // userData is OnMouseWheelFuncAdapterPayload | 161 // userData is OnMouseWheelFuncAdapterPayload |
163 FuncAdapterPayload<GenericFunc>* payload = | 162 FuncAdapterPayload<GenericFunc>* payload = |
164 reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData); | 163 reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData); |
165 // LOG(INFO) << "OnEventAdapterFunc"; | 164 // LOG(INFO) << "OnEventAdapterFunc"; |
166 // LOG(INFO) << "------------------"; | 165 // LOG(INFO) << "------------------"; |
168 // (int)wheelEvent << " userData: " << userData << | 167 // (int)wheelEvent << " userData: " << userData << |
169 // " payload->userData: " << payload->userData; | 168 // " payload->userData: " << payload->userData; |
170 | 169 |
171 GuiAdapterEvent guiEvent; | 170 GuiAdapterEvent guiEvent; |
172 ConvertFromPlatform(guiEvent, eventType, *emEvent); | 171 ConvertFromPlatform(guiEvent, eventType, *emEvent); |
173 bool ret = (*(payload->callback))(payload->canvasId, &guiEvent, payload->userData); | 172 bool ret = (*(payload->callback))(payload->canvasCssSelector, &guiEvent, payload->userData); |
174 return static_cast<EM_BOOL>(ret); | 173 return static_cast<EM_BOOL>(ret); |
175 } | 174 } |
176 | 175 |
177 template<typename GenericFunc, | 176 template<typename GenericFunc, |
178 typename GuiAdapterEvent, | 177 typename GuiAdapterEvent, |
184 FuncAdapterPayload<GenericFunc>* payload = | 183 FuncAdapterPayload<GenericFunc>* payload = |
185 reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData); | 184 reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData); |
186 | 185 |
187 GuiAdapterEvent guiEvent; | 186 GuiAdapterEvent guiEvent; |
188 ConvertFromPlatform(guiEvent, *wheelEvent); | 187 ConvertFromPlatform(guiEvent, *wheelEvent); |
189 bool ret = (*(payload->callback))(payload->canvasId, &guiEvent, payload->userData); | 188 bool ret = (*(payload->callback))(payload->canvasCssSelector, &guiEvent, payload->userData); |
190 return static_cast<EM_BOOL>(ret); | 189 return static_cast<EM_BOOL>(ret); |
191 } | 190 } |
192 | 191 |
193 template<typename GenericFunc> | 192 template<typename GenericFunc> |
194 EM_BOOL OnEventAdapterFunc3( | 193 EM_BOOL OnEventAdapterFunc3( |
198 FuncAdapterPayload<GenericFunc>* payload = | 197 FuncAdapterPayload<GenericFunc>* payload = |
199 reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData); | 198 reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData); |
200 //std::unique_ptr< FuncAdapterPayload<GenericFunc> > deleter(payload); | 199 //std::unique_ptr< FuncAdapterPayload<GenericFunc> > deleter(payload); |
201 bool ret = (*(payload->callback))(time, payload->userData); | 200 bool ret = (*(payload->callback))(time, payload->userData); |
202 return static_cast<EM_BOOL>(ret); | 201 return static_cast<EM_BOOL>(ret); |
202 } | |
203 | |
204 /* | |
205 | |
206 Explanation | |
207 =========== | |
208 | |
209 - in "older" Emscripten, where DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR doesn't exist or is set to 0, | |
210 the following strings need to be used to register events: | |
211 - for canvas, the canvas DOM id. In case of <canvas id="mycanvas1" width='640' ...></canvas>", the string needs | |
212 to be "mycanvas" | |
213 - for the window (for key events), the string needs to be "#window" | |
214 - in newer Emscripten where DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR==1 (or maybe is not there anymore, in the | |
215 future as of 2020-04-20) | |
216 - for canvas, the canvas DOM id. In case of <canvas id="mycanvas1" width='640' ...></canvas>", the string needs | |
217 to be "#mycanvas" (notice the "number sign", aka "hash", NOT AKA "sharp", as can be read on https://en.wikipedia.org/wiki/Number_sign) | |
218 - for the window (for key events), the string needs to be EMSCRIPTEN_EVENT_TARGET_WINDOW. I do not mean | |
219 "EMSCRIPTEN_EVENT_TARGET_WINDOW", but the #define EMSCRIPTEN_EVENT_TARGET_WINDOW ((const char*)2) that | |
220 can be found in emscripten/html5.h | |
221 | |
222 The code below converts the input canvasId (as in the old emscripten) to the emscripten-compliant one, with the | |
223 following compile condition : #if DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR == 1 | |
224 | |
225 If the DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR build parameter disappears, you might want to refactor this code | |
226 or continue to pass the DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR compile macro (which is different from the CMake | |
227 variable) | |
228 | |
229 What we are doing below: | |
230 - in older Emscripten, the registration functions will receive "mycanvas" and "#window" and the callbacks will receive | |
231 the same std::string in their payload ("mycanvas" and "#window") | |
232 | |
233 - in newer Emscripten, the registration functions will receive "#mycanvas" and EMSCRIPTEN_EVENT_TARGET_WINDOW, but | |
234 the callbacks will receive "#mycanvas" and "#window" (since it is not possible to store the EMSCRIPTEN_EVENT_TARGET_WINDOW | |
235 magic value in an std::string, while we still want the callback to be able to change its behavior according to the | |
236 target element. | |
237 | |
238 */ | |
239 | |
240 void convertElementTarget(const char*& outCanvasCssSelectorSz, std::string& outCanvasCssSelector, const std::string& canvasId) | |
241 { | |
242 // only "#window" can start with a # | |
243 if (canvasId[0] == '#') | |
244 { | |
245 ORTHANC_ASSERT(canvasId == "#window"); | |
246 } | |
247 #if DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR == 1 | |
248 if (canvasId == "#window") | |
249 { | |
250 // we store this in the payload so that the callback can | |
251 outCanvasCssSelector = "#window"; | |
252 outCanvasCssSelectorSz = EMSCRIPTEN_EVENT_TARGET_WINDOW; | |
253 } | |
254 else | |
255 { | |
256 outCanvasCssSelector = "#" + canvasId; | |
257 outCanvasCssSelectorSz = outCanvasCssSelector.c_str(); | |
258 } | |
259 #else | |
260 if (canvasId == "#window") | |
261 { | |
262 // we store this in the payload so that the callback can | |
263 outCanvasCssSelector = "#window"; | |
264 outCanvasCssSelectorSz = outCanvasCssSelector.c_str();; | |
265 } | |
266 else | |
267 { | |
268 outCanvasCssSelector = canvasId; | |
269 outCanvasCssSelectorSz = outCanvasCssSelector.c_str();; | |
270 } | |
271 #endif | |
203 } | 272 } |
204 | 273 |
205 // resize: (const char* target, void* userData, EM_BOOL useCapture, em_ui_callback_func callback) | 274 // resize: (const char* target, void* userData, EM_BOOL useCapture, em_ui_callback_func callback) |
206 template< | 275 template< |
207 typename GenericFunc, | 276 typename GenericFunc, |
210 typename EmscriptenSetCallbackFunc> | 279 typename EmscriptenSetCallbackFunc> |
211 static void SetCallback( | 280 static void SetCallback( |
212 EmscriptenSetCallbackFunc emFunc, | 281 EmscriptenSetCallbackFunc emFunc, |
213 std::string canvasId, void* userData, bool capture, GenericFunc func) | 282 std::string canvasId, void* userData, bool capture, GenericFunc func) |
214 { | 283 { |
215 // TODO: write RemoveCallback with an int id that gets returned from | 284 std::string canvasCssSelector; |
216 // here | 285 const char* canvasCssSelectorSz = NULL; |
217 FuncAdapterPayload<GenericFunc>* payload = | 286 convertElementTarget(canvasCssSelectorSz, canvasCssSelector, canvasId); |
218 new FuncAdapterPayload<GenericFunc>(); | 287 |
219 std::unique_ptr<FuncAdapterPayload<GenericFunc> > payloadP(payload); | 288 // TODO: write RemoveCallback with an int id that gets returned from here |
220 payload->canvasId = canvasId; | 289 |
290 // create userdata payload | |
291 std::unique_ptr<FuncAdapterPayload<GenericFunc> > payload(new FuncAdapterPayload<GenericFunc>()); | |
292 payload->canvasCssSelector = canvasCssSelector; | |
221 payload->callback = func; | 293 payload->callback = func; |
222 payload->userData = userData; | 294 payload->userData = userData; |
223 void* userDataRaw = reinterpret_cast<void*>(payload); | 295 void* userDataRaw = reinterpret_cast<void*>(payload.release()); |
224 // LOG(INFO) << "SetCallback -- userDataRaw: " << userDataRaw << | 296 |
225 // " payload: " << payload << " payload->userData: " << payload->userData; | 297 // call the registration function |
226 (*emFunc)( | 298 (*emFunc)( |
227 canvasId.c_str(), | 299 canvasCssSelectorSz, |
228 userDataRaw, | 300 userDataRaw, |
229 static_cast<EM_BOOL>(capture), | 301 static_cast<EM_BOOL>(capture), |
230 &OnEventAdapterFunc<GenericFunc, GuiAdapterEvent, EmscriptenEvent>, | 302 &OnEventAdapterFunc<GenericFunc, GuiAdapterEvent, EmscriptenEvent>, |
231 EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD); | 303 EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD); |
232 payloadP.release(); | |
233 } | 304 } |
234 | 305 |
235 template< | 306 template< |
236 typename GenericFunc, | 307 typename GenericFunc, |
237 typename GuiAdapterEvent, | 308 typename GuiAdapterEvent, |
239 typename EmscriptenSetCallbackFunc> | 310 typename EmscriptenSetCallbackFunc> |
240 static void SetCallback2( | 311 static void SetCallback2( |
241 EmscriptenSetCallbackFunc emFunc, | 312 EmscriptenSetCallbackFunc emFunc, |
242 std::string canvasId, void* userData, bool capture, GenericFunc func) | 313 std::string canvasId, void* userData, bool capture, GenericFunc func) |
243 { | 314 { |
244 std::unique_ptr<FuncAdapterPayload<GenericFunc> > payload( | 315 std::string canvasCssSelector; |
245 new FuncAdapterPayload<GenericFunc>() | 316 const char* canvasCssSelectorSz = NULL; |
246 ); | 317 convertElementTarget(canvasCssSelectorSz, canvasCssSelector, canvasId); |
247 payload->canvasId = canvasId; | 318 |
319 // TODO: write RemoveCallback with an int id that gets returned from here | |
320 | |
321 // create userdata payload | |
322 std::unique_ptr<FuncAdapterPayload<GenericFunc> > payload(new FuncAdapterPayload<GenericFunc>()); | |
323 payload->canvasCssSelector = canvasCssSelector; | |
248 payload->callback = func; | 324 payload->callback = func; |
249 payload->userData = userData; | 325 payload->userData = userData; |
250 void* userDataRaw = reinterpret_cast<void*>(payload.release()); | 326 void* userDataRaw = reinterpret_cast<void*>(payload.release()); |
327 | |
328 // call the registration function | |
251 (*emFunc)( | 329 (*emFunc)( |
252 canvasId.c_str(), | 330 canvasCssSelectorSz, |
253 userDataRaw, | 331 userDataRaw, |
254 static_cast<EM_BOOL>(capture), | 332 static_cast<EM_BOOL>(capture), |
255 &OnEventAdapterFunc2<GenericFunc, GuiAdapterEvent, EmscriptenEvent>, | 333 &OnEventAdapterFunc2<GenericFunc, GuiAdapterEvent, EmscriptenEvent>, |
256 EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD); | 334 EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD); |
257 } | 335 } |
264 void* userData, GenericFunc func) | 342 void* userData, GenericFunc func) |
265 { | 343 { |
266 std::unique_ptr<FuncAdapterPayload<GenericFunc> > payload( | 344 std::unique_ptr<FuncAdapterPayload<GenericFunc> > payload( |
267 new FuncAdapterPayload<GenericFunc>() | 345 new FuncAdapterPayload<GenericFunc>() |
268 ); | 346 ); |
269 payload->canvasId = "UNDEFINED"; | 347 payload->canvasCssSelector = "UNDEFINED"; |
270 payload->callback = func; | 348 payload->callback = func; |
271 payload->userData = userData; | 349 payload->userData = userData; |
272 void* userDataRaw = reinterpret_cast<void*>(payload.release()); | 350 void* userDataRaw = reinterpret_cast<void*>(payload.release()); |
273 (*emFunc)( | 351 (*emFunc)( |
274 &OnEventAdapterFunc3<GenericFunc>, | 352 &OnEventAdapterFunc3<GenericFunc>, |