comparison Samples/WebAssembly/BasicScene.cpp @ 618:0925b27e8750

mouse events in wasm sample
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 02 May 2019 18:58:46 +0200
parents 7efa2543699d
children ea8322566596
comparison
equal deleted inserted replaced
617:7efa2543699d 618:0925b27e8750
36 #include "../../Framework/OpenGL/WebAssemblyOpenGLContext.h" 36 #include "../../Framework/OpenGL/WebAssemblyOpenGLContext.h"
37 37
38 // From Orthanc framework 38 // From Orthanc framework
39 #include <Core/Images/Image.h> 39 #include <Core/Images/Image.h>
40 #include <Core/Logging.h> 40 #include <Core/Logging.h>
41 #include <Core/OrthancException.h>
41 42
42 #include <stdio.h> 43 #include <stdio.h>
43 44
44 static const unsigned int FONT_SIZE = 32; 45 static const unsigned int FONT_SIZE = 32;
45 46
140 141
141 142
142 143
143 namespace OrthancStone 144 namespace OrthancStone
144 { 145 {
145 class WebAssemblyCanvas : public boost::noncopyable 146 class WebAssemblyViewport : public boost::noncopyable
146 { 147 {
147 private: 148 private:
148 OpenGL::WebAssemblyOpenGLContext context_; 149 OpenGL::WebAssemblyOpenGLContext context_;
149 Scene2D scene_; 150 Scene2D scene_;
150 OpenGLCompositor compositor_; 151 OpenGLCompositor compositor_;
151 152
152 void SetupEvents(const std::string& canvas); 153 void SetupEvents(const std::string& canvas);
153 154
154 public: 155 public:
155 WebAssemblyCanvas(const std::string& canvas) : 156 WebAssemblyViewport(const std::string& canvas) :
156 context_(canvas), 157 context_(canvas),
157 compositor_(context_, scene_) 158 compositor_(context_, scene_)
158 { 159 {
159 compositor_.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, 160 compositor_.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT,
160 FONT_SIZE, Orthanc::Encoding_Latin1); 161 FONT_SIZE, Orthanc::Encoding_Latin1);
184 } 185 }
185 186
186 ScenePoint2D GetPixelCenterCoordinates(int x, int y) const 187 ScenePoint2D GetPixelCenterCoordinates(int x, int y) const
187 { 188 {
188 return compositor_.GetPixelCenterCoordinates(x, y); 189 return compositor_.GetPixelCenterCoordinates(x, y);
190 }
191
192 unsigned int GetCanvasWidth() const
193 {
194 return context_.GetCanvasWidth();
195 }
196
197 unsigned int GetCanvasHeight() const
198 {
199 return context_.GetCanvasHeight();
189 } 200 }
190 }; 201 };
191 202
192 203
193 204
198 std::string canvasIdentifier_; 209 std::string canvasIdentifier_;
199 bool insideCanvas_; 210 bool insideCanvas_;
200 211
201 public: 212 public:
202 ActiveTracker(IPointerTracker* tracker, 213 ActiveTracker(IPointerTracker* tracker,
203 const WebAssemblyCanvas& canvas) : 214 const WebAssemblyViewport& viewport) :
204 tracker_(tracker), 215 tracker_(tracker),
205 canvasIdentifier_(canvas.GetCanvasIdentifier()), 216 canvasIdentifier_(viewport.GetCanvasIdentifier()),
206 insideCanvas_(true) 217 insideCanvas_(true)
207 { 218 {
219 if (tracker_.get() == NULL)
220 {
221 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
222 }
223 }
224
225 void Update(const PointerEvent& event)
226 {
227 tracker_->Update(event);
228 }
229
230 void Release()
231 {
232 tracker_->Release();
208 } 233 }
209 }; 234 };
210 } 235 }
211 236
212 237
213 238
214 static OrthancStone::PointerEvent* ConvertMouseEvent(const EmscriptenMouseEvent& source, 239 static OrthancStone::PointerEvent* ConvertMouseEvent(const EmscriptenMouseEvent& source,
215 OrthancStone::WebAssemblyCanvas& canvas) 240 OrthancStone::WebAssemblyViewport& viewport)
216 { 241 {
217 std::auto_ptr<OrthancStone::PointerEvent> target(new OrthancStone::PointerEvent); 242 std::auto_ptr<OrthancStone::PointerEvent> target(new OrthancStone::PointerEvent);
218 243
219 target->AddPosition(canvas.GetPixelCenterCoordinates(source.clientX, source.clientY)); 244 target->AddPosition(viewport.GetPixelCenterCoordinates(source.targetX, source.targetY));
220 target->SetAltModifier(source.altKey); 245 target->SetAltModifier(source.altKey);
221 target->SetControlModifier(source.ctrlKey); 246 target->SetControlModifier(source.ctrlKey);
222 target->SetShiftModifier(source.shiftKey); 247 target->SetShiftModifier(source.shiftKey);
223 248
224 return target.release(); 249 return target.release();
225 } 250 }
226 251
227 252
253 std::auto_ptr<OrthancStone::ActiveTracker> tracker_;
254
255
228 EM_BOOL OnMouseEvent(int eventType, 256 EM_BOOL OnMouseEvent(int eventType,
229 const EmscriptenMouseEvent *mouseEvent, 257 const EmscriptenMouseEvent *mouseEvent,
230 void *userData) 258 void *userData)
231 { 259 {
232 if (userData != NULL) 260 if (mouseEvent != NULL &&
233 { 261 userData != NULL)
234 OrthancStone::WebAssemblyCanvas& canvas = *reinterpret_cast<OrthancStone::WebAssemblyCanvas*>(userData); 262 {
263 OrthancStone::WebAssemblyViewport& viewport =
264 *reinterpret_cast<OrthancStone::WebAssemblyViewport*>(userData);
235 265
236 switch (eventType) 266 switch (eventType)
237 { 267 {
238 case EMSCRIPTEN_EVENT_CLICK: 268 case EMSCRIPTEN_EVENT_CLICK:
239 { 269 {
241 char buf[64]; 271 char buf[64];
242 sprintf(buf, "click %d", count++); 272 sprintf(buf, "click %d", count++);
243 273
244 std::auto_ptr<OrthancStone::TextSceneLayer> layer(new OrthancStone::TextSceneLayer); 274 std::auto_ptr<OrthancStone::TextSceneLayer> layer(new OrthancStone::TextSceneLayer);
245 layer->SetText(buf); 275 layer->SetText(buf);
246 canvas.GetScene().SetLayer(100, layer.release()); 276 viewport.GetScene().SetLayer(100, layer.release());
247 canvas.Refresh(); 277 viewport.Refresh();
248 break; 278 break;
249 } 279 }
250 280
251 case EMSCRIPTEN_EVENT_MOUSEDOWN: 281 case EMSCRIPTEN_EVENT_MOUSEDOWN:
252 LOG(ERROR) << "Mouse down"; 282 {
283 std::auto_ptr<OrthancStone::IPointerTracker> t;
284
285 {
286 std::auto_ptr<OrthancStone::PointerEvent> event(ConvertMouseEvent(*mouseEvent, viewport));
287
288 switch (mouseEvent->button)
289 {
290 case 0: // Left button
291 t.reset(new OrthancStone::RotateSceneTracker(viewport.GetScene(), *event));
292 break;
293
294 case 1: // Middle button
295 t.reset(new OrthancStone::PanSceneTracker(viewport.GetScene(), *event));
296 break;
297
298 case 2: // Right button
299 t.reset(new OrthancStone::ZoomSceneTracker
300 (viewport.GetScene(), *event, viewport.GetCanvasWidth()));
301 break;
302
303 default:
304 break;
305 }
306 }
307
308 if (t.get() != NULL)
309 {
310 tracker_.reset(new OrthancStone::ActiveTracker(t.release(), viewport));
311 viewport.Refresh();
312 }
313
314 break;
315 }
316
317 case EMSCRIPTEN_EVENT_MOUSEMOVE:
318 if (tracker_.get() != NULL)
319 {
320 std::auto_ptr<OrthancStone::PointerEvent> event(ConvertMouseEvent(*mouseEvent, viewport));
321 tracker_->Update(*event);
322 viewport.Refresh();
323 }
324 break;
325
326 case EMSCRIPTEN_EVENT_MOUSEUP:
327 if (tracker_.get() != NULL)
328 {
329 tracker_->Release();
330 viewport.Refresh();
331 tracker_.reset();
332 }
253 break; 333 break;
254 334
255 default: 335 default:
256 break; 336 break;
257 } 337 }
259 339
260 return true; 340 return true;
261 } 341 }
262 342
263 343
264 void OrthancStone::WebAssemblyCanvas::SetupEvents(const std::string& canvas) 344 void OrthancStone::WebAssemblyViewport::SetupEvents(const std::string& canvas)
265 { 345 {
266 emscripten_set_click_callback(canvas.c_str(), this, false, OnMouseEvent); 346 //emscripten_set_click_callback(canvas.c_str(), this, false, OnMouseEvent);
267 //emscripten_set_mousedown_callback(canvas.c_str(), this, false, OnMouseEvent); 347 emscripten_set_mousedown_callback(canvas.c_str(), this, false, OnMouseEvent);
268 } 348 emscripten_set_mousemove_callback(canvas.c_str(), this, false, OnMouseEvent);
269 349 emscripten_set_mouseup_callback(canvas.c_str(), this, false, OnMouseEvent);
270 350 }
271 351
272 352
273 std::auto_ptr<OrthancStone::WebAssemblyCanvas> canvas1_; 353
274 std::auto_ptr<OrthancStone::WebAssemblyCanvas> canvas2_; 354
275 std::auto_ptr<OrthancStone::WebAssemblyCanvas> canvas3_; 355 std::auto_ptr<OrthancStone::WebAssemblyViewport> viewport1_;
276 std::auto_ptr<OrthancStone::ActiveTracker> tracker_; 356 std::auto_ptr<OrthancStone::WebAssemblyViewport> viewport2_;
357 std::auto_ptr<OrthancStone::WebAssemblyViewport> viewport3_;
277 358
278 359
279 EM_BOOL OnWindowResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData) 360 EM_BOOL OnWindowResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData)
280 { 361 {
281 if (canvas1_.get() != NULL) 362 if (viewport1_.get() != NULL)
282 { 363 {
283 canvas1_->UpdateSize(); 364 viewport1_->UpdateSize();
284 } 365 }
285 366
286 if (canvas2_.get() != NULL) 367 if (viewport2_.get() != NULL)
287 { 368 {
288 canvas2_->UpdateSize(); 369 viewport2_->UpdateSize();
289 } 370 }
290 371
291 if (canvas3_.get() != NULL) 372 if (viewport3_.get() != NULL)
292 { 373 {
293 canvas3_->UpdateSize(); 374 viewport3_->UpdateSize();
294 } 375 }
295 376
296 return true; 377 return true;
297 } 378 }
298 379
307 } 388 }
308 389
309 EMSCRIPTEN_KEEPALIVE 390 EMSCRIPTEN_KEEPALIVE
310 void Initialize() 391 void Initialize()
311 { 392 {
312 canvas1_.reset(new OrthancStone::WebAssemblyCanvas("mycanvas1")); 393 viewport1_.reset(new OrthancStone::WebAssemblyViewport("mycanvas1"));
313 PrepareScene(canvas1_->GetScene()); 394 PrepareScene(viewport1_->GetScene());
314 canvas1_->UpdateSize(); 395 viewport1_->UpdateSize();
315 396
316 canvas2_.reset(new OrthancStone::WebAssemblyCanvas("mycanvas2")); 397 viewport2_.reset(new OrthancStone::WebAssemblyViewport("mycanvas2"));
317 PrepareScene(canvas2_->GetScene()); 398 PrepareScene(viewport2_->GetScene());
318 canvas2_->UpdateSize(); 399 viewport2_->UpdateSize();
319 400
320 canvas3_.reset(new OrthancStone::WebAssemblyCanvas("mycanvas3")); 401 viewport3_.reset(new OrthancStone::WebAssemblyViewport("mycanvas3"));
321 PrepareScene(canvas3_->GetScene()); 402 PrepareScene(viewport3_->GetScene());
322 canvas3_->UpdateSize(); 403 viewport3_->UpdateSize();
323 404
324 emscripten_set_resize_callback("#window", NULL, false, OnWindowResize); 405 emscripten_set_resize_callback("#window", NULL, false, OnWindowResize);
325 } 406 }
326 } 407 }