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 (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{
1127 fMouseTimer->SetTime(ms);
1128}
1129
1130////////////////////////////////////////////////////////////////////////////////
1131/// Set delay of tooltip timer.
1132
1134{
1135 fTooltip->SetDelay(ms);
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: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
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
Handle_t Window_t
Window handle.
Definition GuiTypes.h:29
@ 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:92
short Short_t
Definition RtypesCore.h:39
const Bool_t kTRUE
Definition RtypesCore.h:91
#define ClassImp(name)
Definition Rtypes.h:364
R__EXTERN TEnv * gEnv
Definition TEnv.h:171
#define gClient
Definition TGClient.h:166
Int_t gDebug
Definition TROOT.cxx:590
#define gGLManager
Definition TVirtualGL.h:162
#define gPad
#define gVirtualX
Definition TVirtualX.h:338
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:249
UInt_t GetWidth() const
Definition TGFrame.h:248
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'.
TGLVertex3 ViewportToWorld(const TGLVertex3 &viewportVertex, TGLMatrix *modviewMat=0) const
Convert a '3D' viewport vertex to 3D world one.
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
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.
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'.
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.
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)
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.
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:416
void RequestDraw(Int_t milliSec, Short_t redrawLOD)
Definition TGLViewer.h:410
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 void PointToViewport(Int_t &x, Int_t &y)
Convert from point/screen coordinates to GL viewport coordinates.
Definition TGLUtil.cxx:1817
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 Activated()
Definition TGLViewer.h:362
virtual void RefreshPadEditor(TObject *obj=0)
Update GED editor if it is set.
EPushAction GetPushAction() const
Definition TGLViewer.h:298
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:267
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:389
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:375
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:47
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.
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:879
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:893
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:403
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:867
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
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:713
Short_t Abs(Short_t d)
Definition TMathBase.h:120
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