Salome HOME
3f9aff180167796581f6a0435bc9411d68b66f5b
[modules/hydro.git] / src / HYDROCurveCreator / OCCViewer_ViewWidget.cxx
1 // File:        OCCViewer_ViewWidget.h
2 // Created:     26 Jul 2012
3 // Author:      Natalia ERMOLAEVA
4 // Copyright:   CEA 2011
5
6 //#include <MCGUIBase_Defs.h>
7 #include "OCCViewer_ViewWidget.h"
8
9 #include <Basics_OCCTVersion.hxx>
10
11 #include <SUIT_Desktop.h>
12 #include <SUIT_Session.h>
13 #include <SUIT_ResourceMgr.h>
14 #include <SUIT_MessageBox.h>
15 #include <OCCViewer_ViewPort3d.h>
16 #include <OCCViewer_VService.h>
17 #include <SUIT_ViewModel.h>
18 #include <SUIT_Tools.h>
19
20 #include <QtxAction.h>
21
22 #include <AIS_InteractiveObject.hxx>
23 #include <AIS_ListOfInteractive.hxx>
24 #include <V3d_Viewer.hxx>
25 #include <AIS_Shape.hxx>
26 #include <Prs3d_LineAspect.hxx>
27
28 #include <AIS_InteractiveContext.hxx>
29 #include <AIS_ListIteratorOfListOfInteractive.hxx>
30 #include <Geom_Axis2Placement.hxx>
31 #include <AIS_Drawer.hxx>
32 #include <Prs3d_DatumAspect.hxx>
33
34 #include <QLayout>
35 #include <QCursor>
36 #include <QHBoxLayout>
37 #include <QPushButton>
38 #include <QPainter>
39 #include <QLabel>
40 #include <QWheelEvent>
41 #include <QMouseEvent>
42 #include <QToolBar>
43
44 const int SPACING_SIZE = 5;
45 const int Z_FIT_ALL_SIZE = 1000;
46
47 const char* imageZoomCursor[] = { 
48 "32 32 3 1",
49 ". c None",
50 "a c #000000",
51 "# c #ffffff",
52 "................................",
53 "................................",
54 ".#######........................",
55 "..aaaaaaa.......................",
56 "................................",
57 ".............#####..............",
58 "...........##.aaaa##............",
59 "..........#.aa.....a#...........",
60 ".........#.a.........#..........",
61 ".........#a..........#a.........",
62 "........#.a...........#.........",
63 "........#a............#a........",
64 "........#a............#a........",
65 "........#a............#a........",
66 "........#a............#a........",
67 ".........#...........#.a........",
68 ".........#a..........#a.........",
69 ".........##.........#.a.........",
70 "........#####.....##.a..........",
71 ".......###aaa#####.aa...........",
72 "......###aa...aaaaa.......#.....",
73 ".....###aa................#a....",
74 "....###aa.................#a....",
75 "...###aa...............#######..",
76 "....#aa.................aa#aaaa.",
77 ".....a....................#a....",
78 "..........................#a....",
79 "...........................a....",
80 "................................",
81 "................................",
82 "................................",
83 "................................"};
84
85 const char* imageRotateCursor[] = { 
86 "32 32 3 1",
87 ". c None",
88 "a c #000000",
89 "# c #ffffff",
90 "................................",
91 "................................",
92 "................................",
93 "................................",
94 "........#.......................",
95 ".......#.a......................",
96 "......#######...................",
97 ".......#aaaaa#####..............",
98 "........#..##.a#aa##........##..",
99 ".........a#.aa..#..a#.....##.aa.",
100 ".........#.a.....#...#..##.aa...",
101 ".........#a.......#..###.aa.....",
102 "........#.a.......#a..#aa.......",
103 "........#a.........#..#a........",
104 "........#a.........#a.#a........",
105 "........#a.........#a.#a........",
106 "........#a.........#a.#a........",
107 ".........#.........#a#.a........",
108 "........##a........#a#a.........",
109 "......##.a#.......#.#.a.........",
110 "....##.aa..##.....##.a..........",
111 "..##.aa.....a#####.aa...........",
112 "...aa.........aaa#a.............",
113 "................#.a.............",
114 "...............#.a..............",
115 "..............#.a...............",
116 "...............a................",
117 "................................",
118 "................................",
119 "................................",
120 "................................",
121 "................................"};
122
123 const char* imageCrossCursor[] = { 
124   "32 32 3 1",
125   ". c None",
126   "a c #000000",
127   "# c #ffffff",
128   "................................",
129   "................................",
130   "................................",
131   "................................",
132   "................................",
133   "................................",
134   "................................",
135   "...............#................",
136   "...............#a...............",
137   "...............#a...............",
138   "...............#a...............",
139   "...............#a...............",
140   "...............#a...............",
141   "...............#a...............",
142   "...............#a...............",
143   ".......#################........",
144   "........aaaaaaa#aaaaaaaaa.......",
145   "...............#a...............",
146   "...............#a...............",
147   "...............#a...............",
148   "...............#a...............",
149   "...............#a...............",
150   "...............#a...............",
151   "...............#a...............",
152   "................a...............",
153   "................................",
154   "................................",
155   "................................",
156   "................................",
157   "................................",
158   "................................",
159   "................................"};
160
161 // ---------------- OCC view widget --------
162 OCCViewer_ViewWidget::OCCViewer_ViewWidget(QWidget* parent)
163   : QFrame(parent), myShowTrihedron(true)
164 {
165   setObjectName("OCC_view_widget");
166   mySelectedPoint = gp_Pnt(0.,0.,0.);
167   setFrameStyle(QFrame::NoFrame);
168
169   QGridLayout* anAnalLay = new QGridLayout(this);
170   anAnalLay->setMargin(0);
171   anAnalLay->setSpacing(SPACING_SIZE);
172
173   QWidget* aBtnBox = new QWidget(this);
174   QHBoxLayout* aBtnLay = new QHBoxLayout(aBtnBox);
175   aBtnLay->setMargin(0);
176   aBtnLay->setSpacing(SPACING_SIZE);
177
178   myToolBar = new QToolBar(aBtnBox);
179   aBtnLay->addWidget(myToolBar);
180   myZoomBtns = new QtxMultiAction(aBtnBox);
181   myZoomBtns->setObjectName("zoomBtn");
182   myToolBar->addAction(myZoomBtns);
183   myPanBtns = new QtxMultiAction(aBtnBox);
184   myPanBtns->setObjectName("panBtn");
185   myToolBar->addAction(myPanBtns);
186   myProjBtns = new QtxMultiAction(aBtnBox);
187   myProjBtns->setObjectName("projectionBtn");
188   myToolBar->addAction(myProjBtns);
189
190   // Rotation
191   aBtnLay->addStretch(1);
192   anAnalLay->addWidget(aBtnBox, 0, 0, 1, 2);
193
194   myV3dViewer = OCCViewer_VService::CreateViewer((short*) "Viewer3d", "", "", 1000., V3d_XposYnegZpos, true, true);
195   myV3dViewer->Init();
196
197 #if OCC_VERSION_LARGE <= 0x06060000 // Porting to OCCT higher 6.6.0 version
198   myV3dCollector = OCCViewer_VService::CreateViewer((short*) "Collector3d", "", "", 1000., V3d_XposYnegZpos, true, true);
199   myV3dCollector->Init();
200 #endif
201
202   // init selector
203 #if OCC_VERSION_LARGE <= 0x06060000 
204   myAISContext = new AIS_InteractiveContext( myV3dViewer, myV3dCollector );
205 #else
206   myAISContext = new AIS_InteractiveContext( myV3dViewer );
207 #endif
208   myAISContext->SelectionColor(Quantity_NOC_WHITE);
209   myAISContext->IsoOnPlane(true);
210
211   myViewPort = new OCCViewer_ViewPort3d(this, myV3dViewer, V3d_ORTHOGRAPHIC);
212   myViewPort->setBackgroundColor(Qt::black);
213   myViewPort->setMinimumHeight(300);
214   myViewPort->installEventFilter(this);
215   anAnalLay->addWidget(myViewPort, 1, 0, 1, 2);
216
217   Handle(Geom_Axis2Placement) anAxis = new Geom_Axis2Placement(gp::XOY());
218   myTrihedron = new AIS_Trihedron(anAxis);
219   myTrihedron->SetInfiniteState(Standard_True);
220
221   Quantity_Color Col(193/255., 205/255., 193/255., Quantity_TOC_RGB);
222   myTrihedron->SetArrowColor(Col.Name());
223   myTrihedron->SetSize(100);
224   Handle(AIS_Drawer) drawer = myTrihedron->Attributes();
225   if (drawer->HasDatumAspect()) {
226       Handle(Prs3d_DatumAspect) daspect = drawer->DatumAspect();
227       daspect->FirstAxisAspect()->SetColor(Quantity_Color(1.0, 0.0, 0.0, Quantity_TOC_RGB));
228       daspect->SecondAxisAspect()->SetColor(Quantity_Color(0.0, 1.0, 0.0, Quantity_TOC_RGB));
229       daspect->ThirdAxisAspect()->SetColor(Quantity_Color(0.0, 0.0, 1.0, Quantity_TOC_RGB));
230   }
231   myAISContext->Display(myTrihedron);
232   myAISContext->Deactivate(myTrihedron);
233   
234   myTrihedron->SetTransformPersistence(Graphic3d_TMF_TriedronPers, gp_Pnt(-1, -1, 200));
235   myTrihedron->SetSize(100);
236
237   createActions();
238   myButsMap[TrihId]->setChecked(false);
239   onTrihChanged();
240 }
241
242 OCCViewer_ViewWidget::~OCCViewer_ViewWidget()
243 {
244   #if OCC_VERSION_LARGE <= 0x06060000
245     myV3dCollector.Nullify();
246   #endif
247 }
248
249 void OCCViewer_ViewWidget::reset()
250 {
251   clearViewer();
252   myOperation = NOTHING;
253   myCurrPointType = OCCViewer_ViewWindow::GRAVITY;
254 }
255
256 void OCCViewer_ViewWidget::Display(const TopoDS_Shape shape, const bool theShaded,
257                                    const QColor& shapeColor)
258 {
259   clearViewer(false);
260   if (shape.IsNull()) {
261     myAISContext->UpdateCurrentViewer();
262     return;
263   }
264
265   Handle(AIS_InteractiveObject) io = new AIS_Shape(shape);
266   io->UnsetSelectionMode();
267   io->UnsetHilightMode();
268
269   Quantity_Color aColor(shapeColor.red()/255., shapeColor.green()/255.,
270                         shapeColor.blue()/255., Quantity_TOC_RGB);
271   io->SetColor(aColor);
272
273   myAISContext->Display(io, false);
274   if (theShaded) {
275     myAISContext->SetDisplayMode(io, AIS_Shaded, false);
276     myAISContext->SetMaterial(io, Graphic3d_NOM_PLASTIC, false);
277   }
278   else
279     myAISContext->SetDisplayMode(io, AIS_WireFrame, false);
280   viewerFitAll(false);
281   myAISContext->UpdateCurrentViewer();
282 }
283
284 void OCCViewer_ViewWidget::createActions()
285 {
286   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
287   QtxAction* aAction;
288
289   // FitAll
290   aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_FITALL")),
291                            tr("MNU_FITALL"), 0, this);
292   aAction->setStatusTip(tr("DSC_FITALL"));
293   connect(aAction, SIGNAL(activated()), this, SLOT(onActivated()));
294   myButsMap[ FitAllId ] = aAction;
295
296   // FitRect
297   aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_FITAREA")),
298                            tr("MNU_FITRECT"), 0, this);
299   aAction->setStatusTip(tr("DSC_FITRECT"));
300   connect(aAction, SIGNAL(activated()), this, SLOT(onActivated()));
301   myButsMap[ FitRectId ] = aAction;
302
303   // Zoom
304   aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_ZOOM")),
305                            tr("MNU_ZOOM_VIEW"), 0, this);
306   aAction->setStatusTip(tr("DSC_ZOOM_VIEW"));
307   connect(aAction, SIGNAL(activated()), this, SLOT(onActivated()));
308   myButsMap[ ZoomId ] = aAction;
309
310   // Panning
311   aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_PAN")),
312                            tr("MNU_PAN_VIEW"), 0, this);
313   aAction->setStatusTip(tr("DSC_PAN_VIEW"));
314   connect(aAction, SIGNAL(activated()), this, SLOT(onActivated()));
315   myButsMap[ PanId ] = aAction;
316
317   // Global Panning
318   aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_GLOBALPAN")),
319                            tr("MNU_GLOBALPAN_VIEW"), 0, this);
320   aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW"));
321   connect(aAction, SIGNAL(activated()), this, SLOT(onActivated()));
322   myButsMap[ GlobalPanId ] = aAction;
323
324   // Projections
325   aAction = new QtxAction(tr("MNU_FRONT_VIEW"), aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_FRONT")),
326                            tr("MNU_FRONT_VIEW"), 0, this);
327   aAction->setStatusTip(tr("DSC_FRONT_VIEW"));
328   connect(aAction, SIGNAL(activated()), this, SLOT(onFrontView()));
329   myButsMap[ FrontId ] = aAction;
330
331   aAction = new QtxAction(tr("MNU_BACK_VIEW"), aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_BACK")),
332                            tr("MNU_BACK_VIEW"), 0, this);
333   aAction->setStatusTip(tr("DSC_BACK_VIEW"));
334   connect(aAction, SIGNAL(activated()), this, SLOT(onBackView()));
335   myButsMap[ BackId ] = aAction;
336
337   aAction = new QtxAction(tr("MNU_TOP_VIEW"), aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_TOP")),
338                            tr("MNU_TOP_VIEW"), 0, this);
339   aAction->setStatusTip(tr("DSC_TOP_VIEW"));
340   connect(aAction, SIGNAL(activated()), this, SLOT(onTopView()));
341   myButsMap[ TopId ] = aAction;
342
343   aAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_BOTTOM")),
344                            tr("MNU_BOTTOM_VIEW"), 0, this);
345   aAction->setStatusTip(tr("DSC_BOTTOM_VIEW"));
346   connect(aAction, SIGNAL(activated()), this, SLOT(onBottomView()));
347   myButsMap[ BottomId ] = aAction;
348
349   aAction = new QtxAction(tr("MNU_LEFT_VIEW"), aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_LEFT")),
350                            tr("MNU_LEFT_VIEW"), 0, this);
351   aAction->setStatusTip(tr("DSC_LEFT_VIEW"));
352   connect(aAction, SIGNAL(activated()), this, SLOT(onLeftView()));
353   myButsMap[ LeftId ] = aAction;
354
355   aAction = new QtxAction(tr("MNU_RIGHT_VIEW"), aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_RIGHT")),
356                            tr("MNU_RIGHT_VIEW"), 0, this);
357   aAction->setStatusTip(tr("DSC_RIGHT_VIEW"));
358   connect(aAction, SIGNAL(activated()), this, SLOT(onRightView()));
359   myButsMap[ RightId ] = aAction;
360
361   aAction = new QtxAction(tr("MNU_ROTATE_VIEW"), aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_ROTATE")),
362                           tr("MNU_ROTATE_VIEW"), 0, this);
363   aAction->setStatusTip(tr("DSC_ROTATE_VIEW"));
364   connect(aAction, SIGNAL(triggered()), this, SLOT(onActivated()));
365   myToolBar->addAction(aAction);
366   myButsMap[ RotationId ] = aAction;
367
368   aAction = new QtxAction(tr("MNU_SHOW_TRIHEDRE"), aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_TRIHEDRON")),
369                           tr("MNU_SHOW_TRIHEDRE"), 0, this);
370   aAction->setStatusTip(tr("DSC_SHOW_TRIHEDRE"));
371   aAction->setCheckable(true);
372   connect(aAction, SIGNAL(triggered()), this, SLOT(onTrihChanged()));
373   myToolBar->addAction(aAction);
374   myButsMap[ TrihId ] = aAction;
375
376   myZoomBtns->insertAction(myButsMap[ FitAllId ]);
377   myZoomBtns->insertAction(myButsMap[ FitRectId ]);
378   myZoomBtns->insertAction(myButsMap[ ZoomId ]);
379
380   myPanBtns->insertAction(myButsMap[ PanId ]);
381   myPanBtns->insertAction(myButsMap[ GlobalPanId ]);
382
383   myProjBtns->insertAction(myButsMap[ FrontId ]);
384   myProjBtns->insertAction(myButsMap[ BackId ]);
385   myProjBtns->insertAction(myButsMap[ TopId ]);
386   myProjBtns->insertAction(myButsMap[ BottomId ]);
387   myProjBtns->insertAction(myButsMap[ LeftId ]);
388   myProjBtns->insertAction(myButsMap[ RightId ]);
389 }
390
391 /*!
392   Custom event handler
393 */
394 bool OCCViewer_ViewWidget::eventFilter(QObject* watched, QEvent* e)
395 {
396   if (e->type() == QEvent::ContextMenu)
397     return true;
398
399   bool aRes = false;
400   int aReturn = -1;
401   if (watched == myViewPort) {
402     int aType = e->type();
403     switch(aType) {
404     case QEvent::MouseButtonPress:
405       vpMousePressEvent((QMouseEvent*) e);
406       aRes = true;
407       aReturn = 1;
408       break;
409     case QEvent::MouseButtonRelease:
410       vpMouseReleaseEvent((QMouseEvent*) e);
411       aRes = true;
412       aReturn = 1;
413       break;
414     case QEvent::MouseMove:
415       vpMouseMoveEvent((QMouseEvent*) e);
416       aRes = true;
417       aReturn = 1;
418       break;
419     case QEvent::Wheel:
420       {
421         QWheelEvent* aEvent = (QWheelEvent*) e;
422         double aDelta = aEvent->delta();
423         double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.; 
424         myViewPort->getView()->SetZoom(aScale);
425       }
426       aRes = true;
427       aReturn = 1;
428       break;
429     default:
430       break;
431     }
432   }
433   if (aReturn == -1)
434     aRes = QFrame::eventFilter(watched, e);
435
436   if (watched == myViewPort && !myViewPort->getView().IsNull()) {
437     if (e->type() == QEvent::MouseButtonRelease)
438       viewZFitAll();
439   }
440
441   return aRes;
442 }
443
444 void OCCViewer_ViewWidget::onActivated()
445 {
446   if(!sender() || !sender()->inherits("QtxAction"))
447     return;
448   QtxAction* anAction = (QtxAction*)sender();
449   ActionsMap::const_iterator anIt = myButsMap.begin(), last = myButsMap.end();
450   int aCurAction = -1;
451   for (; anIt != last && aCurAction == -1; anIt++) {
452     if (anIt.value() != anAction)
453       continue;
454     aCurAction = anIt.key();
455   }
456   switch(aCurAction) {
457     case RotationId:  activateRotation(); return;
458     case FitAllId:    viewerFitAll();  break;
459     case FitRectId:   activateWindowFit();   break;
460     case ZoomId:      activateZoom();        break;
461     case PanId:       activatePanning();     break;
462     case GlobalPanId: activateGlPanning();   break;
463   }
464   viewZFitAll();
465 }
466
467 void OCCViewer_ViewWidget::viewerFitAll(const bool theUpdate)
468 {
469   myViewPort->fitAll(false, true, theUpdate);
470   viewZFitAll();
471 }
472
473 void OCCViewer_ViewWidget::onTrihChanged()
474 {
475   QtxAction* anAction = myButsMap[TrihId];
476   myShowTrihedron = anAction->isChecked();
477   if (myShowTrihedron) {
478     myAISContext->Display(myTrihedron);
479     myAISContext->Deactivate(myTrihedron);
480   }
481   else 
482     myAISContext->Erase(myTrihedron);
483 }
484 /*!
485   Processes transformation "front view"
486 */
487 void OCCViewer_ViewWidget::onFrontView()
488 {
489   Handle(V3d_View) aView3d = myViewPort->getView();
490   if (!aView3d.IsNull()) aView3d->SetProj (V3d_Xpos);
491   viewerFitAll();
492 }
493
494 /*!
495   Processes transformation "back view"
496 */
497 void OCCViewer_ViewWidget::onBackView()
498 {
499   Handle(V3d_View) aView3d = myViewPort->getView();
500   if (!aView3d.IsNull()) aView3d->SetProj (V3d_Xneg);
501   viewerFitAll();
502 }
503
504 /*!
505   Processes transformation "top view"
506 */
507 void OCCViewer_ViewWidget::onTopView()
508 {
509   Handle(V3d_View) aView3d = myViewPort->getView();
510   if (!aView3d.IsNull()) aView3d->SetProj (V3d_Zpos);
511   viewerFitAll();
512 }
513
514 /*!
515   Processes transformation "bottom view"
516 */
517 void OCCViewer_ViewWidget::onBottomView()
518 {
519   Handle(V3d_View) aView3d = myViewPort->getView();
520   if (!aView3d.IsNull()) aView3d->SetProj (V3d_Zneg);
521   viewerFitAll();
522 }
523
524 /*!
525   Processes transformation "left view"
526 */
527 void OCCViewer_ViewWidget::onLeftView()
528 {
529   Handle(V3d_View) aView3d = myViewPort->getView();
530   if (!aView3d.IsNull()) aView3d->SetProj (V3d_Yneg);
531   viewerFitAll();
532 }
533
534 /*!
535   Processes transformation "right view"
536 */
537 void OCCViewer_ViewWidget::onRightView()
538 {
539   Handle(V3d_View) aView3d = myViewPort->getView();
540   if (!aView3d.IsNull()) aView3d->SetProj (V3d_Ypos);
541   viewerFitAll();
542 }
543
544
545 void OCCViewer_ViewWidget::viewZFitAll()
546 {
547    myViewPort->getView()->ZFitAll(Z_FIT_ALL_SIZE);
548 }
549
550 void OCCViewer_ViewWidget::activateZoom()
551 {
552   if (!transformRequested() && !myCursorIsHand)
553     myCursor = cursor();          /* save old cursor */
554   
555   if (myOperation != ZOOMVIEW) {
556     QPixmap zoomPixmap (imageZoomCursor);
557     QCursor zoomCursor (zoomPixmap);
558     if(setTransformRequested (ZOOMVIEW))
559       setCursor(zoomCursor);
560   }
561 }
562
563 void OCCViewer_ViewWidget::activateWindowFit()
564 {
565   if (!transformRequested() && !myCursorIsHand)
566     myCursor = cursor();          /* save old cursor */
567
568   if (myOperation != WINDOWFIT) {
569     QCursor handCursor (Qt::PointingHandCursor);
570     if(setTransformRequested (WINDOWFIT))
571       setCursor (handCursor);
572     myCursorIsHand = true;
573   }
574 }
575
576 void OCCViewer_ViewWidget::activateRotation()
577 {
578   if (!transformRequested() && !myCursorIsHand)
579     myCursor = cursor();        // save old cursor 
580   
581   if (myOperation != ROTATE) {
582     QPixmap rotatePixmap (imageRotateCursor);
583     QCursor rotCursor (rotatePixmap);
584     if(setTransformRequested (ROTATE))
585       setCursor(rotCursor);
586   }
587 }
588
589 void OCCViewer_ViewWidget::activatePanning()
590 {
591   if (!transformRequested() && !myCursorIsHand)
592     myCursor = cursor();        // save old cursor 
593   
594   if (myOperation != PANVIEW) {
595     QCursor panCursor (Qt::SizeAllCursor);
596     if(setTransformRequested (PANVIEW))
597       setCursor(panCursor);
598   }
599 }
600
601 void OCCViewer_ViewWidget::activateGlPanning()
602 {
603   Handle(V3d_View) aView3d = myViewPort->getView();
604   if (!aView3d.IsNull()) {
605     QPixmap globalPanPixmap (imageCrossCursor);
606     QCursor glPanCursor (globalPanPixmap);
607     myCurScale = aView3d->Scale();
608     aView3d->FitAll(0.01, false);
609     myCursor = cursor();        // save old cursor 
610     myViewPort->fitAll(); // fits view before selecting a new scene center 
611     if(setTransformRequested(PANGLOBAL))
612       setCursor(glPanCursor);
613   }
614 }
615
616 void OCCViewer_ViewWidget::vpMousePressEvent(QMouseEvent* theEvent)
617 {
618   myStartX = theEvent->x();
619   myStartY = theEvent->y();
620   switch (myOperation) {
621     case WINDOWFIT:
622     case PANGLOBAL:
623     case ZOOMVIEW:
624     case PANVIEW:
625     break;
626     case ROTATE:
627     if (theEvent->button() == Qt::LeftButton) {
628             myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
629           }
630     break;
631     default:
632   /*  Try to activate a transformation */
633     switch (getButtonState(theEvent)) {
634       case ZOOMVIEW:
635         activateZoom();
636         break;
637       case PANVIEW:
638         activatePanning();
639         break;
640       case ROTATE:
641         activateRotation();
642         //myViewPort->startRotation(myStartX, myStartY);//, 0, mySelectedPoint);
643         break;
644       default:
645         break;
646     }
647   }
648 }
649 OCCViewer_ViewWidget::OperationType OCCViewer_ViewWidget::getButtonState(QMouseEvent* theEvent)
650 {
651   OperationType aOp = NOTHING;
652   if((theEvent->modifiers() == SUIT_ViewModel::myStateMap[SUIT_ViewModel::STANDARD][SUIT_ViewModel::ZOOM]) &&
653       (theEvent->button() == SUIT_ViewModel::myButtonMap[SUIT_ViewModel::STANDARD][SUIT_ViewModel::ZOOM]))
654     aOp = ZOOMVIEW;
655   else if((theEvent->modifiers() == SUIT_ViewModel::myStateMap[SUIT_ViewModel::STANDARD][SUIT_ViewModel::PAN]) && 
656            (theEvent->button() == SUIT_ViewModel::myButtonMap[SUIT_ViewModel::STANDARD][SUIT_ViewModel::PAN]))
657     aOp = PANVIEW;
658   else if((theEvent->modifiers()  == SUIT_ViewModel::myStateMap[SUIT_ViewModel::STANDARD][SUIT_ViewModel::ROTATE]) &&
659            (theEvent->button() == SUIT_ViewModel::myButtonMap[SUIT_ViewModel::STANDARD][SUIT_ViewModel::ROTATE]))
660     aOp = ROTATE;
661
662   return aOp;
663 }
664
665 void OCCViewer_ViewWidget::vpMouseReleaseEvent(QMouseEvent* theEvent)
666 {
667   switch (myOperation) {
668   case NOTHING:
669     break;
670   case ROTATE:
671     myViewPort->endRotation();
672     resetState();
673     break;
674   case PANVIEW:
675   case ZOOMVIEW:
676     resetState();
677     break;
678     
679   case PANGLOBAL:
680     if (theEvent->button() == Qt::LeftButton) {
681       myViewPort->setCenter(theEvent->x(), theEvent->y());
682       myViewPort->getView()->SetScale(myCurScale);
683       resetState();
684     }
685     break;
686       
687   case WINDOWFIT:
688     if (theEvent->modifiers() == Qt::LeftButton) {
689       myCurrX = theEvent->x();
690       myCurrY = theEvent->y();
691       QRect rect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
692       if (!rect.isEmpty()) myViewPort->fitRect(rect);
693         resetState();
694     }
695     break;
696   }
697   
698   // NOTE: viewer 3D detects a rectangle of selection using this event
699   // so we must emit it BEFORE resetting the selection rectangle
700
701   if (theEvent->button() == Qt::LeftButton && myDrawRect) {
702     myDrawRect = false;
703     drawRect();
704     resetState(); 
705     myViewPort->update();
706   }
707 }
708
709 void OCCViewer_ViewWidget::vpMouseMoveEvent(QMouseEvent* theEvent)
710 {
711   myCurrX = theEvent->x();
712   myCurrY = theEvent->y();
713   switch (myOperation) {
714   case ROTATE:
715     myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint);
716     break;
717   case ZOOMVIEW:
718     myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY);
719     myStartX = myCurrX;
720     myStartY = myCurrY;
721     break;
722     
723   case PANVIEW:
724     myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY);
725     myStartX = myCurrX;
726     myStartY = myCurrY;
727     break;
728     
729   case PANGLOBAL:
730     break;
731
732   default: {
733     int aState = theEvent->modifiers();
734     if (aState == Qt::LeftButton ||
735       aState == ((int) Qt::LeftButton | (int) Qt::ShiftModifier)) {
736         myDrawRect = true;
737         if (myDrawRect) {
738           drawRect();
739           if (!myCursorIsHand) {   // we are going to sketch a rectangle
740             QCursor handCursor (Qt::PointingHandCursor);
741             myCursorIsHand = true;
742             myCursor = cursor();
743             setCursor(handCursor);
744           }
745         }
746       }
747     }
748   }
749 }
750
751 /*!
752   Sets the viewport to its initial state
753   (no transformations in process etc.)
754 */
755 void OCCViewer_ViewWidget::resetState()
756 {
757   myDrawRect = false;
758   myRect.setLeft(2);
759   myRect.setRight(0);
760
761   /* make rectangle empty (left > right) */
762   if (transformRequested() || myCursorIsHand)
763     setCursor(myCursor);
764   myCursorIsHand = false;
765
766   setTransformRequested(NOTHING);
767 }
768
769 void OCCViewer_ViewWidget::drawRect()
770 {
771   QPainter aPainter(myViewPort);
772   aPainter.setCompositionMode(QPainter::CompositionMode_Xor);
773   aPainter.setPen(Qt::white);
774   QRect aRect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
775   if (!myRect.isEmpty())
776     aPainter.drawRect(myRect);
777   aPainter.drawRect(aRect);
778   myRect = aRect;
779 }
780
781 bool OCCViewer_ViewWidget::setTransformRequested (OperationType op)
782 {
783   myOperation = op;
784   myViewPort->setMouseTracking(myOperation == NOTHING);
785   return true;
786 }
787
788 void OCCViewer_ViewWidget::clearViewer(const bool theUpdate)
789 {
790   // check if trihedron is displayed
791   Standard_Boolean isTrihedronDisplayed = myAISContext->IsDisplayed(myTrihedron);
792
793   // get objects to be erased (all currently displayed objects)
794   AIS_ListOfInteractive aList;
795   myAISContext->DisplayedObjects(aList);
796   AIS_ListIteratorOfListOfInteractive anIter(aList);
797   for (; anIter.More(); anIter.Next()) {
798     if (isTrihedronDisplayed && anIter.Value()->DynamicType() == STANDARD_TYPE(AIS_Trihedron))
799       continue;
800     // erase an object
801     Handle(AIS_InteractiveObject) anIO = anIter.Value();
802 #if OCC_VERSION_LARGE <= 0x06060000 
803     myAISContext->Erase(anIO, false, false);
804 #else
805     myAISContext->Erase(anIO, false);
806 #endif
807   }
808
809   // display trihedron if necessary
810   if (isTrihedronDisplayed)
811     myAISContext->Display(myTrihedron, theUpdate);
812   else if (theUpdate)
813     myV3dViewer->Update();
814   if (theUpdate)
815     myAISContext->UpdateCurrentViewer();
816 }