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