comparison Applications/Generic/GuiAdapter.cpp @ 858:e3c56d4f863f

GuiAdapter : mouse event routing in SDL + split the undo stack from the ViewportController for multi-canvas apps + adapted the samples to this change
author Benjamin Golinvaux <bgo@osimis.io>
date Mon, 24 Jun 2019 10:31:04 +0200
parents bb88686acecc
children f0bf971a1e31 12b591d5d63c
comparison
equal deleted inserted replaced
855:41d22389a7d2 858:e3c56d4f863f
39 void GuiAdapter::RegisterWidget(boost::shared_ptr<IGuiAdapterWidget> widget) 39 void GuiAdapter::RegisterWidget(boost::shared_ptr<IGuiAdapterWidget> widget)
40 { 40 {
41 widgets_.push_back(widget); 41 widgets_.push_back(widget);
42 } 42 }
43 43
44 std::ostream& operator<<(
45 std::ostream& os, const GuiAdapterKeyboardEvent& event)
46 {
47 os << "ctrl: " << event.ctrlKey << ", " <<
48 "shift: " << event.shiftKey << ", " <<
49 "alt: " << event.altKey;
50 return os;
51 }
52
44 #if ORTHANC_ENABLE_WASM == 1 53 #if ORTHANC_ENABLE_WASM == 1
45 void GuiAdapter::Run() 54 void GuiAdapter::Run()
46 { 55 {
47 } 56 }
48 57
139 } 148 }
140 149
141 template<typename GenericFunc> 150 template<typename GenericFunc>
142 struct FuncAdapterPayload 151 struct FuncAdapterPayload
143 { 152 {
144 void* userData; 153 std::string canvasId;
154 void* userData;
145 GenericFunc callback; 155 GenericFunc callback;
146 }; 156 };
147 157
148 template<typename GenericFunc, 158 template<typename GenericFunc,
149 typename GuiAdapterEvent, 159 typename GuiAdapterEvent,
150 typename EmscriptenEvent> 160 typename EmscriptenEvent>
151 EM_BOOL OnEventAdapterFunc( 161 EM_BOOL OnEventAdapterFunc(
152 int eventType, const EmscriptenEvent* wheelEvent, void* userData) 162 int eventType, const EmscriptenEvent* emEvent, void* userData)
153 { 163 {
154 164
155 // userData is OnMouseWheelFuncAdapterPayload 165 // userData is OnMouseWheelFuncAdapterPayload
156 FuncAdapterPayload<GenericFunc>* payload = 166 FuncAdapterPayload<GenericFunc>* payload =
157 reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData); 167 reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData);
160 // LOG(INFO) << "eventType: " << eventType << " wheelEvent: " << 170 // LOG(INFO) << "eventType: " << eventType << " wheelEvent: " <<
161 // (int)wheelEvent << " userData: " << userData << 171 // (int)wheelEvent << " userData: " << userData <<
162 // " payload->userData: " << payload->userData; 172 // " payload->userData: " << payload->userData;
163 173
164 GuiAdapterEvent guiEvent; 174 GuiAdapterEvent guiEvent;
165 ConvertFromPlatform(guiEvent, eventType, *wheelEvent); 175 ConvertFromPlatform(guiEvent, eventType, *emEvent);
166 bool ret = (*(payload->callback))(&guiEvent, payload->userData); 176 bool ret = (*(payload->callback))(payload->canvasId, &guiEvent, payload->userData);
167 return static_cast<EM_BOOL>(ret); 177 return static_cast<EM_BOOL>(ret);
168 } 178 }
169 179
170 template<typename GenericFunc, 180 template<typename GenericFunc,
171 typename GuiAdapterEvent, 181 typename GuiAdapterEvent,
177 FuncAdapterPayload<GenericFunc>* payload = 187 FuncAdapterPayload<GenericFunc>* payload =
178 reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData); 188 reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData);
179 189
180 GuiAdapterEvent guiEvent; 190 GuiAdapterEvent guiEvent;
181 ConvertFromPlatform(guiEvent, *wheelEvent); 191 ConvertFromPlatform(guiEvent, *wheelEvent);
182 bool ret = (*(payload->callback))(&guiEvent, payload->userData); 192 bool ret = (*(payload->callback))(payload->canvasId, &guiEvent, payload->userData);
183 return static_cast<EM_BOOL>(ret); 193 return static_cast<EM_BOOL>(ret);
184 } 194 }
185 195
186 template<typename GenericFunc> 196 template<typename GenericFunc>
187 EM_BOOL OnEventAdapterFunc3( 197 EM_BOOL OnEventAdapterFunc3(
208 // TODO: write RemoveCallback with an int id that gets returned from 218 // TODO: write RemoveCallback with an int id that gets returned from
209 // here 219 // here
210 FuncAdapterPayload<GenericFunc>* payload = 220 FuncAdapterPayload<GenericFunc>* payload =
211 new FuncAdapterPayload<GenericFunc>(); 221 new FuncAdapterPayload<GenericFunc>();
212 std::auto_ptr<FuncAdapterPayload<GenericFunc> > payloadP(payload); 222 std::auto_ptr<FuncAdapterPayload<GenericFunc> > payloadP(payload);
223 payload->canvasId = canvasId;
213 payload->callback = func; 224 payload->callback = func;
214 payload->userData = userData; 225 payload->userData = userData;
215 void* userDataRaw = reinterpret_cast<void*>(payload); 226 void* userDataRaw = reinterpret_cast<void*>(payload);
216 // LOG(INFO) << "SetCallback -- userDataRaw: " << userDataRaw << 227 // LOG(INFO) << "SetCallback -- userDataRaw: " << userDataRaw <<
217 // " payload: " << payload << " payload->userData: " << payload->userData; 228 // " payload: " << payload << " payload->userData: " << payload->userData;
234 std::string canvasId, void* userData, bool capture, GenericFunc func) 245 std::string canvasId, void* userData, bool capture, GenericFunc func)
235 { 246 {
236 std::auto_ptr<FuncAdapterPayload<GenericFunc> > payload( 247 std::auto_ptr<FuncAdapterPayload<GenericFunc> > payload(
237 new FuncAdapterPayload<GenericFunc>() 248 new FuncAdapterPayload<GenericFunc>()
238 ); 249 );
250 payload->canvasId = canvasId;
239 payload->callback = func; 251 payload->callback = func;
240 payload->userData = userData; 252 payload->userData = userData;
241 void* userDataRaw = reinterpret_cast<void*>(payload.release()); 253 void* userDataRaw = reinterpret_cast<void*>(payload.release());
242 (*emFunc)( 254 (*emFunc)(
243 canvasId.c_str(), 255 canvasId.c_str(),
248 } 260 }
249 261
250 template< 262 template<
251 typename GenericFunc, 263 typename GenericFunc,
252 typename EmscriptenSetCallbackFunc> 264 typename EmscriptenSetCallbackFunc>
253 static void SetCallback3( 265 static void SetAnimationFrameCallback(
254 EmscriptenSetCallbackFunc emFunc, 266 EmscriptenSetCallbackFunc emFunc,
255 void* userData, GenericFunc func) 267 void* userData, GenericFunc func)
256 { 268 {
257 // LOG(ERROR) << "SetCallback3 !!!!!! (RequestAnimationFrame)"; 269 // LOG(ERROR) << "SetAnimationFrameCallback !!!!!! (RequestAnimationFrame)";
258 std::auto_ptr<FuncAdapterPayload<GenericFunc> > payload( 270 std::auto_ptr<FuncAdapterPayload<GenericFunc> > payload(
259 new FuncAdapterPayload<GenericFunc>() 271 new FuncAdapterPayload<GenericFunc>()
260 ); 272 );
273 payload->canvasId = "UNDEFINED";
261 payload->callback = func; 274 payload->callback = func;
262 payload->userData = userData; 275 payload->userData = userData;
263 void* userDataRaw = reinterpret_cast<void*>(payload.release()); 276 void* userDataRaw = reinterpret_cast<void*>(payload.release());
264 (*emFunc)( 277 (*emFunc)(
265 &OnEventAdapterFunc3<GenericFunc>, 278 &OnEventAdapterFunc3<GenericFunc>,
350 OnAnimationFrameFunc func, void* userData) 363 OnAnimationFrameFunc func, void* userData)
351 { 364 {
352 // LOG(ERROR) << "-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+"; 365 // LOG(ERROR) << "-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+";
353 // LOG(ERROR) << "RequestAnimationFrame"; 366 // LOG(ERROR) << "RequestAnimationFrame";
354 // LOG(ERROR) << "-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+"; 367 // LOG(ERROR) << "-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+";
355 SetCallback3<OnAnimationFrameFunc>( 368 SetAnimationFrameCallback<OnAnimationFrameFunc>(
356 &emscripten_request_animation_frame_loop, 369 &emscripten_request_animation_frame_loop,
357 userData, 370 userData,
358 func); 371 func);
359 } 372 }
360 373
382 #endif 395 #endif
383 396
384 397
385 #else 398 #else
386 399
400 // SDL ONLY
387 void ConvertFromPlatform( 401 void ConvertFromPlatform(
388 GuiAdapterMouseEvent& dest, 402 GuiAdapterMouseEvent& dest,
389 bool ctrlPressed, bool shiftPressed, bool altPressed, 403 bool ctrlPressed, bool shiftPressed, bool altPressed,
390 const SDL_Event& source) 404 const SDL_Event& source)
391 { 405 {
398 case SDL_MOUSEMOTION: 412 case SDL_MOUSEMOTION:
399 dest.type = GUIADAPTER_EVENT_MOUSEMOVE; 413 dest.type = GUIADAPTER_EVENT_MOUSEMOVE;
400 break; 414 break;
401 case SDL_MOUSEBUTTONUP: 415 case SDL_MOUSEBUTTONUP:
402 dest.type = GUIADAPTER_EVENT_MOUSEUP; 416 dest.type = GUIADAPTER_EVENT_MOUSEUP;
417 break;
418 case SDL_MOUSEWHEEL:
419 dest.type = GUIADAPTER_EVENT_WHEEL;
403 break; 420 break;
404 default: 421 default:
405 LOG(ERROR) << "SDL event: " << source.type << " is not supported"; 422 LOG(ERROR) << "SDL event: " << source.type << " is not supported";
406 ORTHANC_ASSERT(false, "Not supported"); 423 ORTHANC_ASSERT(false, "Not supported");
407 } 424 }
439 //dest.canvasX = src.canvasX; 456 //dest.canvasX = src.canvasX;
440 //dest.canvasY = src.canvasY; 457 //dest.canvasY = src.canvasY;
441 //dest.padding = src.padding; 458 //dest.padding = src.padding;
442 } 459 }
443 460
461 void ConvertFromPlatform(
462 GuiAdapterWheelEvent& dest,
463 bool ctrlPressed, bool shiftPressed, bool altPressed,
464 const SDL_Event& source)
465 {
466 ConvertFromPlatform(dest.mouse, ctrlPressed, shiftPressed, altPressed, source);
467 dest.deltaX = source.wheel.x;
468 dest.deltaY = source.wheel.y;
469 }
470
471
472
473 // SDL ONLY
444 void GuiAdapter::SetResizeCallback( 474 void GuiAdapter::SetResizeCallback(
445 std::string canvasId, void* userData, bool capture, OnWindowResizeFunc func) 475 std::string canvasId, void* userData, bool capture, OnWindowResizeFunc func)
446 { 476 {
447 resizeHandlers_.push_back(std::make_pair(func, userData)); 477 resizeHandlers_.push_back(EventHandlerData<OnWindowResizeFunc>(canvasId, func, userData));
448 } 478 }
449 479
480 // SDL ONLY
450 void GuiAdapter::SetMouseDownCallback( 481 void GuiAdapter::SetMouseDownCallback(
451 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) 482 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func)
452 { 483 {
484 mouseDownHandlers_.push_back(EventHandlerData<OnMouseEventFunc>(canvasId, func, userData));
453 } 485 }
454 486
487 // SDL ONLY
455 void GuiAdapter::SetMouseMoveCallback( 488 void GuiAdapter::SetMouseMoveCallback(
456 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) 489 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func)
457 { 490 {
458 } 491 mouseMoveHandlers_.push_back(EventHandlerData<OnMouseEventFunc>(canvasId, func, userData));
459 492 }
493
494 // SDL ONLY
460 void GuiAdapter::SetMouseUpCallback( 495 void GuiAdapter::SetMouseUpCallback(
461 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) 496 std::string canvasId, void* userData, bool capture, OnMouseEventFunc func)
462 { 497 {
463 } 498 mouseUpHandlers_.push_back(EventHandlerData<OnMouseEventFunc>(canvasId, func, userData));
464 499 }
465 void GuiAdapter::SetWheelCallback( 500
501 // SDL ONLY
502 void GuiAdapter::SetWheelCallback(
466 std::string canvasId, void* userData, bool capture, OnMouseWheelFunc func) 503 std::string canvasId, void* userData, bool capture, OnMouseWheelFunc func)
467 { 504 {
468 } 505 mouseWheelHandlers_.push_back(EventHandlerData<OnMouseWheelFunc>(canvasId, func, userData));
469 506 }
470 void GuiAdapter::SetKeyDownCallback( 507
508 // SDL ONLY
509 void GuiAdapter::SetKeyDownCallback(
471 std::string canvasId, void* userData, bool capture, OnKeyDownFunc func) 510 std::string canvasId, void* userData, bool capture, OnKeyDownFunc func)
472 { 511 {
473 } 512 }
474 513
475 void GuiAdapter::SetKeyUpCallback( 514 // SDL ONLY
515 void GuiAdapter::SetKeyUpCallback(
476 std::string canvasId, void* userData, bool capture, OnKeyUpFunc func) 516 std::string canvasId, void* userData, bool capture, OnKeyUpFunc func)
477 { 517 {
478 } 518 }
479 519
480 520
521 // SDL ONLY
481 void GuiAdapter::OnAnimationFrame() 522 void GuiAdapter::OnAnimationFrame()
482 { 523 {
483 for (size_t i = 0; i < animationFrameHandlers_.size(); i++) 524 for (size_t i = 0; i < animationFrameHandlers_.size(); i++)
484 { 525 {
485 // TODO: fix time 526 // TODO: fix time
486 (*(animationFrameHandlers_[i].first))(0, animationFrameHandlers_[i].second); 527 (*(animationFrameHandlers_[i].first))(0, animationFrameHandlers_[i].second);
487 } 528 }
488 } 529 }
489 530
531 // SDL ONLY
490 void GuiAdapter::OnResize() 532 void GuiAdapter::OnResize()
491 { 533 {
492 for (size_t i = 0; i < resizeHandlers_.size(); i++) 534 for (size_t i = 0; i < resizeHandlers_.size(); i++)
493 { 535 {
494 // TODO: fix time 536 (*(resizeHandlers_[i].func))(
495 (*(resizeHandlers_[i].first))(0, resizeHandlers_[i].second); 537 resizeHandlers_[i].canvasName, 0, resizeHandlers_[i].userData);
496 } 538 }
497 } 539 }
498 540
541 // SDL ONLY
542 void GuiAdapter::OnMouseWheelEvent(uint32_t windowID, const GuiAdapterWheelEvent& event)
543 {
544
545 // the SDL window name IS the canvas name ("canvas" is used because this lib
546 // is designed for Wasm
547 SDL_Window* sdlWindow = SDL_GetWindowFromID(windowID);
548 ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << windowID << "\" is not a valid SDL window ID!");
549
550 const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow);
551 ORTHANC_ASSERT(windowTitleSz != NULL, "Window ID \"" << windowID << "\" has a NULL window title!");
552
553 std::string windowTitle(windowTitleSz);
554 ORTHANC_ASSERT(windowTitle != "", "Window ID \"" << windowID << "\" has an empty window title!");
555
556 switch (event.mouse.type)
557 {
558 case GUIADAPTER_EVENT_WHEEL:
559 for (size_t i = 0; i < mouseWheelHandlers_.size(); i++)
560 {
561 if(mouseWheelHandlers_[i].canvasName == windowTitle)
562 (*(mouseWheelHandlers_[i].func))(windowTitle, &event, mouseWheelHandlers_[i].userData);
563 }
564 break;
565 default:
566 ORTHANC_ASSERT(false, "Wrong event.type: " << event.mouse.type << " in GuiAdapter::OnMouseWheelEvent(...)");
567 break;
568 }
569 }
570
571 // SDL ONLY
499 void GuiAdapter::OnMouseEvent(uint32_t windowID, const GuiAdapterMouseEvent& event) 572 void GuiAdapter::OnMouseEvent(uint32_t windowID, const GuiAdapterMouseEvent& event)
500 { 573 {
501 } 574 // the SDL window name IS the canvas name ("canvas" is used because this lib
502 575 // is designed for Wasm
503 576 SDL_Window* sdlWindow = SDL_GetWindowFromID(windowID);
577 ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << windowID << "\" is not a valid SDL window ID!");
578
579 const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow);
580 ORTHANC_ASSERT(windowTitleSz != NULL, "Window ID \"" << windowID << "\" has a NULL window title!");
581
582 std::string windowTitle(windowTitleSz);
583 ORTHANC_ASSERT(windowTitle != "", "Window ID \"" << windowID << "\" has an empty window title!");
584
585 switch (event.type)
586 {
587 case GUIADAPTER_EVENT_MOUSEDOWN:
588 for (size_t i = 0; i < mouseDownHandlers_.size(); i++)
589 {
590 if (mouseDownHandlers_[i].canvasName == windowTitle)
591 (*(mouseDownHandlers_[i].func))(windowTitle, &event, mouseDownHandlers_[i].userData);
592 }
593 break;
594 case GUIADAPTER_EVENT_MOUSEMOVE:
595 for (size_t i = 0; i < mouseMoveHandlers_.size(); i++)
596 {
597 if (mouseMoveHandlers_[i].canvasName == windowTitle)
598 (*(mouseMoveHandlers_[i].func))(windowTitle, &event, mouseMoveHandlers_[i].userData);
599 }
600 break;
601 case GUIADAPTER_EVENT_MOUSEUP:
602 for (size_t i = 0; i < mouseUpHandlers_.size(); i++)
603 {
604 if (mouseUpHandlers_[i].canvasName == windowTitle)
605 (*(mouseUpHandlers_[i].func))(windowTitle, &event, mouseUpHandlers_[i].userData);
606 }
607 break;
608 default:
609 ORTHANC_ASSERT(false, "Wrong event.type: " << event.type << " in GuiAdapter::OnMouseEvent(...)");
610 break;
611 }
612
613 ////boost::shared_ptr<IGuiAdapterWidget> GetWidgetFromWindowId();
614 //boost::shared_ptr<IGuiAdapterWidget> foundWidget;
615 //VisitWidgets([foundWidget, windowID](auto widget)
616 // {
617 // if (widget->GetSdlWindowID() == windowID)
618 // foundWidget = widget;
619 // });
620 //ORTHANC_ASSERT(foundWidget, "WindowID " << windowID << " was not found in the registered widgets!");
621 //if(foundWidget)
622 // foundWidget->
623 }
624
625 // SDL ONLY
504 void GuiAdapter::RequestAnimationFrame(OnAnimationFrameFunc func, void* userData) 626 void GuiAdapter::RequestAnimationFrame(OnAnimationFrameFunc func, void* userData)
505 { 627 {
506 animationFrameHandlers_.push_back(std::make_pair(func, userData)); 628 animationFrameHandlers_.push_back(std::make_pair(func, userData));
507 } 629 }
508 630
509 # if ORTHANC_ENABLE_OPENGL == 1 && !defined(__APPLE__) /* OpenGL debug is not available on OS X */ 631 # if ORTHANC_ENABLE_OPENGL == 1 && !defined(__APPLE__) /* OpenGL debug is not available on OS X */
510 632
633 // SDL ONLY
511 static void GLAPIENTRY 634 static void GLAPIENTRY
512 OpenGLMessageCallback(GLenum source, 635 OpenGLMessageCallback(GLenum source,
513 GLenum type, 636 GLenum type,
514 GLuint id, 637 GLuint id,
515 GLenum severity, 638 GLenum severity,
524 type, severity, message); 647 type, severity, message);
525 } 648 }
526 } 649 }
527 # endif 650 # endif
528 651
652 // SDL ONLY
529 void GuiAdapter::Run() 653 void GuiAdapter::Run()
530 { 654 {
531 # if ORTHANC_ENABLE_OPENGL == 1 && !defined(__APPLE__) 655 # if ORTHANC_ENABLE_OPENGL == 1 && !defined(__APPLE__)
532 glEnable(GL_DEBUG_OUTPUT); 656 glEnable(GL_DEBUG_OUTPUT);
533 glDebugMessageCallback(OpenGLMessageCallback, 0); 657 glDebugMessageCallback(OpenGLMessageCallback, 0);
589 event.button.x, event.button.y)); 713 event.button.x, event.button.y));
590 tracker->PointerMove(e); 714 tracker->PointerMove(e);
591 } 715 }
592 #endif 716 #endif
593 } 717 }
718 else if (event.type == SDL_MOUSEWHEEL)
719 {
720
721 int scancodeCount = 0;
722 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount);
723 bool ctrlPressed(false);
724 bool shiftPressed(false);
725 bool altPressed(false);
726
727 if (SDL_SCANCODE_LCTRL < scancodeCount && keyboardState[SDL_SCANCODE_LCTRL])
728 ctrlPressed = true;
729 if (SDL_SCANCODE_RCTRL < scancodeCount && keyboardState[SDL_SCANCODE_RCTRL])
730 ctrlPressed = true;
731 if (SDL_SCANCODE_LSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_LSHIFT])
732 shiftPressed = true;
733 if (SDL_SCANCODE_RSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_RSHIFT])
734 shiftPressed = true;
735 if (SDL_SCANCODE_LALT < scancodeCount && keyboardState[SDL_SCANCODE_LALT])
736 altPressed = true;
737
738 GuiAdapterWheelEvent dest;
739 ConvertFromPlatform(dest, ctrlPressed, shiftPressed, altPressed, event);
740 OnMouseWheelEvent(event.window.windowID, dest);
741
742 //KeyboardModifiers modifiers = GetKeyboardModifiers(keyboardState, scancodeCount);
743
744 //int x, y;
745 //SDL_GetMouseState(&x, &y);
746
747 //if (event.wheel.y > 0)
748 //{
749 // locker.GetCentralViewport().MouseWheel(MouseWheelDirection_Up, x, y, modifiers);
750 //}
751 //else if (event.wheel.y < 0)
752 //{
753 // locker.GetCentralViewport().MouseWheel(MouseWheelDirection_Down, x, y, modifiers);
754 //}
755 }
594 else if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) 756 else if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
595 { 757 {
596 #if 0 758 #if 0
597 tracker.reset(); 759 tracker.reset();
598 #endif 760 #endif