Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 (nullptr),
62 fLastPos (-1, -1),
63 fLastMouseOverPos (-1, -1),
64 fLastMouseOverShape (nullptr),
65 fTooltip (nullptr),
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(nullptr, 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(nullptr, 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(nullptr, 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 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;
615 if (fGLViewer->RequestOverlaySelect(event->fX, event->fY))
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 {
644 SelectForClicked(event);
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
654 fGLViewer->RequestSelect(event->fX, event->fY);
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(nullptr, 0, 0);
692 if (event->fCode == kButton1)
693 {
695 if (fGLViewer->GetSelected() == nullptr)
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(nullptr, 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(nullptr, 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{
1037 fLastMouseOverShape = nullptr;
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{
1128 fMouseTimer->SetTime(ms);
1129}
1130
1131////////////////////////////////////////////////////////////////////////////////
1132/// Set delay of tooltip timer.
1133
1135{
1136 fTooltip->SetDelay(ms);
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
short Short_t
Definition RtypesCore.h:39
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:377
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
#define gClient
Definition TGClient.h:156
Option_t Option_t TPoint TPoint const char text
Int_t gDebug
Definition TROOT.cxx:597
#define gGLManager
Definition TVirtualGL.h:159
#define gPad
#define gVirtualX
Definition TVirtualX.h:337
This class provides an interface to context sensitive popup menus.
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.
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'.
virtual Bool_t Truck(Double_t xDelta, Double_t yDelta)
Truck the camera - 'move camera parallel to film plane'.
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().
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.
void SetCenterVec(Double_t x, Double_t y, Double_t z)
Set camera center vector.
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().
TGLRect & RefViewport()
Definition TGLCamera.h:128
TGLVertex3 ViewportToWorld(const TGLVertex3 &viewportVertex, TGLMatrix *modviewMat=nullptr) const
Convert a '3D' viewport vertex to 3D world one.
Base-class and default implementation of event-handler for TGLViewer.
Bool_t HandleDoubleClick(Event_t *event) override
Handle mouse double click 'event'.
virtual void GrabMouse()
Acquire mouse grab.
void SetMouseOverSelectDelay(Int_t ms)
Set delay of mouse-over probe (highlight).
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.
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.
Bool_t HandleTimer(TTimer *t) override
If mouse delay timer times out emit signal.
virtual void PopupContextMenu(TGLPhysicalShape *pshp, Event_t *event, Int_t gx, Int_t gy)
Popup context menu.
Bool_t HandleFocusChange(Event_t *event) override
Handle generic Event_t type 'event' - provided to catch focus changes and terminate any interaction i...
Bool_t HandleButton(Event_t *event) override
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.
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Process event of type 'event' - one of EEventType types, occurring at window location px,...
~TGLEventHandler() override
Destructor.
Bool_t HandleKey(Event_t *event) override
Handle keyboard 'event'.
Bool_t HandleConfigureNotify(Event_t *event) override
Handle configure notify 'event' - a window resize/movement.
Float_t fMouseWheelFactor
Bool_t fViewerCentricControls
Bool_t HandleMotion(Event_t *event) override
Handle mouse motion 'event'.
Bool_t HandleEvent(Event_t *event) override
Handle generic Event_t type 'event' - provided to catch focus changes and terminate any interaction i...
void SetMouseOverTooltipDelay(Int_t ms)
Set delay of tooltip timer.
Bool_t fDoInternalSelection
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.
Bool_t HandleCrossing(Event_t *event) override
Handle generic Event_t type 'event' - provided to catch focus changes and terminate any interaction i...
virtual void RemoveTooltip()
Hide the tooltip.
Int_t ControlValue(Int_t v)
void Repaint() override
Handle window expose 'event' - show.
ELock CurrentLock() const
Definition TGLLockable.h:61
static const char * LockName(ELock lock)
Return name-string for given lock-type.
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.
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
void SetEventKeySym(UInt_t k)
Definition TGLRnrCtx.h:248
Float_t GetMinZ() 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
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.
EPushAction fPushAction
Definition TGLViewer.h:131
virtual void RefreshPadEditor(TObject *obj=nullptr)
Update GED editor if it is set.
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.
virtual void Clicked(TObject *obj)
Emit Clicked signal.
@ kPushCamCenter
Definition TGLViewer.h:126
virtual void SelectionChanged()
Update GUI components for embedded viewer selection change.
virtual void UnClicked(TObject *obj, UInt_t button, UInt_t state)
Emit UnClicked signal with button id and modifier state.
Bool_t RequestOverlaySelect(Int_t x, Int_t y)
Post request for secondary selection rendering of selected object around the window point (x,...
virtual void MouseIdle(TGLPhysicalShape *, UInt_t, UInt_t)
Emit MouseIdle signal.
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...
void SwitchColorSet()
Switch between dark and light colorsets.
EDragAction fDragAction
Definition TGLViewer.h:132
TGLSelectRecord fSecSelRec
select record from last select (should go to context)
Definition TGLViewer.h:113
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
@ kDragCameraDolly
Definition TGLViewer.h:128
void UpdateScene(Bool_t redraw=kTRUE)
Force update of pad-scenes.
virtual void OverlayDragFinished()
An overlay operation can result in change to an object.
Bool_t RequestSecondarySelect(Int_t x, Int_t y)
Request secondary select.
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'.
virtual void UnMouseOver(TObject *obj, UInt_t state)
Emit UnMouseOver signal.
virtual void ReClicked(TObject *obj, UInt_t button, UInt_t state)
Emit ReClicked signal with button id and modifier state.
void ClearCurrentOvlElm()
Reset current overlay-element to zero, eventually notifying the old one that the mouse has left.
void ApplySelection()
Process result from last selection (in fSelRec) and extract a new current selection from it.
Bool_t RequestSelect(Int_t x, Int_t y)
Post request for selection render pass viewer, picking objects around the window point (x,...
virtual void DoubleClicked()
Definition TGLViewer.h:376
const TGLPhysicalShape * GetSelected() const
Return selected physical shape.
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.
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.
void Hide()
Hide tool tip window.
void SetPosition(Int_t x, Int_t y)
Set popup position within specified frame (as specified in the ctor).
void SetText(const char *new_text)
Set new tool tip text.
void Reset()
Reset tool tip popup delay timer.
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:973
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
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:961
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
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
Int_t fCount
if non-zero, at least this many more exposes
Definition GuiTypes.h:183
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