00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "TGLEventHandler.h"
00020 #include "TGEventHandler.h"
00021 #include "TGLViewer.h"
00022 #include "TGLWidget.h"
00023 #include "TGWindow.h"
00024 #include "TPoint.h"
00025 #include "TVirtualPad.h"
00026 #include "TVirtualX.h"
00027 #include "TGClient.h"
00028 #include "TVirtualGL.h"
00029 #include "TGLOverlay.h"
00030 #include "TGLLogicalShape.h"
00031 #include "TGLPhysicalShape.h"
00032 #include "TContextMenu.h"
00033 #include "TGToolTip.h"
00034 #include "KeySymbols.h"
00035 #include "TGLAnnotation.h"
00036 #include "TEnv.h"
00037 #include "TMath.h"
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 ClassImp(TGLEventHandler);
00058
00059
00060 TGLEventHandler::TGLEventHandler(TGWindow *w, TObject *obj) :
00061 TGEventHandler ("TGLEventHandler", w, obj),
00062 fGLViewer ((TGLViewer *)obj),
00063 fMouseTimer (0),
00064 fLastPos (-1, -1),
00065 fLastMouseOverPos (-1, -1),
00066 fLastMouseOverShape (0),
00067 fTooltip (0),
00068 fActiveButtonID (0),
00069 fLastEventState (0),
00070 fIgnoreButtonUp (kFALSE),
00071 fInPointerGrab (kFALSE),
00072 fMouseTimerRunning (kFALSE),
00073 fTooltipShown (kFALSE),
00074 fTooltipPixelTolerance (3),
00075 fSecSelType(TGLViewer::kOnRequest),
00076 fDoInternalSelection(kTRUE),
00077 fViewerCentricControls(kFALSE)
00078 {
00079
00080
00081 fMouseTimer = new TTimer(this, 80);
00082 fTooltip = new TGToolTip(0, 0, "", 650);
00083 fTooltip->Hide();
00084 fViewerCentricControls = gEnv->GetValue("OpenGL.EventHandler.ViewerCentricControls", 0) != 0;
00085 fArrowKeyFactor = gEnv->GetValue("OpenGL.EventHandler.ArrowKeyFactor", 1.0);
00086 fMouseDragFactor = gEnv->GetValue("OpenGL.EventHandler.MouseDragFactor", 1.0);
00087 fMouseWheelFactor = gEnv->GetValue("OpenGL.EventHandler.MouseWheelFactor", 1.0);
00088 }
00089
00090
00091 TGLEventHandler::~TGLEventHandler()
00092 {
00093
00094
00095 delete fMouseTimer;
00096 delete fTooltip;
00097 }
00098
00099
00100 void TGLEventHandler::GrabMouse()
00101 {
00102
00103
00104 if (!fInPointerGrab)
00105 {
00106 gVirtualX->GrabPointer(fGLViewer->GetGLWidget()->GetId(),
00107 kButtonPressMask | kButtonReleaseMask | kPointerMotionMask,
00108 kNone, kNone, kTRUE, kFALSE);
00109 fInPointerGrab = kTRUE;
00110 }
00111 }
00112
00113
00114 void TGLEventHandler::UnGrabMouse()
00115 {
00116
00117
00118 if (fInPointerGrab)
00119 {
00120 gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
00121 fInPointerGrab = kFALSE;
00122 }
00123 }
00124
00125
00126 void TGLEventHandler::SelectForClicked(Event_t *event)
00127 {
00128
00129
00130
00131
00132 fGLViewer->RequestSelect(fLastPos.fX, fLastPos.fY);
00133
00134 TGLPhysicalShape *pshp = fGLViewer->fSelRec.GetPhysShape();
00135 TGLLogicalShape *lshp = pshp ? const_cast<TGLLogicalShape*>(pshp->GetLogical()) : 0;
00136 TObject *obj = lshp ? lshp->GetExternal() : 0;
00137
00138
00139 if (lshp && (event->fState & kKeyMod1Mask || (fSecSelType == TGLViewer::kOnRequest && lshp->AlwaysSecondarySelect())))
00140 {
00141 fGLViewer->RequestSecondarySelect(fLastPos.fX, fLastPos.fY);
00142 fGLViewer->fSecSelRec.SetMultiple(event->fState & kKeyControlMask);
00143
00144 lshp->ProcessSelection(*fGLViewer->fRnrCtx, fGLViewer->fSecSelRec);
00145
00146 switch (fGLViewer->fSecSelRec.GetSecSelResult())
00147 {
00148 case TGLSelectRecord::kEnteringSelection:
00149 fGLViewer->Clicked(obj, event->fCode, event->fState);
00150 break;
00151 case TGLSelectRecord::kLeavingSelection:
00152 fGLViewer->UnClicked(obj, event->fCode, event->fState);
00153 break;
00154 case TGLSelectRecord::kModifyingInternalSelection:
00155 fGLViewer->ReClicked(obj, event->fCode, event->fState);
00156 break;
00157 default:
00158 break;
00159 }
00160 }
00161 else
00162 {
00163 fGLViewer->Clicked(obj);
00164 fGLViewer->Clicked(obj, event->fCode, event->fState);
00165 }
00166 }
00167
00168
00169 void TGLEventHandler::SelectForMouseOver()
00170 {
00171
00172
00173
00174
00175 fGLViewer->RequestSelect(fLastPos.fX, fLastPos.fY);
00176
00177 TGLPhysicalShape *pshp = fGLViewer->fSelRec.GetPhysShape();
00178 TGLLogicalShape *lshp = pshp ? const_cast<TGLLogicalShape*>(pshp->GetLogical()) : 0;
00179 TObject *obj = lshp ? lshp->GetExternal() : 0;
00180
00181 if (lshp && (fSecSelType == TGLViewer::kOnRequest && lshp->AlwaysSecondarySelect()))
00182 {
00183 fGLViewer->RequestSecondarySelect(fLastPos.fX, fLastPos.fY);
00184 fGLViewer->fSecSelRec.SetMultiple(kFALSE);
00185 fGLViewer->fSecSelRec.SetHighlight(kTRUE);
00186
00187 lshp->ProcessSelection(*fGLViewer->fRnrCtx, fGLViewer->fSecSelRec);
00188
00189 fGLViewer->fSecSelRec.SetHighlight(kFALSE);
00190
00191 switch (fGLViewer->fSecSelRec.GetSecSelResult())
00192 {
00193 case TGLSelectRecord::kEnteringSelection:
00194 fGLViewer->MouseOver(obj, fLastEventState);
00195 break;
00196 case TGLSelectRecord::kModifyingInternalSelection:
00197 fGLViewer->ReMouseOver(obj, fLastEventState);
00198 break;
00199 case TGLSelectRecord::kLeavingSelection:
00200 fGLViewer->UnMouseOver(obj, fLastEventState);
00201 break;
00202 default:
00203 break;
00204 }
00205 }
00206 else if (fLastMouseOverShape != pshp)
00207 {
00208 fGLViewer->MouseOver(pshp);
00209 fGLViewer->MouseOver(pshp, fLastEventState);
00210 fGLViewer->MouseOver(obj, fLastEventState);
00211 }
00212 fLastMouseOverShape = pshp;
00213 fLastMouseOverPos = fLastPos;
00214 }
00215
00216
00217
00218
00219 void TGLEventHandler::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00220 {
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 Event_t eventSt;
00244 eventSt.fX = px;
00245 eventSt.fY = py;
00246 eventSt.fState = 0;
00247
00248 if (event != kKeyPress) {
00249 eventSt.fY -= Int_t((1 - gPad->GetHNDC() - gPad->GetYlowNDC()) * gPad->GetWh());
00250 eventSt.fX -= Int_t(gPad->GetXlowNDC() * gPad->GetWw());
00251 }
00252
00253 switch (event) {
00254 case kMouseMotion:
00255 eventSt.fCode = kMouseMotion;
00256 eventSt.fType = kMotionNotify;
00257 HandleMotion(&eventSt);
00258 break;
00259 case kButton1Down:
00260 case kButton1Up:
00261 {
00262 eventSt.fCode = kButton1;
00263 eventSt.fType = event == kButton1Down ? kButtonPress:kButtonRelease;
00264 HandleButton(&eventSt);
00265 }
00266 break;
00267 case kButton2Down:
00268 case kButton2Up:
00269 {
00270 eventSt.fCode = kButton2;
00271 eventSt.fType = event == kButton2Down ? kButtonPress:kButtonRelease;
00272 HandleButton(&eventSt);
00273 }
00274 break;
00275 case kButton3Down:
00276 {
00277 eventSt.fState = kKeyShiftMask;
00278 eventSt.fCode = kButton1;
00279 eventSt.fType = kButtonPress;
00280 HandleButton(&eventSt);
00281 }
00282 break;
00283 case kButton3Up:
00284 {
00285 eventSt.fCode = kButton3;
00286 eventSt.fType = kButtonRelease;
00287 HandleButton(&eventSt);
00288 }
00289 break;
00290 case kButton1Double:
00291 case kButton2Double:
00292 case kButton3Double:
00293 {
00294 eventSt.fCode = kButton1Double ? kButton1 : kButton2Double ? kButton2 : kButton3;
00295 eventSt.fType = kButtonDoubleClick;
00296 HandleDoubleClick(&eventSt);
00297 }
00298 break;
00299 case kButton1Motion:
00300 case kButton2Motion:
00301 case kButton3Motion:
00302 {
00303
00304 eventSt.fCode = event == kButton1Motion ? kButton1 : event == kButton2Motion ? kButton2 : kButton3;
00305 eventSt.fType = kMotionNotify;
00306 HandleMotion(&eventSt);
00307 }
00308 break;
00309 case kKeyPress:
00310 {
00311 eventSt.fType = kGKeyPress;
00312 eventSt.fCode = py;
00313 HandleKey(&eventSt);
00314 }
00315 break;
00316 case 6:
00317 if (fGLViewer->CurrentCamera().Zoom(+50, kFALSE, kFALSE)) {
00318 if (fGLViewer->fGLDevice != -1) {
00319 gGLManager->MarkForDirectCopy(fGLViewer->fGLDevice, kTRUE);
00320 gVirtualX->SetDrawMode(TVirtualX::kCopy);
00321 }
00322 fGLViewer->RequestDraw();
00323 }
00324 break;
00325 case 5:
00326 if (fGLViewer->CurrentCamera().Zoom(-50, kFALSE, kFALSE)) {
00327 if (fGLViewer->fGLDevice != -1) {
00328 gGLManager->MarkForDirectCopy(fGLViewer->fGLDevice, kTRUE);
00329 gVirtualX->SetDrawMode(TVirtualX::kCopy);
00330 }
00331 fGLViewer->RequestDraw();
00332 }
00333 break;
00334 case 7:
00335 eventSt.fState = kKeyShiftMask;
00336 eventSt.fCode = kButton1;
00337 eventSt.fType = kButtonPress;
00338 HandleButton(&eventSt);
00339 break;
00340 default:
00341 {
00342
00343 }
00344 }
00345 }
00346
00347
00348 Bool_t TGLEventHandler::HandleEvent(Event_t *event)
00349 {
00350
00351
00352
00353 if (event->fType == kFocusIn) {
00354 if (fGLViewer->fDragAction != TGLViewer::kDragNone) {
00355 Error("TGLEventHandler::HandleEvent", "active drag-action at focus-in.");
00356 fGLViewer->fDragAction = TGLViewer::kDragNone;
00357 }
00358 StartMouseTimer();
00359 }
00360 if (event->fType == kFocusOut) {
00361 if (fGLViewer->fDragAction != TGLViewer::kDragNone) {
00362 Warning("TGLEventHandler::HandleEvent", "drag-action active at focus-out.");
00363 fGLViewer->fDragAction = TGLViewer::kDragNone;
00364 }
00365 StopMouseTimer();
00366 ClearMouseOver();
00367 }
00368
00369 return kTRUE;
00370 }
00371
00372
00373 Bool_t TGLEventHandler::HandleFocusChange(Event_t *event)
00374 {
00375
00376
00377
00378 fGLViewer->MouseIdle(0, 0, 0);
00379 if (event->fType == kFocusIn) {
00380 if (fGLViewer->fDragAction != TGLViewer::kDragNone) {
00381 Error("TGLEventHandler::HandleFocusChange", "active drag-action at focus-in.");
00382 fGLViewer->fDragAction = TGLViewer::kDragNone;
00383 }
00384 StartMouseTimer();
00385 fGLViewer->Activated();
00386 }
00387 if (event->fType == kFocusOut) {
00388 if (fGLViewer->fDragAction != TGLViewer::kDragNone) {
00389 Warning("TGLEventHandler::HandleFocusChange", "drag-action active at focus-out.");
00390 fGLViewer->fDragAction = TGLViewer::kDragNone;
00391 }
00392 StopMouseTimer();
00393 ClearMouseOver();
00394 }
00395
00396 return kTRUE;
00397 }
00398
00399
00400 Bool_t TGLEventHandler::HandleCrossing(Event_t *event)
00401 {
00402
00403
00404
00405
00406 if (event->fCode != 0) {
00407 return kTRUE;
00408 }
00409
00410 fGLViewer->MouseIdle(0, 0, 0);
00411 if (event->fType == kEnterNotify) {
00412 if (fGLViewer->fDragAction != TGLViewer::kDragNone) {
00413 Error("TGLEventHandler::HandleCrossing", "active drag-action at enter-notify.");
00414 fGLViewer->fDragAction = TGLViewer::kDragNone;
00415 }
00416 StartMouseTimer();
00417
00418 fGLViewer->Activated();
00419 }
00420 if (event->fType == kLeaveNotify) {
00421 if (fGLViewer->fDragAction != TGLViewer::kDragNone) {
00422 Warning("TGLEventHandler::HandleCrossing", "drag-action active at leave-notify.");
00423 fGLViewer->fDragAction = TGLViewer::kDragNone;
00424 }
00425 StopMouseTimer();
00426 ClearMouseOver();
00427 }
00428
00429 return kTRUE;
00430 }
00431
00432
00433 Bool_t TGLEventHandler::HandleButton(Event_t * event)
00434 {
00435
00436
00437 if (fGLViewer->IsLocked()) {
00438 if (gDebug>2) {
00439 Info("TGLEventHandler::HandleButton", "ignored - viewer is %s",
00440 fGLViewer->LockName(fGLViewer->CurrentLock()));
00441 }
00442 return kFALSE;
00443 }
00444
00445
00446 if (event->fCode > kButton3)
00447 {
00448
00449
00450
00451
00452 if (event->fType == kButtonRelease)
00453 {
00454 Bool_t redraw = kFALSE;
00455
00456 Int_t zoom = TMath::Nint(fMouseWheelFactor * ControlValue(50));
00457 switch(event->fCode)
00458 {
00459 case kButton5:
00460 redraw = fGLViewer->CurrentCamera().Zoom(zoom, kFALSE, kFALSE);
00461 break;
00462
00463 case kButton4:
00464 redraw = fGLViewer->CurrentCamera().Zoom(-zoom, kFALSE, kFALSE);
00465 break;
00466
00467 case kButton6:
00468 case kButton7:
00469 break;
00470 }
00471
00472 if (redraw)
00473 fGLViewer->fRedrawTimer->RequestDraw(10, TGLRnrCtx::kLODMed);
00474 }
00475 return kTRUE;
00476 }
00477
00478
00479
00480 if (fActiveButtonID && event->fCode != fActiveButtonID)
00481 {
00482 return kTRUE;
00483 }
00484 else
00485 {
00486 fActiveButtonID = event->fCode;
00487 }
00488
00489
00490
00491 if (event->fType == kButtonPress)
00492 {
00493 GrabMouse();
00494
00495 fGLViewer->MouseIdle(0, 0, 0);
00496
00497 fButtonPushPos.fX = event->fX;
00498 fButtonPushPos.fY = event->fY;
00499
00500 if (fGLViewer->GetPushAction() != TGLViewer::kPushStd)
00501 {
00502 fGLViewer->RequestSelect(event->fX, event->fY);
00503 if (fGLViewer->fSelRec.GetN() > 0)
00504 {
00505 TGLVector3 v(event->fX, event->fY, 0.5*fGLViewer->fSelRec.GetMinZ());
00506 fGLViewer->CurrentCamera().WindowToViewport(v);
00507 v = fGLViewer->CurrentCamera().ViewportToWorld(v);
00508 if (fGLViewer->GetPushAction() == TGLViewer::kPushCamCenter)
00509 {
00510 fGLViewer->CurrentCamera().SetExternalCenter(kTRUE);
00511 fGLViewer->CurrentCamera().SetCenterVec(v.X(), v.Y(), v.Z());
00512 }
00513 else
00514 {
00515 TGLSelectRecord& rec = fGLViewer->GetSelRec();
00516 TObject* obj = rec.GetObject();
00517 TGLRect& vp = fGLViewer->CurrentCamera().RefViewport();
00518 new TGLAnnotation(fGLViewer, obj->GetTitle(),
00519 event->fX * 1.0f/vp.Width(),
00520 1 - event->fY * 1.0f/vp.Height(), v);
00521 }
00522
00523 fGLViewer->RequestDraw();
00524 }
00525 return kTRUE;
00526 }
00527
00528 Bool_t handled = kFALSE;
00529
00530 if (fGLViewer->fDragAction == TGLViewer::kDragNone && fGLViewer->fCurrentOvlElm)
00531 {
00532 if (fGLViewer->fCurrentOvlElm->Handle(*fGLViewer->fRnrCtx, fGLViewer->fOvlSelRec, event))
00533 {
00534 handled = kTRUE;
00535 fGLViewer->fDragAction = TGLViewer::kDragOverlay;
00536 fGLViewer->RequestDraw();
00537 }
00538 }
00539
00540 if ( ! handled)
00541 {
00542 switch(event->fCode)
00543 {
00544
00545 case kButton1:
00546 {
00547 fGLViewer->fDragAction = TGLViewer::kDragCameraRotate;
00548 if (fMouseTimer)
00549 {
00550 fMouseTimer->TurnOff();
00551 fMouseTimer->Reset();
00552 }
00553 break;
00554 }
00555
00556 case kButton2:
00557 {
00558 fGLViewer->fDragAction = TGLViewer::kDragCameraTruck;
00559 break;
00560 }
00561
00562 case kButton3:
00563 {
00564 fGLViewer->fDragAction = TGLViewer::kDragCameraDolly;
00565 break;
00566 }
00567 }
00568 }
00569 }
00570
00571 else if (event->fType == kButtonRelease)
00572 {
00573 fActiveButtonID = 0;
00574
00575 if (fInPointerGrab)
00576 {
00577 UnGrabMouse();
00578 }
00579 else
00580 {
00581 Warning("TGLEventHandler::HandleButton", "Unexpected button-release.");
00582 }
00583
00584 if (fIgnoreButtonUp)
00585 {
00586 fIgnoreButtonUp = kFALSE;
00587 return kTRUE;
00588 }
00589
00590 if (fGLViewer->GetPushAction() != TGLViewer::kPushStd)
00591 {
00592
00593 fGLViewer->fPushAction = TGLViewer::kPushStd;
00594 fGLViewer->RefreshPadEditor(fGLViewer);
00595 return kTRUE;
00596 }
00597 else if (fGLViewer->fDragAction == TGLViewer::kDragOverlay && fGLViewer->fCurrentOvlElm)
00598 {
00599 fGLViewer->fCurrentOvlElm->Handle(*fGLViewer->fRnrCtx, fGLViewer->fOvlSelRec, event);
00600 fGLViewer->OverlayDragFinished();
00601 if (fGLViewer->RequestOverlaySelect(event->fX, event->fY))
00602 fGLViewer->RequestDraw();
00603 }
00604 else if (fGLViewer->fDragAction >= TGLViewer::kDragCameraRotate &&
00605 fGLViewer->fDragAction <= TGLViewer::kDragCameraDolly)
00606 {
00607 fGLViewer->RequestDraw(TGLRnrCtx::kLODHigh);
00608 }
00609
00610 fGLViewer->fDragAction = TGLViewer::kDragNone;
00611
00612 if (fGLViewer->fGLDevice != -1)
00613 {
00614 gGLManager->MarkForDirectCopy(fGLViewer->fGLDevice, kFALSE);
00615 }
00616
00617 if (event->fX == fButtonPushPos.fX && event->fY == fButtonPushPos.fY)
00618 {
00619 if (event->fCode == kButton1)
00620 {
00621 if (event->fState & kKeyShiftMask && fDoInternalSelection)
00622 {
00623 if (fGLViewer->RequestSelect(event->fX, event->fY))
00624 {
00625 fGLViewer->ApplySelection();
00626 }
00627 }
00628 else
00629 {
00630 SelectForClicked(event);
00631 }
00632 }
00633 else if (event->fCode == kButton3)
00634 {
00635 Int_t x, y;
00636 Window_t childdum;
00637 gVirtualX->TranslateCoordinates(fGLViewer->fGLWidget->GetId(), gClient->GetDefaultRoot()->GetId(),
00638 event->fX, event->fY, x, y, childdum);
00639
00640 fGLViewer->RequestSelect(event->fX, event->fY);
00641
00642 PopupContextMenu(fGLViewer->fSelRec.GetPhysShape(), event, x, y);
00643 }
00644 }
00645
00646 if (event->fCode == kButton1 && fMouseTimer)
00647 {
00648 fMouseTimer->TurnOn();
00649 }
00650 }
00651
00652 return kTRUE;
00653 }
00654
00655
00656 Bool_t TGLEventHandler::HandleDoubleClick(Event_t *event)
00657 {
00658
00659
00660 if (fGLViewer->IsLocked()) {
00661 if (gDebug>3) {
00662 Info("TGLEventHandler::HandleDoubleClick", "ignored - viewer is %s",
00663 fGLViewer->LockName(fGLViewer->CurrentLock()));
00664 }
00665 return kFALSE;
00666 }
00667
00668 if (event->fCode > 3)
00669 return kTRUE;
00670
00671 if (fActiveButtonID)
00672 return kTRUE;
00673
00674 fActiveButtonID = event->fCode;
00675 GrabMouse();
00676
00677 fGLViewer->MouseIdle(0, 0, 0);
00678 if (event->fCode == kButton1)
00679 {
00680 fGLViewer->DoubleClicked();
00681 if (fGLViewer->GetSelected() == 0)
00682 fGLViewer->SelectionChanged();
00683 }
00684 return kTRUE;
00685 }
00686
00687
00688 Bool_t TGLEventHandler::HandleConfigureNotify(Event_t *event)
00689 {
00690
00691
00692 if (fGLViewer->IsLocked())
00693 {
00694 if (gDebug > 0) {
00695 Info("TGLEventHandler::HandleConfigureNotify", "ignored - viewer is %s",
00696 fGLViewer->LockName(fGLViewer->CurrentLock()));
00697 }
00698 return kFALSE;
00699 }
00700 if (event)
00701 {
00702 fGLViewer->SetViewport(event->fX, event->fY, event->fWidth, event->fHeight);
00703 fGLViewer->fRedrawTimer->RequestDraw(10, TGLRnrCtx::kLODMed);
00704 }
00705 return kTRUE;
00706 }
00707
00708
00709 Bool_t TGLEventHandler::HandleExpose(Event_t * event)
00710 {
00711
00712
00713 if (event->fCount != 0) return kTRUE;
00714
00715 if (fGLViewer->IsLocked()) {
00716 if (gDebug > 0) {
00717 Info("TGLViewer::HandleExpose", "ignored - viewer is %s",
00718 fGLViewer->LockName(fGLViewer->CurrentLock()));
00719 }
00720 return kFALSE;
00721 }
00722
00723 fGLViewer->fRedrawTimer->RequestDraw(20, TGLRnrCtx::kLODHigh);
00724 return kTRUE;
00725 }
00726
00727
00728 Bool_t TGLEventHandler::HandleKey(Event_t *event)
00729 {
00730
00731
00732
00733 if (event->fType == kKeyRelease)
00734 return kTRUE;
00735
00736 if (fTooltipShown)
00737 fTooltip->Hide();
00738
00739 fLastEventState = event->fState;
00740
00741 fGLViewer->MouseIdle(0, 0, 0);
00742 if (fGLViewer->IsLocked()) {
00743 if (gDebug>3) {
00744 Info("TGLEventHandler::HandleKey", "ignored - viewer is %s",
00745 fGLViewer->LockName(fGLViewer->CurrentLock()));
00746 }
00747 return kFALSE;
00748 }
00749
00750 char tmp[10] = {0};
00751 UInt_t keysym = 0;
00752
00753 if (fGLViewer->fGLDevice == -1)
00754 gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
00755 else
00756 keysym = event->fCode;
00757 fGLViewer->fRnrCtx->SetEventKeySym(keysym);
00758
00759 Bool_t redraw = kFALSE;
00760 if (fGLViewer->fCurrentOvlElm &&
00761 fGLViewer->fCurrentOvlElm->Handle(*fGLViewer->fRnrCtx, fGLViewer->fOvlSelRec, event))
00762 {
00763 redraw = kTRUE;
00764 }
00765 else
00766 {
00767 const Bool_t mod1 = event->fState & kKeyControlMask;
00768 const Bool_t mod2 = event->fState & kKeyShiftMask;
00769
00770 const Int_t shift = TMath::Nint(fArrowKeyFactor * ControlValue(10));
00771
00772 switch (keysym)
00773 {
00774 case kKey_R:
00775 case kKey_r:
00776 fGLViewer->SetStyle(TGLRnrCtx::kFill);
00777 redraw = kTRUE;
00778 break;
00779 case kKey_E:
00780 case kKey_e:
00781 fGLViewer->SwitchColorSet();
00782 redraw = kTRUE;
00783 break;
00784 case kKey_W:
00785 case kKey_w:
00786 fGLViewer->SetStyle(TGLRnrCtx::kWireFrame);
00787 redraw = kTRUE;
00788 break;
00789 case kKey_T:
00790 case kKey_t:
00791 fGLViewer->SetStyle(TGLRnrCtx::kOutline);
00792 redraw = kTRUE;
00793 break;
00794
00795 case kKey_F1:
00796 fGLViewer->RequestSelect(fLastPos.fX, fLastPos.fY);
00797 fGLViewer->MouseIdle(fGLViewer->fSelRec.GetPhysShape(), (UInt_t)fLastPos.fX, (UInt_t)fLastPos.fY);
00798 break;
00799
00800
00801 case kKey_Plus:
00802 case kKey_J:
00803 case kKey_j:
00804 redraw = fGLViewer->CurrentCamera().Dolly(shift, mod1, mod2);
00805 break;
00806 case kKey_Minus:
00807 case kKey_K:
00808 case kKey_k:
00809 redraw = fGLViewer->CurrentCamera().Dolly(-shift, mod1, mod2);
00810 break;
00811 case kKey_Up:
00812 redraw = fGLViewer->CurrentCamera().Truck(0, shift, mod1, mod2);
00813 break;
00814 case kKey_Down:
00815 redraw = fGLViewer->CurrentCamera().Truck(0, -shift, mod1, mod2);
00816 break;
00817 case kKey_Left:
00818 redraw = fGLViewer->CurrentCamera().Truck(-shift, 0, mod1, mod2);
00819 break;
00820 case kKey_Right:
00821 redraw = fGLViewer->CurrentCamera().Truck(shift, 0, mod1, mod2);
00822 break;
00823 case kKey_Home:
00824 if (mod1) {
00825 TGLCamera &cam = fGLViewer->CurrentCamera();
00826 cam.SetExternalCenter(!cam.GetExternalCenter());
00827 fGLViewer->RefreshPadEditor(fGLViewer);
00828 } else {
00829 fGLViewer->ResetCurrentCamera();
00830 }
00831 redraw = kTRUE;
00832 break;
00833
00834
00835 case kKey_d:
00836 fGLViewer->fDebugMode = !fGLViewer->fDebugMode;
00837 redraw = kTRUE;
00838 Info("OpenGL viewer debug mode : ", fGLViewer->fDebugMode ? "ON" : "OFF");
00839 break;
00840
00841 case kKey_D:
00842 if (fGLViewer->fDebugMode) {
00843 Info("OpenGL viewer FORCED rebuild", " ");
00844 fGLViewer->UpdateScene();
00845 }
00846 default:;
00847 }
00848 }
00849
00850 if (redraw) {
00851 if (fGLViewer->fGLDevice != -1)
00852 gGLManager->MarkForDirectCopy(fGLViewer->fGLDevice, kTRUE);
00853 fGLViewer->RequestDraw();
00854 }
00855
00856 return kTRUE;
00857 }
00858
00859
00860 Bool_t TGLEventHandler::HandleMotion(Event_t * event)
00861 {
00862
00863
00864 fGLViewer->MouseIdle(0, 0, 0);
00865 if (fGLViewer->IsLocked()) {
00866 if (gDebug>3) {
00867 Info("TGLEventHandler::HandleMotion", "ignored - viewer is %s",
00868 fGLViewer->LockName(fGLViewer->CurrentLock()));
00869 }
00870 return kFALSE;
00871 }
00872
00873 Bool_t processed = kFALSE, changed = kFALSE;
00874 Short_t lod = TGLRnrCtx::kLODMed;
00875
00876
00877 Int_t xDelta = TMath::Nint(fMouseDragFactor * ControlValue(event->fX - fLastPos.fX));
00878 Int_t yDelta = TMath::Nint(fMouseDragFactor * ControlValue(event->fY - fLastPos.fY));
00879 Bool_t mod1 = event->fState & kKeyControlMask;
00880 Bool_t mod2 = event->fState & kKeyShiftMask;
00881
00882 if (fMouseTimerRunning) StopMouseTimer();
00883
00884 if (fTooltipShown &&
00885 ( TMath::Abs(event->fXRoot - fTooltipPos.fX) > fTooltipPixelTolerance ||
00886 TMath::Abs(event->fYRoot - fTooltipPos.fY) > fTooltipPixelTolerance ))
00887 {
00888 RemoveTooltip();
00889 }
00890
00891 if (fGLViewer->fDragAction == TGLViewer::kDragNone)
00892 {
00893 if (fGLViewer->fRedrawTimer->IsPending()) {
00894 if (gDebug > 2)
00895 Info("TGLEventHandler::HandleMotion", "Redraw pending, ignoring.");
00896 return kTRUE;
00897 }
00898 changed = fGLViewer->RequestOverlaySelect(event->fX, event->fY);
00899 if (fGLViewer->fCurrentOvlElm)
00900 processed = fGLViewer->fCurrentOvlElm->Handle(*fGLViewer->fRnrCtx, fGLViewer->fOvlSelRec, event);
00901 lod = TGLRnrCtx::kLODHigh;
00902 if ( ! processed && ! fMouseTimerRunning)
00903 StartMouseTimer();
00904 }
00905 else if (fGLViewer->fDragAction == TGLViewer::kDragCameraRotate)
00906 {
00907 processed = Rotate(xDelta, yDelta, mod1, mod2);
00908 }
00909 else if (fGLViewer->fDragAction == TGLViewer::kDragCameraTruck)
00910 {
00911 processed = fGLViewer->CurrentCamera().Truck(xDelta, -yDelta, mod1, mod2);
00912 }
00913 else if (fGLViewer->fDragAction == TGLViewer::kDragCameraDolly)
00914 {
00915 processed = fGLViewer->CurrentCamera().Dolly(yDelta - xDelta, mod1, mod2);
00916 }
00917 else if (fGLViewer->fDragAction == TGLViewer::kDragOverlay)
00918 {
00919 if (fGLViewer->fCurrentOvlElm)
00920 processed = fGLViewer->fCurrentOvlElm->Handle(*fGLViewer->fRnrCtx, fGLViewer->fOvlSelRec, event);
00921 }
00922
00923 fLastPos.fX = event->fX;
00924 fLastPos.fY = event->fY;
00925
00926 fLastGlobalPos.fX = event->fXRoot;
00927 fLastGlobalPos.fY = event->fYRoot;
00928
00929 if (processed || changed) {
00930 if (fGLViewer->fGLDevice != -1) {
00931 gGLManager->MarkForDirectCopy(fGLViewer->fGLDevice, kTRUE);
00932 gVirtualX->SetDrawMode(TVirtualX::kCopy);
00933 }
00934
00935 fGLViewer->RequestDraw(lod);
00936 }
00937
00938 return processed;
00939 }
00940
00941
00942 Bool_t TGLEventHandler::Rotate(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2)
00943 {
00944
00945
00946 return fGLViewer->CurrentCamera().Rotate(xDelta, -yDelta, mod1, mod2);
00947 }
00948
00949
00950 Bool_t TGLEventHandler::HandleTimer(TTimer *t)
00951 {
00952
00953
00954 if (t != fMouseTimer) return kFALSE;
00955
00956 fMouseTimerRunning = kFALSE;
00957
00958 if (fGLViewer->fRedrawTimer->IsPending()) {
00959 if (gDebug > 2)
00960 Info("TGLEventHandler::HandleTimer", "Redraw pending, ignoring.");
00961 return kTRUE;
00962 }
00963
00964 if (fGLViewer->fDragAction == TGLViewer::kDragNone)
00965 {
00966 if (fLastMouseOverPos != fLastPos)
00967 {
00968 SelectForMouseOver();
00969 }
00970 }
00971 return kTRUE;
00972 }
00973
00974
00975 void TGLEventHandler::StartMouseTimer()
00976 {
00977
00978
00979 fMouseTimer->Start(-1, kTRUE);
00980 fMouseTimerRunning = kTRUE;
00981 }
00982
00983
00984 void TGLEventHandler::StopMouseTimer()
00985 {
00986
00987
00988 fMouseTimerRunning = kFALSE;
00989 fMouseTimer->Stop();
00990 }
00991
00992
00993 void TGLEventHandler::ClearMouseOver()
00994 {
00995
00996
00997
00998 fLastMouseOverPos.fX = fLastMouseOverPos.fY = -1;
00999 fLastMouseOverShape = 0;
01000 fGLViewer->MouseOver(fLastMouseOverShape);
01001 fGLViewer->MouseOver(fLastMouseOverShape, fLastEventState);
01002 fGLViewer->MouseOver((TObject*)0, fLastEventState);
01003
01004 fGLViewer->ClearCurrentOvlElm();
01005 }
01006
01007
01008 void TGLEventHandler::Repaint()
01009 {
01010
01011
01012 if (fGLViewer->IsLocked()) {
01013 if (gDebug > 0) {
01014 Info("TGLViewer::HandleExpose", "ignored - viewer is %s",
01015 fGLViewer->LockName(fGLViewer->CurrentLock()));
01016 }
01017 return;
01018 }
01019 fGLViewer->fRedrawTimer->RequestDraw(20, TGLRnrCtx::kLODHigh);
01020 }
01021
01022
01023 void TGLEventHandler::PopupContextMenu(TGLPhysicalShape* pshp, Event_t * ,
01024 Int_t gx, Int_t gy)
01025 {
01026
01027
01028 if (!fGLViewer->fContextMenu)
01029 {
01030 fGLViewer->fContextMenu = new TContextMenu("glcm", "GL Viewer Context Menu");
01031 }
01032
01033 if (pshp)
01034 {
01035 fActiveButtonID = 0;
01036 UnGrabMouse();
01037
01038 pshp->InvokeContextMenu(*fGLViewer->fContextMenu, gx, gy);
01039 }
01040
01041
01042
01043
01044
01045
01046
01047 }
01048
01049
01050 void TGLEventHandler::TriggerTooltip(const char* text)
01051 {
01052
01053
01054 static UInt_t screenW = 0, screenH = 0;
01055 fTooltipPos = fLastGlobalPos;
01056 fTooltipShown = kTRUE;
01057 fTooltip->SetText(text);
01058 Int_t x = fTooltipPos.fX + 16, y = fTooltipPos.fY + 16;
01059 if (screenW == 0 || screenH == 0) {
01060 screenW = gClient->GetDisplayWidth();
01061 screenH = gClient->GetDisplayHeight();
01062 }
01063 if (x + 5 + fTooltip->GetWidth() > screenW) {
01064 x = screenW - fTooltip->GetWidth() - 5;
01065 if (y + 5 + fTooltip->GetHeight() > screenH) {
01066 y -= (25 + fTooltip->GetHeight());
01067 }
01068 }
01069 if (y + 5 + fTooltip->GetHeight() > screenH) {
01070 y = screenH - fTooltip->GetHeight() - 10;
01071 }
01072 fTooltip->SetPosition(x, y);
01073 fTooltip->Reset();
01074 }
01075
01076
01077 void TGLEventHandler::RemoveTooltip()
01078 {
01079
01080
01081 fTooltip->Hide();
01082 fTooltipShown = kFALSE;
01083 }
01084
01085
01086 void TGLEventHandler::SetMouseOverSelectDelay(Int_t ms)
01087 {
01088
01089
01090 fMouseTimer->SetTime(ms);
01091 }
01092
01093
01094 void TGLEventHandler::SetMouseOverTooltipDelay(Int_t ms)
01095 {
01096
01097
01098 fTooltip->SetDelay(ms);
01099 }