Logo ROOT  
Reference Guide
TGLEventHandler.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Bertrand Bellenot 29/01/2008
3
4/*************************************************************************
5 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "TGLEventHandler.h"
13#include "TGEventHandler.h"
14#include "TGLViewer.h"
15#include "TGLWidget.h"
16#include "TGWindow.h"
17#include "TPoint.h"
18#include "TVirtualPad.h" // Remove when pad removed - use signal
19#include "TVirtualX.h"
20#include "TGClient.h"
21#include "TVirtualGL.h"
22#include "TGLOverlay.h"
23#include "TGLLogicalShape.h"
24#include "TGLPhysicalShape.h"
25#include "TContextMenu.h"
26#include "TGToolTip.h"
27#include "KeySymbols.h"
28#include "TGLAnnotation.h"
29#include "TEnv.h"
30#include "TMath.h"
31#include "RConfigure.h"
32
33/** \class TGLEventHandler
34\ingroup opengl
35Base-class and default implementation of event-handler for TGLViewer.
36
37This allows for complete disentanglement of GL-viewer from GUI
38event handling. Further, alternative event-handlers can easily be
39designed and set at run-time.
40
41The signals about object being selected or hovered above are
42emitted via the TGLViewer itself.
43
44The following rootrc settings influence the behaviour:
45~~~ {.cpp}
46OpenGL.EventHandler.ViewerCentricControls: 1
47OpenGL.EventHandler.ArrowKeyFactor: -1.0
48OpenGL.EventHandler.MouseDragFactor: -1.0
49OpenGL.EventHandler.MouseWheelFactor: -1.0
50~~~
51*/
52
54
55////////////////////////////////////////////////////////////////////////////////
56/// Constructor.
57
59 TGEventHandler ("TGLEventHandler", w, obj),
60 fGLViewer ((TGLViewer *)obj),
61 fMouseTimer (0),
62 fLastPos (-1, -1),
63 fLastMouseOverPos (-1, -1),
64 fLastMouseOverShape (0),
65 fTooltip (0),
66 fActiveButtonID (0),
67 fLastEventState (0),
68 fIgnoreButtonUp (kFALSE),
69 fInPointerGrab (kFALSE),
70 fMouseTimerRunning (kFALSE),
71 fTooltipShown (kFALSE),
72 fArcBall (kFALSE),
73 fTooltipPixelTolerance (3),
74 fSecSelType(TGLViewer::kOnRequest),
75 fDoInternalSelection(kTRUE),
76 fViewerCentricControls(kFALSE)
77{
78 fMouseTimer = new TTimer(this, 80);
79 fTooltip = new TGToolTip(0, 0, "", 650);
80 fTooltip->Hide();
81 fViewerCentricControls = gEnv->GetValue("OpenGL.EventHandler.ViewerCentricControls", 0) != 0;
82 fArrowKeyFactor = gEnv->GetValue("OpenGL.EventHandler.ArrowKeyFactor", 1.0);
83 fMouseDragFactor = gEnv->GetValue("OpenGL.EventHandler.MouseDragFactor", 1.0);
84 fMouseWheelFactor = gEnv->GetValue("OpenGL.EventHandler.MouseWheelFactor", 1.0);
85}
86
87////////////////////////////////////////////////////////////////////////////////
88/// Destructor.
89
91{
92 delete fMouseTimer;
93 delete fTooltip;
94}
95
96////////////////////////////////////////////////////////////////////////////////
97/// Acquire mouse grab.
98
100{
101 if (!fInPointerGrab)
102 {
103 gVirtualX->GrabPointer(fGLViewer->GetGLWidget()->GetId(),
107 }
108}
109
110////////////////////////////////////////////////////////////////////////////////
111/// Release mouse grab.
112
114{
115 if (fInPointerGrab)
116 {
117 gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
119 }
120}
121
122////////////////////////////////////////////////////////////////////////////////
123/// Run selection (optionally with on secondary selection) and emit
124/// corresponding Clicked() signals.
125/// Protected method.
126
128{
130
133
134 // secondary selection
135 if (lshp && (event->fState & kKeyMod1Mask || (fSecSelType == TGLViewer::kOnRequest && lshp->AlwaysSecondarySelect())))
136 {
139
141
143 {
145 fGLViewer->Clicked(obj, event->fCode, event->fState);
146 break;
148 fGLViewer->UnClicked(obj, event->fCode, event->fState);
149 break;
151 fGLViewer->ReClicked(obj, event->fCode, event->fState);
152 break;
153 default:
154 break;
155 }
156 }
157 else
158 {
159 fGLViewer->Clicked(obj);
160 fGLViewer->Clicked(obj, event->fCode, event->fState);
161 }
162}
163
164////////////////////////////////////////////////////////////////////////////////
165/// Run selection (optionally with on secondary selection) and emit
166/// corresponding MouseOver() signals.
167/// Protected method.
168
170{
172
176
177 if (lshp && (fSecSelType == TGLViewer::kOnRequest && lshp->AlwaysSecondarySelect()))
178 {
182
184
186
188 {
191 break;
194 break;
197 break;
198 default:
199 break;
200 }
201 }
202 else if (fLastMouseOverShape != pshp)
203 {
204 fGLViewer->MouseOver(pshp);
207 }
208 fLastMouseOverShape = pshp;
210}
211
212//==============================================================================
213
214////////////////////////////////////////////////////////////////////////////////
215/// Process event of type 'event' - one of EEventType types,
216/// occurring at window location px, py
217/// This is provided for use when embedding GL viewer into pad
218
220{
221 /*enum EEventType {
222 kNoEvent = 0,
223 kButton1Down = 1, kButton2Down = 2, kButton3Down = 3, kKeyDown = 4,
224 kButton1Up = 11, kButton2Up = 12, kButton3Up = 13, kKeyUp = 14,
225 kButton1Motion = 21, kButton2Motion = 22, kButton3Motion = 23, kKeyPress = 24,
226 kButton1Locate = 41, kButton2Locate = 42, kButton3Locate = 43,
227 kMouseMotion = 51, kMouseEnter = 52, kMouseLeave = 53,
228 kButton1Double = 61, kButton2Double = 62, kButton3Double = 63
229
230 enum EGEventType {
231 kGKeyPress, kKeyRelease, kButtonPress, kButtonRelease,
232 kMotionNotify, kEnterNotify, kLeaveNotify, kFocusIn, kFocusOut,
233 kExpose, kConfigureNotify, kMapNotify, kUnmapNotify, kDestroyNotify,
234 kClientMessage, kSelectionClear, kSelectionRequest, kSelectionNotify,
235 kColormapNotify, kButtonDoubleClick, kOtherEvent*/
236
237 // Map our event EEventType (base/inc/Buttons.h) back to Event_t (base/inc/GuiTypes.h)
238 // structure, and call appropriate HandleXyzz() function
239 Event_t eventSt = { kOtherEvent, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
240 kFALSE, 0, 0, {0, 0, 0, 0, 0} };
241 eventSt.fX = px;
242 eventSt.fY = py;
243 eventSt.fState = 0;
244 eventSt.fXRoot = eventSt.fYRoot = 0;
245
246 if (event != kKeyPress) {
247 eventSt.fY -= Int_t((1 - gPad->GetHNDC() - gPad->GetYlowNDC()) * gPad->GetWh());
248 eventSt.fX -= Int_t(gPad->GetXlowNDC() * gPad->GetWw());
249 eventSt.fXRoot = eventSt.fX;
250 eventSt.fYRoot = eventSt.fY;
251 }
252
253 switch (event) {
254 case kMouseMotion:
255 eventSt.fCode = kMouseMotion;
256 eventSt.fType = kMotionNotify;
257 HandleMotion(&eventSt);
258 break;
259 case kButton1Down:
260 case kButton1Up:
261 {
262 eventSt.fCode = kButton1;
263 eventSt.fType = event == kButton1Down ? kButtonPress:kButtonRelease;
264 HandleButton(&eventSt);
265 }
266 break;
267 case kButton2Down:
268 case kButton2Up:
269 {
270 eventSt.fCode = kButton2;
271 eventSt.fType = event == kButton2Down ? kButtonPress:kButtonRelease;
272 HandleButton(&eventSt);
273 }
274 break;
275 case kButton3Down:
276 {
277 eventSt.fState = kKeyShiftMask;
278 eventSt.fCode = kButton1;
279 eventSt.fType = kButtonPress;
280 HandleButton(&eventSt);
281 }
282 break;
283 case kButton3Up:
284 {
285 eventSt.fCode = kButton3;
286 eventSt.fType = kButtonRelease;//event == kButton3Down ? kButtonPress:kButtonRelease;
287 HandleButton(&eventSt);
288 }
289 break;
290 case kButton1Double:
291 case kButton2Double:
292 case kButton3Double:
293 {
294 eventSt.fCode = event == kButton1Double ? kButton1 : event == kButton2Double ? kButton2 : kButton3;
295 eventSt.fType = kButtonDoubleClick;
296 HandleDoubleClick(&eventSt);
297 }
298 break;
299 case kButton1Motion:
300 case kButton2Motion:
301 case kButton3Motion:
302 {
303
304 eventSt.fCode = event == kButton1Motion ? kButton1 : event == kButton2Motion ? kButton2 : kButton3;
305 eventSt.fType = kMotionNotify;
306 HandleMotion(&eventSt);
307 }
308 break;
309 case kKeyPress: // We only care about full key 'presses' not individual down/up
310 {
311 eventSt.fType = kGKeyPress;
312 eventSt.fCode = py; // px contains key code - need modifiers from somewhere
313 HandleKey(&eventSt);
314 }
315 break;
316 case 6://trick :)
317 if (fGLViewer->CurrentCamera().Zoom(+50, kFALSE, kFALSE)) { //TODO : val static const somewhere
318 if (fGLViewer->fGLDevice != -1) {
319 gGLManager->MarkForDirectCopy(fGLViewer->fGLDevice, kTRUE);
320 gVirtualX->SetDrawMode(TVirtualX::kCopy);
321 }
323 }
324 break;
325 case 5://trick :)
326 if (fGLViewer->CurrentCamera().Zoom(-50, kFALSE, kFALSE)) { //TODO : val static const somewhere
327 if (fGLViewer->fGLDevice != -1) {
328 gGLManager->MarkForDirectCopy(fGLViewer->fGLDevice, kTRUE);
329 gVirtualX->SetDrawMode(TVirtualX::kCopy);
330 }
332 }
333 break;
334 case 7://trick :)
335 eventSt.fState = kKeyShiftMask;
336 eventSt.fCode = kButton1;
337 eventSt.fType = kButtonPress;
338 HandleButton(&eventSt);
339 break;
340 default:
341 {
342 // Error("TGLEventHandler::ExecuteEvent", "invalid event type");
343 }
344 }
345}
346
347////////////////////////////////////////////////////////////////////////////////
348/// Handle generic Event_t type 'event' - provided to catch focus changes
349/// and terminate any interaction in viewer.
350
352{
353 if (event->fType == kFocusIn) {
355 Error("TGLEventHandler::HandleEvent", "active drag-action at focus-in.");
357 }
359 }
360 if (event->fType == kFocusOut) {
362 Warning("TGLEventHandler::HandleEvent", "drag-action active at focus-out.");
364 }
367 }
368
369 return kTRUE;
370}
371
372////////////////////////////////////////////////////////////////////////////////
373/// Handle generic Event_t type 'event' - provided to catch focus changes
374/// and terminate any interaction in viewer.
375
377{
378 fGLViewer->MouseIdle(0, 0, 0);
379 if (event->fType == kFocusIn) {
381 Error("TGLEventHandler::HandleFocusChange", "active drag-action at focus-in.");
383 }
386 }
387 if (event->fType == kFocusOut) {
389 Warning("TGLEventHandler::HandleFocusChange", "drag-action active at focus-out.");
391 }
394 }
395
396 return kTRUE;
397}
398
399////////////////////////////////////////////////////////////////////////////////
400/// Handle generic Event_t type 'event' - provided to catch focus changes
401/// and terminate any interaction in viewer.
402
404{
405 // Ignore grab and ungrab events.
406 if (event->fCode != 0) {
407 return kTRUE;
408 }
409
410 fGLViewer->MouseIdle(0, 0, 0);
411 if (event->fType == kEnterNotify) {
413 Error("TGLEventHandler::HandleCrossing", "active drag-action at enter-notify.");
415 }
417 // Maybe, maybe not...
419 }
420 if (event->fType == kLeaveNotify) {
422 Warning("TGLEventHandler::HandleCrossing", "drag-action active at leave-notify.");
424 }
427 }
428
429 return kTRUE;
430}
431
432////////////////////////////////////////////////////////////////////////////////
433/// Handle mouse button 'event'.
434
436{
437 if (fGLViewer->IsLocked()) {
438 if (gDebug>2) {
439 Info("TGLEventHandler::HandleButton", "ignored - viewer is %s",
441 }
442 return kFALSE;
443 }
444
445 // Handle mouse-wheel events first.
446 if (event->fCode > kButton3)
447 {
448 // On Win32 only button release events come for mouse wheel.
449 // Note: Modifiers (ctrl/shift) disabled as fState doesn't seem to
450 // have correct modifier flags with mouse wheel under Windows.
451
452 if (event->fType == kButtonRelease)
453 {
454 Bool_t redraw = kFALSE;
455
457 switch(event->fCode)
458 {
459 case kButton5: // Zoom out (dolly or adjust camera FOV).
460 redraw = fGLViewer->CurrentCamera().Zoom(zoom, kFALSE, kFALSE);
461 break;
462
463 case kButton4: // Zoom in (dolly or adjust camera FOV).
464 redraw = fGLViewer->CurrentCamera().Zoom(-zoom, kFALSE, kFALSE);
465 break;
466
467 case kButton6:
468 case kButton7: // Ignore for now.
469 break;
470 }
471
472 if (redraw)
474 }
475 return kTRUE;
476 }
477
478 // Now we know we have Button 1 -> 3.
479 // Allow a single action/button down/up pairing - block others
480 if (fActiveButtonID && event->fCode != fActiveButtonID)
481 {
482 return kTRUE;
483 }
484 else
485 {
486 fActiveButtonID = event->fCode;
487 }
488
489#if defined(R__HAS_COCOA)
490 // On osx/cocoa use cmd modifier for mouse-2 and cmd-alt for mouse-3.
491 if (event->fCode == kButton1 && event->fState & kKeyMod2Mask)
492 {
493 event->fCode = event->fState & kKeyMod1Mask ? kButton3 : kButton2;
494 }
495#endif
496
497 // Button DOWN
498 if (event->fType == kButtonPress)
499 {
500 GrabMouse();
501
502 fGLViewer->MouseIdle(0, 0, 0);
503
504 fButtonPushPos.fX = event->fX;
505 fButtonPushPos.fY = event->fY;
506
508 {
510 if (fGLViewer->fSelRec.GetN() > 0)
511 {
512 auto scaling = TGLUtil::GetScreenScalingFactor();
513 TGLVector3 v(scaling * event->fX, scaling * event->fY, 0.5*fGLViewer->fSelRec.GetMinZ());
517 {
519 fGLViewer->CurrentCamera().SetCenterVec(v.X(), v.Y(), v.Z());
520 }
521 else
522 {
524 TObject* obj = rec.GetObject();
526 Int_t x = event->fX, y = event->fY;
528 new TGLAnnotation(fGLViewer, obj->GetTitle(),
529 x * 1.0f/vp.Width(),
530 1 - y * 1.0f/vp.Height(), v);
531 }
532
534 }
535 return kTRUE;
536 }
537
538 Bool_t handled = kFALSE;
539
541 {
542 Event_t e = *event;
545 {
546 handled = kTRUE;
549 }
550 }
551
552 if ( ! handled)
553 {
554 switch (event->fCode)
555 {
556 // LEFT mouse button
557 case kButton1:
558 {
560 if (fMouseTimer)
561 {
564 }
565 break;
566 }
567 // MIDDLE mouse button
568 case kButton2:
569 {
571 break;
572 }
573 // RIGHT mouse button
574 case kButton3:
575 {
577 break;
578 }
579 }
580 }
581 }
582 // Button UP
583 else if (event->fType == kButtonRelease)
584 {
585 fActiveButtonID = 0;
586
587 if (fInPointerGrab)
588 {
589 UnGrabMouse();
590 }
591 else
592 {
593 Warning("TGLEventHandler::HandleButton", "Unexpected button-release.");
594 }
595
596 if (fIgnoreButtonUp)
597 {
599 return kTRUE;
600 }
601
603 {
604 // This should be 'tool' dependant.
607 return kTRUE;
608 }
610 {
611 Event_t e = *event;
617 }
620 {
622 }
623
625
626 if (fGLViewer->fGLDevice != -1)
627 {
628 gGLManager->MarkForDirectCopy(fGLViewer->fGLDevice, kFALSE);
629 }
630
631 if (event->fX == fButtonPushPos.fX && event->fY == fButtonPushPos.fY)
632 {
633 if (event->fCode == kButton1)
634 {
636 {
637 if (fGLViewer->RequestSelect(event->fX, event->fY))
638 {
640 }
641 }
642 else
643 {
645 }
646 }
647 else if (event->fCode == kButton3)
648 {
649 Int_t x, y;
650 Window_t childdum;
651 gVirtualX->TranslateCoordinates(fGLViewer->fGLWidget->GetId(), gClient->GetDefaultRoot()->GetId(),
652 event->fX, event->fY, x, y, childdum);
653
655
657 }
658 }
659
660 if (event->fCode == kButton1 && fMouseTimer)
661 {
663 }
664 }
665
666 return kTRUE;
667}
668
669////////////////////////////////////////////////////////////////////////////////
670/// Handle mouse double click 'event'.
671
673{
674 if (fGLViewer->IsLocked()) {
675 if (gDebug>3) {
676 Info("TGLEventHandler::HandleDoubleClick", "ignored - viewer is %s",
678 }
679 return kFALSE;
680 }
681
682 if (event->fCode > 3)
683 return kTRUE;
684
685 if (fActiveButtonID)
686 return kTRUE;
687
688 fActiveButtonID = event->fCode;
689 GrabMouse();
690
691 fGLViewer->MouseIdle(0, 0, 0);
692 if (event->fCode == kButton1)
693 {
695 if (fGLViewer->GetSelected() == 0)
697 }
698 return kTRUE;
699}
700
701////////////////////////////////////////////////////////////////////////////////
702/// Handle configure notify 'event' - a window resize/movement.
703
705{
706 if (fGLViewer->IsLocked())
707 {
708 if (gDebug > 0) {
709 Info("TGLEventHandler::HandleConfigureNotify", "ignored - viewer is %s",
711 }
712 return kFALSE;
713 }
714 if (event)
715 {
716 Int_t x = event->fX, y = event->fY, w = event->fWidth, h = event->fHeight;
718 fGLViewer->SetViewport(x, y, w, h);
720 }
721 return kTRUE;
722}
723
724////////////////////////////////////////////////////////////////////////////////
725/// Handle window expose 'event' - show.
726
728{
729 if (event->fCount != 0) return kTRUE;
730
731 if (fGLViewer->IsLocked()) {
732 if (gDebug > 0) {
733 Info("TGLViewer::HandleExpose", "ignored - viewer is %s",
735 }
736 return kFALSE;
737 }
738
740 return kTRUE;
741}
742
743////////////////////////////////////////////////////////////////////////////////
744/// Handle keyboard 'event'.
745
747{
748 // We only handle key-press events.
749 if (event->fType == kKeyRelease)
750 return kTRUE;
751
752 if (fTooltipShown)
753 fTooltip->Hide();
754
755 fLastEventState = event->fState;
756
757 fGLViewer->MouseIdle(0, 0, 0);
758 if (fGLViewer->IsLocked()) {
759 if (gDebug>3) {
760 Info("TGLEventHandler::HandleKey", "ignored - viewer is %s",
762 }
763 return kFALSE;
764 }
765
766 char tmp[10] = {0};
767 UInt_t keysym = 0;
768
769 if (fGLViewer->fGLDevice == -1)
770 gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
771 else
772 keysym = event->fCode;
774
775 Bool_t handled = kFALSE;
776 Bool_t redraw = kFALSE;
777
779 {
780 Event_t e = *event;
783 {
784 handled = kTRUE;
785 redraw = kTRUE;
786 }
787 }
788
789 if ( ! handled)
790 {
791 const Bool_t mod1 = event->fState & kKeyControlMask;
792 const Bool_t mod2 = event->fState & kKeyShiftMask;
793
794 const Int_t shift = TMath::Nint(fArrowKeyFactor * ControlValue(10));
795
796 switch (keysym)
797 {
798 case kKey_R:
799 case kKey_r:
801 redraw = kTRUE;
802 break;
803 case kKey_E:
804 case kKey_e:
806 redraw = kTRUE;
807 break;
808 case kKey_W:
809 case kKey_w:
811 redraw = kTRUE;
812 break;
813 case kKey_T:
814 case kKey_t:
816 redraw = kTRUE;
817 break;
818
819 case kKey_F1:
822 break;
823
824 // Camera
825 case kKey_A:
826 case kKey_a:
827 fArcBall = ! fArcBall;
828 break;
829 case kKey_Plus:
830 case kKey_J:
831 case kKey_j:
832 redraw = fGLViewer->CurrentCamera().Dolly(shift, mod1, mod2);
833 break;
834 case kKey_Minus:
835 case kKey_K:
836 case kKey_k:
837 redraw = fGLViewer->CurrentCamera().Dolly(-shift, mod1, mod2);
838 break;
839 case kKey_Up:
840 redraw = fGLViewer->CurrentCamera().Truck(0, shift, mod1, mod2);
841 break;
842 case kKey_Down:
843 redraw = fGLViewer->CurrentCamera().Truck(0, -shift, mod1, mod2);
844 break;
845 case kKey_Left:
846 redraw = fGLViewer->CurrentCamera().Truck(-shift, 0, mod1, mod2);
847 break;
848 case kKey_Right:
849 redraw = fGLViewer->CurrentCamera().Truck(shift, 0, mod1, mod2);
850 break;
851 case kKey_Home:
852 if (mod1) {
856 } else {
858 }
859 redraw = kTRUE;
860 break;
861
862 // Toggle debugging mode
863 case kKey_d:
865 redraw = kTRUE;
866 Info("OpenGL viewer debug mode : ", fGLViewer->fDebugMode ? "ON" : "OFF");
867 break;
868 // Forced rebuild for debugging mode
869 case kKey_D:
870 if (fGLViewer->fDebugMode) {
871 Info("OpenGL viewer FORCED rebuild", " ");
873 }
874 default:;
875 } // switch
876 }
877
878 if (redraw) {
879 if (fGLViewer->fGLDevice != -1)
880 gGLManager->MarkForDirectCopy(fGLViewer->fGLDevice, kTRUE);
882 }
883
884 return kTRUE;
885}
886
887////////////////////////////////////////////////////////////////////////////////
888/// Handle mouse motion 'event'.
889
891{
892 fGLViewer->MouseIdle(0, 0, 0);
893 if (fGLViewer->IsLocked()) {
894 if (gDebug>3) {
895 Info("TGLEventHandler::HandleMotion", "ignored - viewer is %s",
897 }
898 return kFALSE;
899 }
900
901 Bool_t processed = kFALSE, changed = kFALSE;
903
904 // Camera interface requires GL coords - Y inverted
907 Bool_t mod1 = event->fState & kKeyControlMask;
908 Bool_t mod2 = event->fState & kKeyShiftMask;
909 TGLUtil::PointToViewport(xDelta, yDelta);
910
912
913 if (fTooltipShown &&
916 {
918 }
919
921 {
923 if (gDebug > 2)
924 Info("TGLEventHandler::HandleMotion", "Redraw pending, ignoring.");
925 return kTRUE;
926 }
927 changed = fGLViewer->RequestOverlaySelect(event->fX, event->fY);
929 {
930 Event_t e = *event;
933 }
935 if ( ! processed && ! fMouseTimerRunning)
937 }
939 {
940 processed = Rotate(xDelta, yDelta, mod1, mod2);
941 }
943 {
944 processed = fGLViewer->CurrentCamera().Truck(xDelta, -yDelta, mod1, mod2);
945 }
947 {
948 processed = fGLViewer->CurrentCamera().Dolly(yDelta - xDelta, mod1, mod2);
949 }
951 {
953 Event_t e = *event;
956 }
957 }
958
959 fLastPos.fX = event->fX;
960 fLastPos.fY = event->fY;
961
962 fLastGlobalPos.fX = event->fXRoot;
963 fLastGlobalPos.fY = event->fYRoot;
964
965 if (processed || changed) {
966 if (fGLViewer->fGLDevice != -1) {
967 gGLManager->MarkForDirectCopy(fGLViewer->fGLDevice, kTRUE);
968 gVirtualX->SetDrawMode(TVirtualX::kCopy);
969 }
970
972 }
973
974 return processed;
975}
976
977////////////////////////////////////////////////////////////////////////////////
978/// Method to handle action TGLViewer::kDragCameraRotate.
979
981{
983 if (fArcBall) return cam.RotateArcBall(xDelta, -yDelta, mod1, mod2);
984 else return cam.Rotate (xDelta, -yDelta, mod1, mod2);
985}
986
987////////////////////////////////////////////////////////////////////////////////
988/// If mouse delay timer times out emit signal.
989
991{
992 if (t != fMouseTimer) return kFALSE;
993
995
997 if (gDebug > 2)
998 Info("TGLEventHandler::HandleTimer", "Redraw pending, ignoring.");
999 return kTRUE;
1000 }
1001
1003 {
1005 {
1007 }
1008 }
1009 return kTRUE;
1010}
1011
1012////////////////////////////////////////////////////////////////////////////////
1013/// Start mouse timer in single-shot mode.
1014
1016{
1017 fMouseTimer->Start(-1, kTRUE);
1019}
1020
1021////////////////////////////////////////////////////////////////////////////////
1022/// Make sure mouse timers are not running.
1023
1025{
1027 fMouseTimer->Stop();
1028}
1029
1030////////////////////////////////////////////////////////////////////////////////
1031/// Clear mouse-over state and emit mouse-over signals.
1032/// Current overlay element is also told the mouse has left.
1033
1035{
1041
1043}
1044
1045////////////////////////////////////////////////////////////////////////////////
1046/// Handle window expose 'event' - show.
1047
1049{
1050 if (fGLViewer->IsLocked()) {
1051 if (gDebug > 0) {
1052 Info("TGLViewer::HandleExpose", "ignored - viewer is %s",
1054 }
1055 return;
1056 }
1058}
1059
1060////////////////////////////////////////////////////////////////////////////////
1061/// Popup context menu.
1062
1064 Int_t gx, Int_t gy)
1065{
1066 if (!fGLViewer->fContextMenu)
1067 {
1068 fGLViewer->fContextMenu = new TContextMenu("glcm", "GL Viewer Context Menu");
1069 }
1070
1071 if (pshp)
1072 {
1073 fActiveButtonID = 0;
1074 UnGrabMouse();
1075
1076 pshp->InvokeContextMenu(*fGLViewer->fContextMenu, gx, gy);
1077 }
1078
1079 // This is dangerous ... should have special menu, probably even
1080 // tool / context specific.
1081 // else
1082 // {
1083 // fGLViewer->fContextMenu->Popup(x, y, fGLViewer);
1084 // }
1085}
1086
1087////////////////////////////////////////////////////////////////////////////////
1088/// Trigger display of tooltip.
1089
1091{
1092 static UInt_t screenW = 0, screenH = 0;
1096 Int_t x = fTooltipPos.fX + 16, y = fTooltipPos.fY + 16;
1097 if (screenW == 0 || screenH == 0) {
1098 screenW = gClient->GetDisplayWidth();
1099 screenH = gClient->GetDisplayHeight();
1100 }
1101 if (x + 5 + fTooltip->GetWidth() > screenW) {
1102 x = screenW - fTooltip->GetWidth() - 5;
1103 if (y + 5 + fTooltip->GetHeight() > screenH) {
1104 y -= (25 + fTooltip->GetHeight());
1105 }
1106 }
1107 if (y + 5 + fTooltip->GetHeight() > screenH) {
1108 y = screenH - fTooltip->GetHeight() - 10;
1109 }
1111 fTooltip->Reset();
1112}
1113
1114////////////////////////////////////////////////////////////////////////////////
1115/// Hide the tooltip.
1116
1118{
1119 fTooltip->Hide();
1121}
1122
1123////////////////////////////////////////////////////////////////////////////////
1124/// Set delay of mouse-over probe (highlight).
1125
1127{
1129}
1130
1131////////////////////////////////////////////////////////////////////////////////
1132/// Set delay of tooltip timer.
1133
1135{
1137}
@ kMouseMotion
Definition: Buttons.h:23
@ kButton3Up
Definition: Buttons.h:19
@ kButton2Motion
Definition: Buttons.h:20
@ kButton3Motion
Definition: Buttons.h:20
@ kButton3Down
Definition: Buttons.h:17
@ kButton2Down
Definition: Buttons.h:17
@ kKeyPress
Definition: Buttons.h:20
@ kButton2Double
Definition: Buttons.h:24
@ kButton1Double
Definition: Buttons.h:24
@ kButton3Double
Definition: Buttons.h:24
@ kButton1Motion
Definition: Buttons.h:20
@ kButton1Up
Definition: Buttons.h:19
@ kButton2Up
Definition: Buttons.h:19
@ kButton1Down
Definition: Buttons.h:17
@ kGKeyPress
Definition: GuiTypes.h:60
@ kButtonRelease
Definition: GuiTypes.h:60
@ kButtonPress
Definition: GuiTypes.h:60
@ kButtonDoubleClick
Definition: GuiTypes.h:64
@ kFocusOut
Definition: GuiTypes.h:61
@ kMotionNotify
Definition: GuiTypes.h:61
@ kFocusIn
Definition: GuiTypes.h:61
@ kEnterNotify
Definition: GuiTypes.h:61
@ kOtherEvent
Definition: GuiTypes.h:64
@ kKeyRelease
Definition: GuiTypes.h:60
@ kLeaveNotify
Definition: GuiTypes.h:61
const Mask_t kButtonPressMask
Definition: GuiTypes.h:161
const Mask_t kKeyMod1Mask
typically the Alt key
Definition: GuiTypes.h:198
Handle_t Window_t
Window handle.
Definition: GuiTypes.h:29
const Mask_t kPointerMotionMask
Definition: GuiTypes.h:163
const Mask_t kKeyShiftMask
Definition: GuiTypes.h:195
const Handle_t kNone
Definition: GuiTypes.h:88
const Mask_t kKeyControlMask
Definition: GuiTypes.h:197
const Mask_t kKeyMod2Mask
typically mod on numeric keys
Definition: GuiTypes.h:199
const Mask_t kButtonReleaseMask
Definition: GuiTypes.h:162
@ kButton4
Definition: GuiTypes.h:215
@ kButton7
Definition: GuiTypes.h:215
@ kButton2
Definition: GuiTypes.h:214
@ kButton5
Definition: GuiTypes.h:215
@ kButton3
Definition: GuiTypes.h:214
@ kButton1
Definition: GuiTypes.h:214
@ kButton6
Definition: GuiTypes.h:215
@ kKey_Right
Definition: KeySymbols.h:42
@ kKey_J
Definition: KeySymbols.h:135
@ kKey_W
Definition: KeySymbols.h:148
@ kKey_Down
Definition: KeySymbols.h:43
@ kKey_F1
Definition: KeySymbols.h:57
@ kKey_Up
Definition: KeySymbols.h:41
@ kKey_r
Definition: KeySymbols.h:175
@ kKey_j
Definition: KeySymbols.h:167
@ kKey_A
Definition: KeySymbols.h:126
@ kKey_Left
Definition: KeySymbols.h:40
@ kKey_E
Definition: KeySymbols.h:130
@ kKey_T
Definition: KeySymbols.h:145
@ kKey_D
Definition: KeySymbols.h:129
@ kKey_Home
Definition: KeySymbols.h:38
@ kKey_e
Definition: KeySymbols.h:162
@ kKey_w
Definition: KeySymbols.h:180
@ kKey_k
Definition: KeySymbols.h:168
@ kKey_Plus
Definition: KeySymbols.h:104
@ kKey_t
Definition: KeySymbols.h:177
@ kKey_R
Definition: KeySymbols.h:143
@ kKey_a
Definition: KeySymbols.h:158
@ kKey_Minus
Definition: KeySymbols.h:106
@ kKey_d
Definition: KeySymbols.h:161
@ kKey_K
Definition: KeySymbols.h:136
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
int Int_t
Definition: RtypesCore.h:45
const Bool_t kFALSE
Definition: RtypesCore.h:101
short Short_t
Definition: RtypesCore.h:39
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:375
R__EXTERN TEnv * gEnv
Definition: TEnv.h:170
#define gClient
Definition: TGClient.h:157
Option_t Option_t TPoint TPoint const char text
Int_t gDebug
Definition: TROOT.cxx:585
#define gGLManager
Definition: TVirtualGL.h:160
#define gPad
Definition: TVirtualPad.h:302
#define gVirtualX
Definition: TVirtualX.h:338
This class provides an interface to context sensitive popup menus.
Definition: TContextMenu.h:44
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
UInt_t GetHeight() const
Definition: TGFrame.h:225
UInt_t GetWidth() const
Definition: TGFrame.h:224
GL-overlay annotation.
Definition: TGLAnnotation.h:26
Abstract base camera class - concrete classes for orthographic and perspective cameras derive from it...
Definition: TGLCamera.h:44
virtual Bool_t Dolly(Int_t delta, Bool_t mod1, Bool_t mod2)
Dolly the camera - 'move camera along eye line, retaining lens focal length'.
Definition: TGLCamera.cxx:1046
virtual Bool_t Truck(Double_t xDelta, Double_t yDelta)
Truck the camera - 'move camera parallel to film plane'.
Definition: TGLCamera.cxx:894
virtual Bool_t Rotate(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2)
Rotate the camera round view volume center established in Setup().
Definition: TGLCamera.cxx:916
virtual Bool_t Zoom(Int_t delta, Bool_t mod1, Bool_t mod2)=0
void WindowToViewport(Int_t &, Int_t &y) const
Definition: TGLCamera.h:198
Bool_t GetExternalCenter()
Definition: TGLCamera.h:153
void SetExternalCenter(Bool_t x)
Set camera center diffrent than scene center, if enable is kTRUE.
Definition: TGLCamera.cxx:825
void SetCenterVec(Double_t x, Double_t y, Double_t z)
Set camera center vector.
Definition: TGLCamera.cxx:847
virtual Bool_t RotateArcBall(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2)
Rotate the camera round view volume center established in Setup().
Definition: TGLCamera.cxx:990
TGLRect & RefViewport()
Definition: TGLCamera.h:128
TGLVertex3 ViewportToWorld(const TGLVertex3 &viewportVertex, TGLMatrix *modviewMat=nullptr) const
Convert a '3D' viewport vertex to 3D world one.
Definition: TGLCamera.cxx:442
Base-class and default implementation of event-handler for TGLViewer.
virtual void GrabMouse()
Acquire mouse grab.
void SetMouseOverSelectDelay(Int_t ms)
Set delay of mouse-over probe (highlight).
virtual Bool_t HandleTimer(TTimer *t)
If mouse delay timer times out emit signal.
TGLEventHandler(TGWindow *w, TObject *obj)
Constructor.
virtual void SelectForClicked(Event_t *event)
Run selection (optionally with on secondary selection) and emit corresponding Clicked() signals.
TGLViewer * fGLViewer
TGLPhysicalShape * fLastMouseOverShape
virtual void UnGrabMouse()
Release mouse grab.
virtual Bool_t HandleExpose(Event_t *event)
Handle window expose 'event' - show.
TPoint fLastMouseOverPos
virtual void StartMouseTimer()
Start mouse timer in single-shot mode.
virtual void TriggerTooltip(const char *text)
Trigger display of tooltip.
virtual void StopMouseTimer()
Make sure mouse timers are not running.
virtual Bool_t HandleDoubleClick(Event_t *event)
Handle mouse double click 'event'.
virtual Bool_t HandleEvent(Event_t *event)
Handle generic Event_t type 'event' - provided to catch focus changes and terminate any interaction i...
virtual void PopupContextMenu(TGLPhysicalShape *pshp, Event_t *event, Int_t gx, Int_t gy)
Popup context menu.
virtual Bool_t HandleButton(Event_t *event)
Handle mouse button 'event'.
virtual Bool_t Rotate(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2)
Method to handle action TGLViewer::kDragCameraRotate.
virtual Bool_t HandleMotion(Event_t *event)
Handle mouse motion 'event'.
TTimer * fMouseTimer
Float_t fMouseDragFactor
Bool_t fMouseTimerRunning
Float_t fMouseWheelFactor
virtual Bool_t HandleCrossing(Event_t *event)
Handle generic Event_t type 'event' - provided to catch focus changes and terminate any interaction i...
Bool_t fViewerCentricControls
virtual Bool_t HandleConfigureNotify(Event_t *event)
Handle configure notify 'event' - a window resize/movement.
virtual Bool_t HandleKey(Event_t *event)
Handle keyboard 'event'.
void SetMouseOverTooltipDelay(Int_t ms)
Set delay of tooltip timer.
Bool_t fDoInternalSelection
virtual void Repaint()
Handle window expose 'event' - show.
virtual ~TGLEventHandler()
Destructor.
virtual void ClearMouseOver()
Clear mouse-over state and emit mouse-over signals.
TGToolTip * fTooltip
virtual void SelectForMouseOver()
Run selection (optionally with on secondary selection) and emit corresponding MouseOver() signals.
Int_t fTooltipPixelTolerance
virtual void RemoveTooltip()
Hide the tooltip.
virtual Bool_t HandleFocusChange(Event_t *event)
Handle generic Event_t type 'event' - provided to catch focus changes and terminate any interaction i...
Int_t ControlValue(Int_t v)
Float_t fArrowKeyFactor
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Process event of type 'event' - one of EEventType types, occurring at window location px,...
ELock CurrentLock() const
Definition: TGLLockable.h:61
static const char * LockName(ELock lock)
Return name-string for given lock-type.
Definition: TGLLockable.cxx:69
Bool_t IsLocked() const
Definition: TGLLockable.h:60
Abstract logical shape - a GL 'drawable' - base for all shapes - faceset sphere etc.
virtual void ProcessSelection(TGLRnrCtx &rnrCtx, TGLSelectRecord &rec)
Virtual method called-back after a secondary selection hit is recorded (see TGLViewer::HandleButton()...
virtual Bool_t AlwaysSecondarySelect() const
virtual Bool_t Handle(TGLRnrCtx &rnrCtx, TGLOvlSelectRecord &selRec, Event_t *event)
Handle overlay event.
Definition: TGLOverlay.cxx:46
Concrete physical shape - a GL drawable.
void InvokeContextMenu(TContextMenu &menu, UInt_t x, UInt_t y) const
Request creation of context menu on shape, attached to 'menu' at screen position 'x' 'y'.
Viewport (pixel base) 2D rectangle class.
Definition: TGLUtil.h:422
Int_t Height() const
Definition: TGLUtil.h:452
Int_t Width() const
Definition: TGLUtil.h:450
Bool_t IsPending() const
Definition: TGLViewer.h:417
void RequestDraw(Int_t milliSec, Short_t redrawLOD)
Definition: TGLViewer.h:411
@ kLODHigh
Definition: TGLRnrCtx.h:67
void SetEventKeySym(UInt_t k)
Definition: TGLRnrCtx.h:248
@ kWireFrame
Definition: TGLRnrCtx.h:48
@ kOutline
Definition: TGLRnrCtx.h:47
Float_t GetMinZ() const
Int_t GetN() const
Standard selection record including information about containing scene and details ob out selected ob...
ESecSelResult GetSecSelResult() const
void SetHighlight(Bool_t hlt)
void SetMultiple(Bool_t multi)
TObject * GetObject() const
TGLLogicalShape * GetLogShape() const
TGLPhysicalShape * GetPhysShape() const
static Float_t GetScreenScalingFactor()
Returns scaling factor between screen points and GL viewport pixels.
Definition: TGLUtil.cxx:1852
static void PointToViewport(Int_t &x, Int_t &y)
Convert from point/screen coordinates to GL viewport coordinates.
Definition: TGLUtil.cxx:1823
3 component (x/y/z) vector class.
Definition: TGLUtil.h:248
TGLRnrCtx * fRnrCtx
Definition: TGLViewerBase.h:62
void SetStyle(Short_t st)
Base GL viewer object - used by both standalone and embedded (in pad) GL.
Definition: TGLViewer.h:55
TGLRedrawTimer * fRedrawTimer
Definition: TGLViewer.h:135
virtual void MouseOver(TGLPhysicalShape *)
Emit MouseOver signal.
Definition: TGLViewer.cxx:2105
EPushAction fPushAction
Definition: TGLViewer.h:131
virtual void RefreshPadEditor(TObject *obj=nullptr)
Update GED editor if it is set.
Definition: TGLViewer.cxx:2286
virtual void Activated()
Definition: TGLViewer.h:363
EPushAction GetPushAction() const
Definition: TGLViewer.h:299
TGLSelectRecord fSelRec
select record in use as selected
Definition: TGLViewer.h:112
virtual void ReMouseOver(TObject *obj, UInt_t state)
Emit MouseOver signal.
Definition: TGLViewer.cxx:2135
virtual void Clicked(TObject *obj)
Emit Clicked signal.
Definition: TGLViewer.cxx:2158
@ kPushCamCenter
Definition: TGLViewer.h:126
virtual void SelectionChanged()
Update GUI components for embedded viewer selection change.
Definition: TGLViewer.cxx:2255
virtual void UnClicked(TObject *obj, UInt_t button, UInt_t state)
Emit UnClicked signal with button id and modifier state.
Definition: TGLViewer.cxx:2191
Bool_t RequestOverlaySelect(Int_t x, Int_t y)
Post request for secondary selection rendering of selected object around the window point (x,...
Definition: TGLViewer.cxx:1489
virtual void MouseIdle(TGLPhysicalShape *, UInt_t, UInt_t)
Emit MouseIdle signal.
Definition: TGLViewer.cxx:2203
void RequestDraw(Short_t LOD=TGLRnrCtx::kLODMed)
Post request for redraw of viewer at level of detail 'LOD' Request is directed via cross thread gVirt...
Definition: TGLViewer.cxx:438
void SwitchColorSet()
Switch between dark and light colorsets.
Definition: TGLViewer.cxx:1633
EDragAction fDragAction
Definition: TGLViewer.h:132
TGLSelectRecord fSecSelRec
select record from last select (should go to context)
Definition: TGLViewer.h:113
@ kOnRequest
Definition: TGLViewer.h:66
TGLWidget * fGLWidget
Definition: TGLViewer.h:185
TGLCamera & CurrentCamera() const
Definition: TGLViewer.h:268
TContextMenu * fContextMenu
external pad - remove replace with signal
Definition: TGLViewer.h:81
@ kDragCameraTruck
Definition: TGLViewer.h:128
@ kDragCameraRotate
Definition: TGLViewer.h:128
@ kDragOverlay
Definition: TGLViewer.h:129
@ kDragCameraDolly
Definition: TGLViewer.h:128
void UpdateScene(Bool_t redraw=kTRUE)
Force update of pad-scenes.
Definition: TGLViewer.cxx:336
virtual void OverlayDragFinished()
An overlay operation can result in change to an object.
Definition: TGLViewer.cxx:2275
Bool_t RequestSecondarySelect(Int_t x, Int_t y)
Request secondary select.
Definition: TGLViewer.cxx:1382
TGLSelectRecord & GetSelRec()
Definition: TGLViewer.h:390
void SetViewport(Int_t x, Int_t y, Int_t width, Int_t height)
Set viewer viewport (window area) with bottom/left at (x,y), with dimensions 'width'/'height'.
Definition: TGLViewer.cxx:1732
virtual void UnMouseOver(TObject *obj, UInt_t state)
Emit UnMouseOver signal.
Definition: TGLViewer.cxx:2147
virtual void ReClicked(TObject *obj, UInt_t button, UInt_t state)
Emit ReClicked signal with button id and modifier state.
Definition: TGLViewer.cxx:2179
void ClearCurrentOvlElm()
Reset current overlay-element to zero, eventually notifying the old one that the mouse has left.
Definition: TGLViewer.cxx:2328
void ApplySelection()
Process result from last selection (in fSelRec) and extract a new current selection from it.
Definition: TGLViewer.cxx:1472
Bool_t RequestSelect(Int_t x, Int_t y)
Post request for selection render pass viewer, picking objects around the window point (x,...
Definition: TGLViewer.cxx:1306
virtual void DoubleClicked()
Definition: TGLViewer.h:376
const TGLPhysicalShape * GetSelected() const
Return selected physical shape.
Definition: TGLViewer.cxx:2094
Bool_t fDebugMode
cache logicals during scene rebuilds
Definition: TGLViewer.h:156
Int_t fGLDevice
Definition: TGLViewer.h:186
TGLOvlSelectRecord fOvlSelRec
current overlay element
Definition: TGLViewer.h:117
TGLOverlayElement * fCurrentOvlElm
Definition: TGLViewer.h:116
void ResetCurrentCamera()
Resets position/rotation of current camera to default values.
Definition: TGLViewer.cxx:358
TGLWidget * GetGLWidget()
Definition: TGLViewer.h:223
Handle_t GetId() const
Definition: TGObject.h:41
A tooltip can be a one or multiple lines help text that is displayed in a window when the mouse curso...
Definition: TGToolTip.h:24
void SetDelay(Long_t delayms)
Set delay in milliseconds.
Definition: TGToolTip.cxx:399
void Hide()
Hide tool tip window.
Definition: TGToolTip.cxx:250
void SetPosition(Int_t x, Int_t y)
Set popup position within specified frame (as specified in the ctor).
Definition: TGToolTip.cxx:409
void SetText(const char *new_text)
Set new tool tip text.
Definition: TGToolTip.cxx:390
void Reset()
Reset tool tip popup delay timer.
Definition: TGToolTip.cxx:263
ROOT GUI Window base class.
Definition: TGWindow.h:23
Mother of all ROOT objects.
Definition: TObject.h:41
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:956
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:970
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:483
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:944
SCoord_t fY
Definition: TPoint.h:36
SCoord_t fX
Definition: TPoint.h:35
Handles synchronous and a-synchronous timer events.
Definition: TTimer.h:51
virtual void TurnOff()
Remove timer from system timer list.
Definition: TTimer.cxx:231
virtual void Start(Long_t milliSec=-1, Bool_t singleShot=kFALSE)
Starts the timer with a milliSec timeout.
Definition: TTimer.cxx:213
virtual void TurnOn()
Add the timer to the system timer list.
Definition: TTimer.cxx:243
void Reset()
Reset the timer.
Definition: TTimer.cxx:159
void SetTime(Long_t milliSec)
Definition: TTimer.h:91
virtual void Stop()
Definition: TTimer.h:94
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
static constexpr double ms
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition: TMath.h:693
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition: TMathBase.h:123
Event structure.
Definition: GuiTypes.h:174
EGEventType fType
of event (see EGEventType)
Definition: GuiTypes.h:175
Int_t fY
pointer x, y coordinates in event window
Definition: GuiTypes.h:178
Int_t fXRoot
Definition: GuiTypes.h:179
UInt_t fState
key or button mask
Definition: GuiTypes.h:181
Int_t fYRoot
coordinates relative to root
Definition: GuiTypes.h:179
Int_t fX
Definition: GuiTypes.h:178
UInt_t fCode
key or button code
Definition: GuiTypes.h:180