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