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 {
509 fGLViewer->RequestSelect(event->fX, event->fY);
510 if (fGLViewer->fSelRec.GetN() > 0)
511 {
512 TGLVector3 v(event->fX, event->fY, 0.5*fGLViewer->fSelRec.GetMinZ());
516 {
518 fGLViewer->CurrentCamera().SetCenterVec(v.X(), v.Y(), v.Z());
519 }
520 else
521 {
523 TObject* obj = rec.GetObject();
525 Int_t x = event->fX, y = event->fY;
527 new TGLAnnotation(fGLViewer, obj->GetTitle(),
528 x * 1.0f/vp.Width(),
529 1 - y * 1.0f/vp.Height(), v);
530 }
531
533 }
534 return kTRUE;
535 }
536
537 Bool_t handled = kFALSE;
538
540 {
541 Event_t e = *event;
544 {
545 handled = kTRUE;
548 }
549 }
550
551 if ( ! handled)
552 {
553 switch (event->fCode)
554 {
555 // LEFT mouse button
556 case kButton1:
557 {
559 if (fMouseTimer)
560 {
563 }
564 break;
565 }
566 // MIDDLE mouse button
567 case kButton2:
568 {
570 break;
571 }
572 // RIGHT mouse button
573 case kButton3:
574 {
576 break;
577 }
578 }
579 }
580 }
581 // Button UP
582 else if (event->fType == kButtonRelease)
583 {
584 fActiveButtonID = 0;
585
586 if (fInPointerGrab)
587 {
588 UnGrabMouse();
589 }
590 else
591 {
592 Warning("TGLEventHandler::HandleButton", "Unexpected button-release.");
593 }
594
595 if (fIgnoreButtonUp)
596 {
598 return kTRUE;
599 }
600
602 {
603 // This should be 'tool' dependant.
606 return kTRUE;
607 }
609 {
610 Event_t e = *event;
614 if (fGLViewer->RequestOverlaySelect(event->fX, event->fY))
616 }
619 {
621 }
622
624
625 if (fGLViewer->fGLDevice != -1)
626 {
627 gGLManager->MarkForDirectCopy(fGLViewer->fGLDevice, kFALSE);
628 }
629
630 if (event->fX == fButtonPushPos.fX && event->fY == fButtonPushPos.fY)
631 {
632 if (event->fCode == kButton1)
633 {
635 {
636 if (fGLViewer->RequestSelect(event->fX, event->fY))
637 {
639 }
640 }
641 else
642 {
643 SelectForClicked(event);
644 }
645 }
646 else if (event->fCode == kButton3)
647 {
648 Int_t x, y;
649 Window_t childdum;
650 gVirtualX->TranslateCoordinates(fGLViewer->fGLWidget->GetId(), gClient->GetDefaultRoot()->GetId(),
651 event->fX, event->fY, x, y, childdum);
652
653 fGLViewer->RequestSelect(event->fX, event->fY);
654
656 }
657 }
658
659 if (event->fCode == kButton1 && fMouseTimer)
660 {
662 }
663 }
664
665 return kTRUE;
666}
667
668////////////////////////////////////////////////////////////////////////////////
669/// Handle mouse double click 'event'.
670
672{
673 if (fGLViewer->IsLocked()) {
674 if (gDebug>3) {
675 Info("TGLEventHandler::HandleDoubleClick", "ignored - viewer is %s",
677 }
678 return kFALSE;
679 }
680
681 if (event->fCode > 3)
682 return kTRUE;
683
684 if (fActiveButtonID)
685 return kTRUE;
686
687 fActiveButtonID = event->fCode;
688 GrabMouse();
689
690 fGLViewer->MouseIdle(0, 0, 0);
691 if (event->fCode == kButton1)
692 {
694 if (fGLViewer->GetSelected() == 0)
696 }
697 return kTRUE;
698}
699
700////////////////////////////////////////////////////////////////////////////////
701/// Handle configure notify 'event' - a window resize/movement.
702
704{
705 if (fGLViewer->IsLocked())
706 {
707 if (gDebug > 0) {
708 Info("TGLEventHandler::HandleConfigureNotify", "ignored - viewer is %s",
710 }
711 return kFALSE;
712 }
713 if (event)
714 {
715 Int_t x = event->fX, y = event->fY, w = event->fWidth, h = event->fHeight;
717 fGLViewer->SetViewport(x, y, w, h);
719 }
720 return kTRUE;
721}
722
723////////////////////////////////////////////////////////////////////////////////
724/// Handle window expose 'event' - show.
725
727{
728 if (event->fCount != 0) return kTRUE;
729
730 if (fGLViewer->IsLocked()) {
731 if (gDebug > 0) {
732 Info("TGLViewer::HandleExpose", "ignored - viewer is %s",
734 }
735 return kFALSE;
736 }
737
739 return kTRUE;
740}
741
742////////////////////////////////////////////////////////////////////////////////
743/// Handle keyboard 'event'.
744
746{
747 // We only handle key-press events.
748 if (event->fType == kKeyRelease)
749 return kTRUE;
750
751 if (fTooltipShown)
752 fTooltip->Hide();
753
754 fLastEventState = event->fState;
755
756 fGLViewer->MouseIdle(0, 0, 0);
757 if (fGLViewer->IsLocked()) {
758 if (gDebug>3) {
759 Info("TGLEventHandler::HandleKey", "ignored - viewer is %s",
761 }
762 return kFALSE;
763 }
764
765 char tmp[10] = {0};
766 UInt_t keysym = 0;
767
768 if (fGLViewer->fGLDevice == -1)
769 gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
770 else
771 keysym = event->fCode;
773
774 Bool_t handled = kFALSE;
775 Bool_t redraw = kFALSE;
776
778 {
779 Event_t e = *event;
782 {
783 handled = kTRUE;
784 redraw = kTRUE;
785 }
786 }
787
788 if ( ! handled)
789 {
790 const Bool_t mod1 = event->fState & kKeyControlMask;
791 const Bool_t mod2 = event->fState & kKeyShiftMask;
792
793 const Int_t shift = TMath::Nint(fArrowKeyFactor * ControlValue(10));
794
795 switch (keysym)
796 {
797 case kKey_R:
798 case kKey_r:
800 redraw = kTRUE;
801 break;
802 case kKey_E:
803 case kKey_e:
805 redraw = kTRUE;
806 break;
807 case kKey_W:
808 case kKey_w:
810 redraw = kTRUE;
811 break;
812 case kKey_T:
813 case kKey_t:
815 redraw = kTRUE;
816 break;
817
818 case kKey_F1:
821 break;
822
823 // Camera
824 case kKey_A:
825 case kKey_a:
826 fArcBall = ! fArcBall;
827 break;
828 case kKey_Plus:
829 case kKey_J:
830 case kKey_j:
831 redraw = fGLViewer->CurrentCamera().Dolly(shift, mod1, mod2);
832 break;
833 case kKey_Minus:
834 case kKey_K:
835 case kKey_k:
836 redraw = fGLViewer->CurrentCamera().Dolly(-shift, mod1, mod2);
837 break;
838 case kKey_Up:
839 redraw = fGLViewer->CurrentCamera().Truck(0, shift, mod1, mod2);
840 break;
841 case kKey_Down:
842 redraw = fGLViewer->CurrentCamera().Truck(0, -shift, mod1, mod2);
843 break;
844 case kKey_Left:
845 redraw = fGLViewer->CurrentCamera().Truck(-shift, 0, mod1, mod2);
846 break;
847 case kKey_Right:
848 redraw = fGLViewer->CurrentCamera().Truck(shift, 0, mod1, mod2);
849 break;
850 case kKey_Home:
851 if (mod1) {
855 } else {
857 }
858 redraw = kTRUE;
859 break;
860
861 // Toggle debugging mode
862 case kKey_d:
864 redraw = kTRUE;
865 Info("OpenGL viewer debug mode : ", fGLViewer->fDebugMode ? "ON" : "OFF");
866 break;
867 // Forced rebuild for debugging mode
868 case kKey_D:
869 if (fGLViewer->fDebugMode) {
870 Info("OpenGL viewer FORCED rebuild", " ");
872 }
873 default:;
874 } // switch
875 }
876
877 if (redraw) {
878 if (fGLViewer->fGLDevice != -1)
879 gGLManager->MarkForDirectCopy(fGLViewer->fGLDevice, kTRUE);
881 }
882
883 return kTRUE;
884}
885
886////////////////////////////////////////////////////////////////////////////////
887/// Handle mouse motion 'event'.
888
890{
891 fGLViewer->MouseIdle(0, 0, 0);
892 if (fGLViewer->IsLocked()) {
893 if (gDebug>3) {
894 Info("TGLEventHandler::HandleMotion", "ignored - viewer is %s",
896 }
897 return kFALSE;
898 }
899
900 Bool_t processed = kFALSE, changed = kFALSE;
902
903 // Camera interface requires GL coords - Y inverted
906 Bool_t mod1 = event->fState & kKeyControlMask;
907 Bool_t mod2 = event->fState & kKeyShiftMask;
908 TGLUtil::PointToViewport(xDelta, yDelta);
909
911
912 if (fTooltipShown &&
915 {
917 }
918
920 {
922 if (gDebug > 2)
923 Info("TGLEventHandler::HandleMotion", "Redraw pending, ignoring.");
924 return kTRUE;
925 }
926 changed = fGLViewer->RequestOverlaySelect(event->fX, event->fY);
928 {
929 Event_t e = *event;
932 }
934 if ( ! processed && ! fMouseTimerRunning)
936 }
938 {
939 processed = Rotate(xDelta, yDelta, mod1, mod2);
940 }
942 {
943 processed = fGLViewer->CurrentCamera().Truck(xDelta, -yDelta, mod1, mod2);
944 }
946 {
947 processed = fGLViewer->CurrentCamera().Dolly(yDelta - xDelta, mod1, mod2);
948 }
950 {
952 Event_t e = *event;
955 }
956 }
957
958 fLastPos.fX = event->fX;
959 fLastPos.fY = event->fY;
960
961 fLastGlobalPos.fX = event->fXRoot;
962 fLastGlobalPos.fY = event->fYRoot;
963
964 if (processed || changed) {
965 if (fGLViewer->fGLDevice != -1) {
966 gGLManager->MarkForDirectCopy(fGLViewer->fGLDevice, kTRUE);
967 gVirtualX->SetDrawMode(TVirtualX::kCopy);
968 }
969
971 }
972
973 return processed;
974}
975
976////////////////////////////////////////////////////////////////////////////////
977/// Method to handle action TGLViewer::kDragCameraRotate.
978
980{
982 if (fArcBall) return cam.RotateArcBall(xDelta, -yDelta, mod1, mod2);
983 else return cam.Rotate (xDelta, -yDelta, mod1, mod2);
984}
985
986////////////////////////////////////////////////////////////////////////////////
987/// If mouse delay timer times out emit signal.
988
990{
991 if (t != fMouseTimer) return kFALSE;
992
994
996 if (gDebug > 2)
997 Info("TGLEventHandler::HandleTimer", "Redraw pending, ignoring.");
998 return kTRUE;
999 }
1000
1002 {
1004 {
1006 }
1007 }
1008 return kTRUE;
1009}
1010
1011////////////////////////////////////////////////////////////////////////////////
1012/// Start mouse timer in single-shot mode.
1013
1015{
1016 fMouseTimer->Start(-1, kTRUE);
1018}
1019
1020////////////////////////////////////////////////////////////////////////////////
1021/// Make sure mouse timers are not running.
1022
1024{
1026 fMouseTimer->Stop();
1027}
1028
1029////////////////////////////////////////////////////////////////////////////////
1030/// Clear mouse-over state and emit mouse-over signals.
1031/// Current overlay element is also told the mouse has left.
1032
1034{
1040
1042}
1043
1044////////////////////////////////////////////////////////////////////////////////
1045/// Handle window expose 'event' - show.
1046
1048{
1049 if (fGLViewer->IsLocked()) {
1050 if (gDebug > 0) {
1051 Info("TGLViewer::HandleExpose", "ignored - viewer is %s",
1053 }
1054 return;
1055 }
1057}
1058
1059////////////////////////////////////////////////////////////////////////////////
1060/// Popup context menu.
1061
1063 Int_t gx, Int_t gy)
1064{
1065 if (!fGLViewer->fContextMenu)
1066 {
1067 fGLViewer->fContextMenu = new TContextMenu("glcm", "GL Viewer Context Menu");
1068 }
1069
1070 if (pshp)
1071 {
1072 fActiveButtonID = 0;
1073 UnGrabMouse();
1074
1075 pshp->InvokeContextMenu(*fGLViewer->fContextMenu, gx, gy);
1076 }
1077
1078 // This is dangerous ... should have special menu, probably even
1079 // tool / context specific.
1080 // else
1081 // {
1082 // fGLViewer->fContextMenu->Popup(x, y, fGLViewer);
1083 // }
1084}
1085
1086////////////////////////////////////////////////////////////////////////////////
1087/// Trigger display of tooltip.
1088
1090{
1091 static UInt_t screenW = 0, screenH = 0;
1095 Int_t x = fTooltipPos.fX + 16, y = fTooltipPos.fY + 16;
1096 if (screenW == 0 || screenH == 0) {
1097 screenW = gClient->GetDisplayWidth();
1098 screenH = gClient->GetDisplayHeight();
1099 }
1100 if (x + 5 + fTooltip->GetWidth() > screenW) {
1101 x = screenW - fTooltip->GetWidth() - 5;
1102 if (y + 5 + fTooltip->GetHeight() > screenH) {
1103 y -= (25 + fTooltip->GetHeight());
1104 }
1105 }
1106 if (y + 5 + fTooltip->GetHeight() > screenH) {
1107 y = screenH - fTooltip->GetHeight() - 10;
1108 }
1110 fTooltip->Reset();
1111}
1112
1113////////////////////////////////////////////////////////////////////////////////
1114/// Hide the tooltip.
1115
1117{
1118 fTooltip->Hide();
1120}
1121
1122////////////////////////////////////////////////////////////////////////////////
1123/// Set delay of mouse-over probe (highlight).
1124
1126{
1128}
1129
1130////////////////////////////////////////////////////////////////////////////////
1131/// Set delay of tooltip timer.
1132
1134{
1136}
@ 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:59
@ kButtonRelease
Definition: GuiTypes.h:59
@ kButtonPress
Definition: GuiTypes.h:59
@ kButtonDoubleClick
Definition: GuiTypes.h:63
@ kFocusOut
Definition: GuiTypes.h:60
@ kMotionNotify
Definition: GuiTypes.h:60
@ kFocusIn
Definition: GuiTypes.h:60
@ kEnterNotify
Definition: GuiTypes.h:60
@ kOtherEvent
Definition: GuiTypes.h:63
@ kKeyRelease
Definition: GuiTypes.h:59
@ kLeaveNotify
Definition: GuiTypes.h:60
const Mask_t kButtonPressMask
Definition: GuiTypes.h:160
const Mask_t kKeyMod1Mask
Definition: GuiTypes.h:197
const Mask_t kPointerMotionMask
Definition: GuiTypes.h:162
const Mask_t kKeyShiftMask
Definition: GuiTypes.h:194
const Handle_t kNone
Definition: GuiTypes.h:87
const Mask_t kKeyControlMask
Definition: GuiTypes.h:196
const Mask_t kKeyMod2Mask
Definition: GuiTypes.h:198
const Mask_t kButtonReleaseMask
Definition: GuiTypes.h:161
@ kButton4
Definition: GuiTypes.h:214
@ kButton7
Definition: GuiTypes.h:214
@ kButton2
Definition: GuiTypes.h:213
@ kButton5
Definition: GuiTypes.h:214
@ kButton3
Definition: GuiTypes.h:213
@ kButton1
Definition: GuiTypes.h:213
@ kButton6
Definition: GuiTypes.h:214
Handle_t Window_t
Definition: GuiTypes.h:28
@ 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:41
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
short Short_t
Definition: RtypesCore.h:35
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
#define gClient
Definition: TGClient.h:166
#define gGLManager
Definition: TVirtualGL.h:162
#define gPad
Definition: TVirtualPad.h:286
#define gVirtualX
Definition: TVirtualX.h:345
This class provides an interface to context sensitive popup menus.
Definition: TContextMenu.h:40
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:272
UInt_t GetWidth() const
Definition: TGFrame.h:271
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
TGLVertex3 ViewportToWorld(const TGLVertex3 &viewportVertex, TGLMatrix *modviewMat=0) const
Convert a '3D' viewport vertex to 3D world one.
Definition: TGLCamera.cxx:442
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
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:421
Int_t Height() const
Definition: TGLUtil.h:451
Int_t Width() const
Definition: TGLUtil.h:449
Bool_t IsPending() const
Definition: TGLViewer.h:418
void RequestDraw(Int_t milliSec, Short_t redrawLOD)
Definition: TGLViewer.h:412
@ 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 void PointToViewport(Int_t &x, Int_t &y)
Convert from point/screen coordinates to GL viewport coordinates.
Definition: TGLUtil.cxx:1818
3 component (x/y/z) vector class.
Definition: TGLUtil.h:247
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:57
TGLRedrawTimer * fRedrawTimer
Definition: TGLViewer.h:137
virtual void MouseOver(TGLPhysicalShape *)
Emit MouseOver signal.
Definition: TGLViewer.cxx:2097
EPushAction fPushAction
Definition: TGLViewer.h:133
virtual void Activated()
Definition: TGLViewer.h:364
virtual void RefreshPadEditor(TObject *obj=0)
Update GED editor if it is set.
Definition: TGLViewer.cxx:2278
EPushAction GetPushAction() const
Definition: TGLViewer.h:300
TGLSelectRecord fSelRec
select record in use as selected
Definition: TGLViewer.h:114
virtual void ReMouseOver(TObject *obj, UInt_t state)
Emit MouseOver signal.
Definition: TGLViewer.cxx:2127
virtual void Clicked(TObject *obj)
Emit Clicked signal.
Definition: TGLViewer.cxx:2150
@ kPushCamCenter
Definition: TGLViewer.h:128
virtual void SelectionChanged()
Update GUI components for embedded viewer selection change.
Definition: TGLViewer.cxx:2247
virtual void UnClicked(TObject *obj, UInt_t button, UInt_t state)
Emit UnClicked signal with button id and modifier state.
Definition: TGLViewer.cxx:2183
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:1491
virtual void MouseIdle(TGLPhysicalShape *, UInt_t, UInt_t)
Emit MouseIdle signal.
Definition: TGLViewer.cxx:2195
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:440
void SwitchColorSet()
Switch between dark and light colorsets.
Definition: TGLViewer.cxx:1635
EDragAction fDragAction
Definition: TGLViewer.h:134
TGLSelectRecord fSecSelRec
select record from last select (should go to context)
Definition: TGLViewer.h:115
@ kOnRequest
Definition: TGLViewer.h:68
TGLWidget * fGLWidget
Definition: TGLViewer.h:187
TGLCamera & CurrentCamera() const
Definition: TGLViewer.h:269
TContextMenu * fContextMenu
external pad - remove replace with signal
Definition: TGLViewer.h:83
@ kDragCameraTruck
Definition: TGLViewer.h:130
@ kDragCameraRotate
Definition: TGLViewer.h:130
@ kDragOverlay
Definition: TGLViewer.h:131
@ kDragCameraDolly
Definition: TGLViewer.h:130
void UpdateScene(Bool_t redraw=kTRUE)
Force update of pad-scenes.
Definition: TGLViewer.cxx:338
virtual void OverlayDragFinished()
An overlay operation can result in change to an object.
Definition: TGLViewer.cxx:2267
Bool_t RequestSecondarySelect(Int_t x, Int_t y)
Request secondary select.
Definition: TGLViewer.cxx:1384
TGLSelectRecord & GetSelRec()
Definition: TGLViewer.h:391
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:1724
virtual void UnMouseOver(TObject *obj, UInt_t state)
Emit UnMouseOver signal.
Definition: TGLViewer.cxx:2139
virtual void ReClicked(TObject *obj, UInt_t button, UInt_t state)
Emit ReClicked signal with button id and modifier state.
Definition: TGLViewer.cxx:2171
void ClearCurrentOvlElm()
Reset current overlay-element to zero, eventually notifying the old one that the mouse has left.
Definition: TGLViewer.cxx:2320
void ApplySelection()
Process result from last selection (in fSelRec) and extract a new current selection from it.
Definition: TGLViewer.cxx:1474
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:1308
virtual void DoubleClicked()
Definition: TGLViewer.h:377
const TGLPhysicalShape * GetSelected() const
Return selected physical shape.
Definition: TGLViewer.cxx:2086
Bool_t fDebugMode
cache logicals during scene rebuilds
Definition: TGLViewer.h:158
Int_t fGLDevice
Definition: TGLViewer.h:188
TGLOvlSelectRecord fOvlSelRec
current overlay element
Definition: TGLViewer.h:119
TGLOverlayElement * fCurrentOvlElm
Definition: TGLViewer.h:118
void ResetCurrentCamera()
Resets position/rotation of current camera to default values.
Definition: TGLViewer.cxx:360
TGLWidget * GetGLWidget()
Definition: TGLViewer.h:225
Handle_t GetId() const
Definition: TGObject.h:47
void SetDelay(Long_t delayms)
Set delay in milliseconds.
Definition: TGToolTip.cxx:395
void Hide()
Hide tool tip window.
Definition: TGToolTip.cxx:246
void SetPosition(Int_t x, Int_t y)
Set popup position within specified frame (as specified in the ctor).
Definition: TGToolTip.cxx:405
void SetText(const char *new_text)
Set new tool tip text.
Definition: TGToolTip.cxx:386
void Reset()
Reset tool tip popup delay timer.
Definition: TGToolTip.cxx:259
Mother of all ROOT objects.
Definition: TObject.h:37
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:401
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
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:229
virtual void Start(Long_t milliSec=-1, Bool_t singleShot=kFALSE)
Starts the timer with a milliSec timeout.
Definition: TTimer.cxx:211
virtual void TurnOn()
Add the timer to the system timer list.
Definition: TTimer.cxx:241
void Reset()
Reset the timer.
Definition: TTimer.cxx:157
void SetTime(Long_t milliSec)
Definition: TTimer.h:90
virtual void Stop()
Definition: TTimer.h:93
TText * text
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:703
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
EGEventType fType
Definition: GuiTypes.h:174
Int_t fY
Definition: GuiTypes.h:177
Int_t fXRoot
Definition: GuiTypes.h:178
Int_t fCount
Definition: GuiTypes.h:182
UInt_t fState
Definition: GuiTypes.h:180
Int_t fYRoot
Definition: GuiTypes.h:178
Int_t fX
Definition: GuiTypes.h:177
UInt_t fCode
Definition: GuiTypes.h:179