1 #include "XGUI_ViewWindow.h"
2 #include "XGUI_ViewPort.h"
3 #include "XGUI_Viewer.h"
4 #include "XGUI_Tools.h"
5 #include "XGUI_RubberBand.h"
11 #include <QResizeEvent>
12 #include <QApplication>
14 #include <QMdiSubWindow>
17 #include <QFileDialog>
18 #include <QStyleOptionToolBar>
20 #include <TopoDS_Shape.hxx>
21 #include <BRep_Tool.hxx>
23 #include <Visual3d_View.hxx>
27 const char* imageZoomCursor[] = { "32 32 3 1", ". c None", "a c #000000", "# c #ffffff",
28 "................................", "................................",
29 ".#######........................", "..aaaaaaa.......................",
30 "................................", ".............#####..............",
31 "...........##.aaaa##............", "..........#.aa.....a#...........",
32 ".........#.a.........#..........", ".........#a..........#a.........",
33 "........#.a...........#.........", "........#a............#a........",
34 "........#a............#a........", "........#a............#a........",
35 "........#a............#a........", ".........#...........#.a........",
36 ".........#a..........#a.........", ".........##.........#.a.........",
37 "........#####.....##.a..........", ".......###aaa#####.aa...........",
38 "......###aa...aaaaa.......#.....", ".....###aa................#a....",
39 "....###aa.................#a....", "...###aa...............#######..",
40 "....#aa.................aa#aaaa.", ".....a....................#a....",
41 "..........................#a....", "...........................a....",
42 "................................", "................................",
43 "................................", "................................" };
45 const char* imageRotateCursor[] = { "32 32 3 1", ". c None", "a c #000000", "# c #ffffff",
46 "................................", "................................",
47 "................................", "................................",
48 "........#.......................", ".......#.a......................",
49 "......#######...................", ".......#aaaaa#####..............",
50 "........#..##.a#aa##........##..", ".........a#.aa..#..a#.....##.aa.",
51 ".........#.a.....#...#..##.aa...", ".........#a.......#..###.aa.....",
52 "........#.a.......#a..#aa.......", "........#a.........#..#a........",
53 "........#a.........#a.#a........", "........#a.........#a.#a........",
54 "........#a.........#a.#a........", ".........#.........#a#.a........",
55 "........##a........#a#a.........", "......##.a#.......#.#.a.........",
56 "....##.aa..##.....##.a..........", "..##.aa.....a#####.aa...........",
57 "...aa.........aaa#a.............", "................#.a.............",
58 "...............#.a..............", "..............#.a...............",
59 "...............a................", "................................",
60 "................................", "................................",
61 "................................", "................................" };
63 const char* imageCrossCursor[] = { "32 32 3 1", ". c None", "a c #000000", "# c #ffffff",
64 "................................", "................................",
65 "................................", "................................",
66 "................................", "................................",
67 "................................", "...............#................",
68 "...............#a...............", "...............#a...............",
69 "...............#a...............", "...............#a...............",
70 "...............#a...............", "...............#a...............",
71 "...............#a...............", ".......#################........",
72 "........aaaaaaa#aaaaaaaaa.......", "...............#a...............",
73 "...............#a...............", "...............#a...............",
74 "...............#a...............", "...............#a...............",
75 "...............#a...............", "...............#a...............",
76 "................a...............", "................................",
77 "................................", "................................",
78 "................................", "................................",
79 "................................", "................................" };
81 ViewerToolbar::ViewerToolbar(QWidget* theParent, XGUI_ViewPort* thePort)
82 : QToolBar(theParent),
86 connect(myVPort, SIGNAL(resized()), this, SLOT(onViewPortResized()));
89 void ViewerToolbar::paintEvent(QPaintEvent* theEvent)
91 //QToolBar::paintEvent(theEvent);
93 QPainter aPainter(this);
95 QRect aVPRect = myVPort->rect();
96 QPoint aGlobPnt = mapToGlobal(aRect.topLeft());
97 QPoint aPnt = myVPort->mapFromGlobal(aGlobPnt);
100 QRect(aPnt.x(), aPnt.y() + aVPRect.height() - aRect.height(), aRect.width(), aRect.height()));
101 QImage aImg = myVPort->dumpView(aImgRect, myResize);
103 aPainter.drawImage(aRect, aImg);
107 QStyle *style = this->style();
108 QStyleOptionToolBar aOpt;
109 initStyleOption(&aOpt);
111 aOpt.rect = style->subElementRect(QStyle::SE_ToolBarHandle, &aOpt, this);
112 if (aOpt.rect.isValid())
113 style->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &aOpt, &aPainter, this);
116 //**************************************************************************
117 ViewerLabel::ViewerLabel(QWidget* theParent, XGUI_ViewPort* thePort)
122 connect(myVPort, SIGNAL(resized()), this, SLOT(onViewPortResized()));
125 void ViewerLabel::paintEvent(QPaintEvent* theEvent)
127 QRect aRect = rect();
128 QRect aVPRect = myVPort->rect();
129 QPoint aGlobPnt = mapToGlobal(aRect.topLeft());
130 QPoint aPnt = myVPort->mapFromGlobal(aGlobPnt);
133 QRect(aPnt.x(), aPnt.y() + aVPRect.height() - aRect.height(), aRect.width(), aRect.height()));
134 QImage aImg = myVPort->dumpView(aImgRect, myResize);
136 QPainter(this).drawImage(aRect, aImg);
138 QLabel::paintEvent(theEvent);
141 //**************************************************************************
142 //**************************************************************************
143 //**************************************************************************
144 XGUI_ViewWindow::XGUI_ViewWindow(XGUI_Viewer* theViewer, V3d_TypeOfView theType)
148 MinimizeIco(":pictures/wnd_minimize.png"),
149 MaximizeIco(":pictures/wnd_maximize.png"),
150 CloseIco(":pictures/wnd_close.png"),
151 RestoreIco(":pictures/wnd_restore.png"),
152 myInteractionStyle(XGUI::STANDARD),
155 my2dMode(XGUI::No2dMode),
156 myCurrPointType(XGUI::GRAVITY),
157 myPrevPointType(XGUI::GRAVITY),
158 myRotationPointSelection(false),
167 myEnableDrawMode(false),
168 myCursorIsHand(false),
169 myEventStarted(false),
171 myLastState(WindowNormalState),
174 mySelectedPoint = gp_Pnt(0., 0., 0.);
175 setFrameStyle(QFrame::Raised);
176 setFrameShape(QFrame::Panel);
177 setLineWidth(BORDER_SIZE);
178 setMouseTracking(true);
180 QVBoxLayout* aLay = new QVBoxLayout(this);
181 aLay->setContentsMargins(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE);
182 myViewPort = new XGUI_ViewPort(this, myViewer->v3dViewer(), theType);
183 myViewPort->installEventFilter(this);
184 myViewPort->setCursor(Qt::ArrowCursor);
185 aLay->addWidget(myViewPort);
187 myPicture = new QLabel(this);
188 myPicture->setFrameStyle(QFrame::Sunken);
189 myPicture->setFrameShape(QFrame::Panel);
190 myPicture->setMouseTracking(true);
191 myPicture->installEventFilter(this);
192 aLay->addWidget(myPicture);
195 QVBoxLayout* aVPLay = new QVBoxLayout(myViewPort);
196 aVPLay->setMargin(0);
197 aVPLay->setSpacing(0);
198 aVPLay->setContentsMargins(0, 0, 0, 0);
200 QHBoxLayout* aToolLay = new QHBoxLayout();
201 aToolLay->setMargin(0);
202 aToolLay->setSpacing(0);
203 aToolLay->setContentsMargins(0, 0, 0, 0);
204 aVPLay->addLayout(aToolLay);
205 aVPLay->addStretch();
207 myGripWgt = new ViewerLabel(this, myViewPort);
208 myGripWgt->setPixmap(QPixmap(":pictures/wnd_grip.png"));
209 myGripWgt->setMouseTracking(true);
210 myGripWgt->installEventFilter(this);
211 myGripWgt->setCursor(Qt::OpenHandCursor);
212 aToolLay->addWidget(myGripWgt);
214 // Create Viewer management buttons
215 myViewBar = new ViewerToolbar(this, myViewPort);
216 myViewBar->setCursor(Qt::PointingHandCursor);
217 aToolLay->addWidget(myViewBar);
218 aToolLay->addStretch();
223 aBtn = new QAction(QIcon(":pictures/occ_view_camera_dump.png"), tr("Dump view"), myViewBar);
224 connect(aBtn, SIGNAL(triggered()), SLOT(dumpView()));
225 myViewBar->addAction(aBtn);
227 aBtn = new QAction(QIcon(":pictures/occ_view_fitall.png"), tr("Fit all"), myViewBar);
228 connect(aBtn, SIGNAL(triggered()), SLOT(fitAll()));
229 myViewBar->addAction(aBtn);
231 aBtn = new QAction(QIcon(":pictures/occ_view_fitarea.png"), tr("Fit area"), myViewBar);
232 connect(aBtn, SIGNAL(triggered()), SLOT(activateWindowFit()));
233 myViewBar->addAction(aBtn);
235 aBtn = new QAction(QIcon(":pictures/occ_view_zoom.png"), tr("Zoom"), myViewBar);
236 connect(aBtn, SIGNAL(triggered()), SLOT(activateZoom()));
237 myViewBar->addAction(aBtn);
239 aBtn = new QAction(QIcon(":pictures/occ_view_pan.png"), tr("Panning"), myViewBar);
240 connect(aBtn, SIGNAL(triggered()), SLOT(activatePanning()));
241 myViewBar->addAction(aBtn);
243 aBtn = new QAction(QIcon(":pictures/occ_view_glpan.png"), tr("Global panning"), myViewBar);
244 connect(aBtn, SIGNAL(triggered()), SLOT(activateGlobalPanning()));
245 myViewBar->addAction(aBtn);
247 aBtn = new QAction(QIcon(":pictures/occ_view_rotate.png"), tr("Rotate"), myViewBar);
248 connect(aBtn, SIGNAL(triggered()), SLOT(activateRotation()));
249 myViewBar->addAction(aBtn);
251 aBtn = new QAction(QIcon(":pictures/occ_view_reset.png"), tr("Reset"), myViewBar);
252 connect(aBtn, SIGNAL(triggered()), SLOT(reset()));
253 myViewBar->addAction(aBtn);
255 aBtn = new QAction(QIcon(":pictures/occ_view_front.png"), tr("Front"), myViewBar);
256 connect(aBtn, SIGNAL(triggered()), SLOT(frontView()));
257 myViewBar->addAction(aBtn);
259 aBtn = new QAction(QIcon(":pictures/occ_view_back.png"), tr("Back"), myViewBar);
260 connect(aBtn, SIGNAL(triggered()), SLOT(backView()));
261 myViewBar->addAction(aBtn);
263 aBtn = new QAction(QIcon(":pictures/occ_view_top.png"), tr("Top"), myViewBar);
264 connect(aBtn, SIGNAL(triggered()), SLOT(topView()));
265 myViewBar->addAction(aBtn);
267 aBtn = new QAction(QIcon(":pictures/occ_view_bottom.png"), tr("Bottom"), myViewBar);
268 connect(aBtn, SIGNAL(triggered()), SLOT(bottomView()));
269 myViewBar->addAction(aBtn);
271 aBtn = new QAction(QIcon(":pictures/occ_view_left.png"), tr("Left"), myViewBar);
272 connect(aBtn, SIGNAL(triggered()), SLOT(leftView()));
273 myViewBar->addAction(aBtn);
275 aBtn = new QAction(QIcon(":pictures/occ_view_right.png"), tr("Right"), myViewBar);
276 connect(aBtn, SIGNAL(triggered()), SLOT(rightView()));
277 myViewBar->addAction(aBtn);
279 aBtn = new QAction(QIcon(":pictures/occ_view_clone.png"), tr("Clone"), myViewBar);
280 connect(aBtn, SIGNAL(triggered()), SLOT(cloneView()));
281 myViewBar->addAction(aBtn);
283 // Create Window management buttons
284 myWindowBar = new ViewerToolbar(this, myViewPort);
285 myWindowBar->setCursor(Qt::PointingHandCursor);
286 aToolLay->addWidget(myWindowBar);
288 myMinimizeBtn = new QAction(myWindowBar);
289 myMinimizeBtn->setIcon(MinimizeIco);
290 myWindowBar->addAction(myMinimizeBtn);
291 connect(myMinimizeBtn, SIGNAL(triggered()), SLOT(onMinimize()));
293 myMaximizeBtn = new QAction(myWindowBar);
294 myMaximizeBtn->setIcon(MaximizeIco);
295 myWindowBar->addAction(myMaximizeBtn);
296 connect(myMaximizeBtn, SIGNAL(triggered()), SLOT(onMaximize()));
298 aBtn = new QAction(myWindowBar);
299 aBtn->setIcon(CloseIco);
300 myWindowBar->addAction(aBtn);
301 connect(aBtn, SIGNAL(triggered()), SLOT(onClose()));
303 //Support copy of background on updating of viewer
304 connect(myViewPort, SIGNAL(vpTransformed()), this, SLOT(updateToolBar()));
305 connect(myViewPort, SIGNAL(vpUpdated()), this, SLOT(updateToolBar()));
306 connect(this, SIGNAL(vpTransformationFinished(XGUI_ViewWindow::OperationType)), this,
307 SLOT(updateToolBar()));
310 //****************************************************************
311 XGUI_ViewWindow::~XGUI_ViewWindow()
315 //****************************************************************
316 void XGUI_ViewWindow::showEvent(QShowEvent* theEvent)
318 QFrame::showEvent(theEvent);
319 myWindowBar->setFixedSize(myWindowBar->sizeHint());
322 //****************************************************************
323 void XGUI_ViewWindow::changeEvent(QEvent* theEvent)
326 if (theEvent->type() == QEvent::WindowStateChange) {
328 if (myPicture->isHidden()) {
336 if (myPicture->isVisible()) {
341 myMinimizeBtn->setIcon(MinimizeIco);
342 myMaximizeBtn->setIcon(RestoreIco);
344 myViewBar->setVisible(myIsActive);
345 myWindowBar->setVisible(myIsActive);
346 myGripWgt->setVisible(myIsActive && (!isMaximized()));
349 QWidget::changeEvent(theEvent);
352 //****************************************************************
353 void XGUI_ViewWindow::windowActivated()
355 if (!(isMinimized() || parentWidget()->isMinimized())) {
357 if (isMaximized() || parentWidget()->isMaximized()) {
358 myMaximizeBtn->setIcon(RestoreIco);
360 myMaximizeBtn->setIcon(MaximizeIco);
364 myGripWgt->setVisible(
365 !(isMaximized() || isMinimized() || parentWidget()->isMaximized()
366 || parentWidget()->isMinimized()));
371 //****************************************************************
372 void XGUI_ViewWindow::windowDeactivated()
375 if (!(isMinimized() || parentWidget()->isMinimized())) {
376 if (isMaximized() || parentWidget()->isMaximized()) {
377 myMaximizeBtn->setIcon(RestoreIco);
379 myMaximizeBtn->setIcon(MaximizeIco);
387 //****************************************************************
388 void XGUI_ViewWindow::onClose()
390 if (parentWidget()) {
391 emit tryClosing(this);
393 emit closed(static_cast<QMdiSubWindow*>(parentWidget()));
394 parentWidget()->close();
399 //****************************************************************
400 void XGUI_ViewWindow::onMinimize()
402 QPixmap aPMap = QPixmap::fromImage(myViewPort->dumpView());
405 double aR = aW / 100.;
406 int aNewH = int(aH / aR);
407 myPicture->setPixmap(aPMap.scaled(100, aNewH));
410 (isMaximized() || parentWidget()->isMaximized()) ? MaximizedState : WindowNormalState;
412 parentWidget()->showMinimized();
413 parentWidget()->setGeometry(parentWidget()->x(), parentWidget()->y(), 100, aNewH);
414 parentWidget()->lower();
416 myViewer->onWindowMinimized((QMdiSubWindow*) parentWidget());
419 //****************************************************************
420 void XGUI_ViewWindow::onMaximize()
422 if (isMaximized() || parentWidget()->isMaximized()) {
423 myMaximizeBtn->setIcon(MaximizeIco);
426 parentWidget()->showNormal();
428 myMaximizeBtn->setIcon(RestoreIco);
431 parentWidget()->showMaximized();
433 parentWidget()->activateWindow();
434 myMinimizeBtn->setIcon(MinimizeIco);
436 // In order to avoid frosen background in toolbars when it shown as a second view
437 QTimer::singleShot(50, parentWidget(), SLOT(setFocus()));
440 //****************************************************************
441 bool XGUI_ViewWindow::processWindowControls(QObject *theObj, QEvent *theEvent)
443 switch (theEvent->type()) {
444 case QEvent::MouseButtonPress: {
445 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
446 if ((aEvent->button() == Qt::LeftButton) && (!myMoving)) {
448 myMousePnt = aEvent->globalPos();
453 case QEvent::MouseButtonRelease: {
454 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
455 if ((aEvent->button() == Qt::LeftButton) && myMoving) {
461 case QEvent::MouseMove: {
462 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
464 QMdiSubWindow* aParent = static_cast<QMdiSubWindow*>(parentWidget());
465 QMdiArea* aMDIArea = aParent->mdiArea();
467 QPoint aPnt = aEvent->globalPos();
468 QPoint aMDIPnt = aMDIArea->mapFromGlobal(aPnt);
469 if (aMDIArea->rect().contains(aMDIPnt)) {
470 int aX = aParent->x() + (aPnt.x() - myMousePnt.x());
471 int aY = aParent->y() + (aPnt.y() - myMousePnt.y());
472 aParent->move(aX, aY);
479 case QEvent::MouseButtonDblClick:
480 if (theObj == myPicture) {
482 if (myLastState == MaximizedState) {
487 myViewer->onWindowActivated((QMdiSubWindow*) parentWidget());
489 // In order to avoid frosen background in toolbars when it shown as a second view
490 QTimer::singleShot(20, parentWidget(), SLOT(setFocus()));
498 //****************************************************************
499 bool XGUI_ViewWindow::processViewPort(QEvent *theEvent)
501 switch (theEvent->type()) {
502 case QEvent::MouseButtonPress:
503 vpMousePressEvent((QMouseEvent*) theEvent);
506 case QEvent::MouseButtonRelease:
507 vpMouseReleaseEvent((QMouseEvent*) theEvent);
510 case QEvent::MouseMove:
511 vpMouseMoveEvent((QMouseEvent*) theEvent);
514 case QEvent::MouseButtonDblClick:
515 emit mouseDoubleClicked(this, (QMouseEvent*) theEvent);
517 case QEvent::Wheel: {
518 QWheelEvent* aEvent = (QWheelEvent*) theEvent;
519 myViewPort->startZoomAtPoint(aEvent->x(), aEvent->y());
520 double aDelta = (double) (aEvent->delta()) / (15 * 8);
523 int x1 = (int) (aEvent->x() + width() * aDelta / 100);
524 int y1 = (int) (aEvent->y() + height() * aDelta / 100);
525 myViewPort->zoom(x, y, x1, y1);
532 //****************************************************************
533 bool XGUI_ViewWindow::eventFilter(QObject *theObj, QEvent *theEvent)
535 if ((theObj == myGripWgt) || (theObj == myPicture)) {
536 if (processWindowControls(theObj, theEvent))
538 } else if (theObj == myViewPort) {
539 if (processViewPort(theEvent)) {
542 if (theEvent->type() == QEvent::KeyRelease) {
543 emit keyReleased(this, (QKeyEvent*) theEvent);
547 return QFrame::eventFilter(theObj, theEvent);
550 //****************************************************************
551 XGUI_ViewWindow::OperationType XGUI_ViewWindow::getButtonState(
552 QMouseEvent* theEvent, XGUI::InteractionStyle theInteractionStyle)
554 OperationType aOp = NOTHING;
555 XGUI::InteractionStyle aStyle = (XGUI::InteractionStyle) theInteractionStyle;
556 if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ZOOM])
557 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ZOOM]))
559 else if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::PAN])
560 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::PAN]))
562 else if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ROTATE])
563 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ROTATE])
564 && (my2dMode == XGUI::No2dMode))
570 //****************************************************************
571 void XGUI_ViewWindow::vpMousePressEvent(QMouseEvent* theEvent)
573 myStartX = theEvent->x();
574 myStartY = theEvent->y();
575 XGUI::InteractionStyle anInteractionStyle = interactionStyle();
577 // in "key free" interaction style zoom operation is activated by two buttons (simultaneously pressed),
578 // which are assigned for pan and rotate - these operations are activated immediately after pressing
579 // of the first button, so it is necessary to switch to zoom when the second button is pressed
580 bool aSwitchToZoom = false;
581 if ((anInteractionStyle == XGUI::KEY_FREE) && (myOperation == PANVIEW || myOperation == ROTATE)) {
582 aSwitchToZoom = getButtonState(theEvent, anInteractionStyle) == ZOOMVIEW;
585 switch (myOperation) {
587 if (theEvent->button() == Qt::LeftButton)
588 emit vpTransformationStarted(WINDOWFIT);
592 if (theEvent->button() == Qt::LeftButton)
593 emit vpTransformationStarted(PANGLOBAL);
597 if (theEvent->button() == Qt::LeftButton) {
598 myViewPort->startZoomAtPoint(myStartX, myStartY);
599 emit vpTransformationStarted(ZOOMVIEW);
605 myViewPort->startZoomAtPoint(myStartX, myStartY);
607 } else if (theEvent->button() == Qt::LeftButton)
608 emit vpTransformationStarted(PANVIEW);
613 myViewPort->startZoomAtPoint(myStartX, myStartY);
615 } else if (theEvent->button() == Qt::LeftButton) {
616 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
617 emit vpTransformationStarted(ROTATE);
622 /* Try to activate a transformation */
623 OperationType aState;
624 if (interactionStyle() == XGUI::STANDARD)
625 aState = getButtonState(theEvent, anInteractionStyle);
627 aState = XGUI_ViewWindow::NOTHING;
632 myViewPort->startZoomAtPoint(myStartX, myStartY);
640 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
643 if (myRotationPointSelection) {
644 if (theEvent->button() == Qt::LeftButton) {
645 Handle(AIS_InteractiveContext) ic = myViewer->AISContext();
647 for (ic->InitSelected(); ic->MoreSelected(); ic->NextSelected()) {
648 TopoDS_Shape aShape = ic->SelectedShape();
649 if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) {
650 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(ic->SelectedShape()));
651 /*if ( mySetRotationPointDlg ) {
652 myRotationPointSelection = false;
653 mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z());
656 myCurrPointType = myPrevPointType;
660 if (ic->NbSelected() == 0)
661 myCurrPointType = myPrevPointType;
662 //if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange();
663 ic->CloseAllContexts();
664 myOperation = NOTHING;
665 myViewPort->setCursor(myCursor);
666 myCursorIsHand = false;
667 myRotationPointSelection = false;
670 emit mousePressed(this, theEvent);
673 /* notify that we start a transformation */
674 if (transformRequested())
675 emit vpTransformationStarted(myOperation);
677 if (transformRequested())
678 setTransformInProcess(true);
680 /* we may need it for sketching... */
681 /* if ( l_mbPressEvent )
682 delete l_mbPressEvent;
683 l_mbPressEvent = new QMouseEvent( *theEvent );*/
686 //****************************************************************
687 void XGUI_ViewWindow::contextMenuEvent(QContextMenuEvent* theEvent)
689 if (theEvent->modifiers() == Qt::NoModifier) {
690 // Temporary: has to be removed when viewer popup will be defined
691 //QFrame::contextMenuEvent(theEvent);
692 emit contextMenuRequested(theEvent);
696 //****************************************************************
697 void XGUI_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
699 switch (myOperation) {
701 int prevState = myCurSketch;
702 /* if(theEvent->button() == Qt::RightButton) {
703 QList<OCCViewer_ViewSketcher*>::Iterator it;
704 for ( it = mySketchers.begin(); it != mySketchers.end() && myCurSketch != -1; ++it ) {
705 OCCViewer_ViewSketcher* sk = (*it);
706 if( ( sk->sketchButton() & theEvent->button() ) && sk->sketchButton() == myCurSketch )
711 emit mouseReleased(this, theEvent);
715 myViewPort->endRotation();
725 if (theEvent->button() == Qt::LeftButton) {
726 myViewPort->setCenter(theEvent->x(), theEvent->y());
727 myViewPort->getView()->SetScale(myCurScale);
733 if (theEvent->button() == Qt::LeftButton) {
734 myCurrX = theEvent->x();
735 myCurrY = theEvent->y();
737 QRect rect = XGUI_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
739 myViewPort->fitRect(rect);
746 // NOTE: viewer 3D detects a rectangle of selection using this event
747 // so we must emit it BEFORE resetting the selection rectangle
748 if (theEvent->button() == Qt::LeftButton && myDrawRect) {
752 myViewPort->update();
754 /* if ( l_mbPressEvent ) {
755 delete l_mbPressEvent;
760 //****************************************************************
761 void XGUI_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent)
763 if (myIsKeyFree && interactionStyle() == XGUI::KEY_FREE) {
765 switch (getButtonState(theEvent, interactionStyle())) {
767 myViewPort->startZoomAtPoint(myStartX, myStartY);
775 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
782 myCurrX = theEvent->x();
783 myCurrY = theEvent->y();
784 switch (myOperation) {
786 myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint);
790 myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY);
796 myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY);
805 if (myRotationPointSelection /*|| isSketcherStyle()*/) {
806 emit mouseMoving(this, theEvent);
808 int aState = theEvent->modifiers();
809 int aButton = theEvent->buttons();
810 int anInteractionStyle = interactionStyle();
811 if (((anInteractionStyle == XGUI::STANDARD) && (aButton == Qt::LeftButton)
812 && (aState == Qt::NoModifier || Qt::ShiftModifier))
813 || ((anInteractionStyle == XGUI::KEY_FREE) && (aButton == Qt::LeftButton)
814 && (aState == Qt::ControlModifier
815 || aState == (Qt::ControlModifier | Qt::ShiftModifier)))) {
816 myDrawRect = myEnableDrawMode;
819 if (!myCursorIsHand) { // we are going to sketch a rectangle
820 QCursor handCursor(Qt::PointingHandCursor);
821 myCursorIsHand = true;
823 myViewPort->setCursor(handCursor);
826 emit mouseMoving(this, theEvent);
827 } /* else if ( ( (anInteractionStyle == XGUI::STANDARD) &&
828 (aButton == Qt::RightButton) &&
829 ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) ||
830 ( (anInteractionStyle == XGUI::KEY_FREE) &&
831 (aButton == Qt::RightButton) &&
832 ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) {
833 OCCViewer_ViewSketcher* sketcher = 0;
834 QList<OCCViewer_ViewSketcher*>::Iterator it;
835 for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) {
836 OCCViewer_ViewSketcher* sk = (*it);
837 if( sk->isDefault() && sk->sketchButton() == aButton )
840 if ( sketcher && myCurSketch == -1 ) {
841 activateSketching( sketcher->type() );
843 myCurSketch = mypSketcher->sketchButton();
845 if ( l_mbPressEvent ) {
846 QApplication::sendEvent( getViewPort(), l_mbPressEvent );
847 delete l_mbPressEvent;
850 QApplication::sendEvent( getViewPort(), theEvent );
854 emit mouseMoving(this, theEvent);
860 \brief Draw rubber band rectangle.
862 void XGUI_ViewWindow::drawRect()
865 myRectBand = new XGUI_RectRubberBand(myViewPort);
868 myRectBand->setUpdatesEnabled(false);
869 QRect aRect = XGUI_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
870 myRectBand->initGeometry(aRect);
872 if (!myRectBand->isVisible())
875 myRectBand->setUpdatesEnabled(true);
879 \brief Clear rubber band rectangle on the end on the dragging operation.
881 void XGUI_ViewWindow::endDrawRect()
884 myRectBand->clearGeometry();
889 void XGUI_ViewWindow::activateZoom()
891 if (!transformRequested() && !myCursorIsHand)
892 myCursor = cursor(); /* save old cursor */
894 if (myOperation != ZOOMVIEW) {
895 QPixmap zoomPixmap(imageZoomCursor);
896 QCursor zoomCursor(zoomPixmap);
897 if (setTransformRequested(ZOOMVIEW))
898 myViewPort->setCursor(zoomCursor);
902 bool XGUI_ViewWindow::transformRequested() const
904 return (myOperation != NOTHING);
908 \brief Start delayed viewer operation.
910 bool XGUI_ViewWindow::setTransformRequested(OperationType op)
912 bool ok = transformEnabled(op);
913 myOperation = ok ? op : NOTHING;
914 myViewPort->setMouseTracking(myOperation == NOTHING);
919 Set enabled state of transformation (rotate, zoom, etc)
921 void XGUI_ViewWindow::setTransformEnabled(const OperationType id, const bool on)
924 myStatus.insert(id, on);
928 \return enabled state of transformation (rotate, zoom, etc)
930 bool XGUI_ViewWindow::transformEnabled(const OperationType id) const
932 return myStatus.contains(id) ? myStatus[id] : true;
936 \brief Start panning operation.
938 Sets the corresponding cursor for the widget.
940 void XGUI_ViewWindow::activatePanning()
942 if (!transformRequested() && !myCursorIsHand)
943 myCursor = cursor(); // save old cursor
945 if (myOperation != PANVIEW) {
946 QCursor panCursor(Qt::SizeAllCursor);
947 if (setTransformRequested(PANVIEW))
948 myViewPort->setCursor(panCursor);
953 \brief Start global panning operation
955 Sets the corresponding cursor for the widget.
957 void XGUI_ViewWindow::activateGlobalPanning()
959 Handle(V3d_View) aView3d = myViewPort->getView();
960 if (!aView3d.IsNull()) {
961 QPixmap globalPanPixmap(imageCrossCursor);
962 QCursor glPanCursor(globalPanPixmap);
963 myCurScale = aView3d->Scale();
964 aView3d->FitAll(0.01, false);
965 myCursor = cursor(); // save old cursor
966 myViewPort->fitAll(); // fits view before selecting a new scene center
967 if (setTransformRequested(PANGLOBAL))
968 myViewPort->setCursor(glPanCursor);
973 \brief Start rotation operation
975 Sets the corresponding cursor for the widget.
977 void XGUI_ViewWindow::activateRotation()
979 if (!transformRequested() && !myCursorIsHand)
980 myCursor = cursor(); // save old cursor
982 if (myOperation != ROTATE) {
983 QPixmap rotatePixmap(imageRotateCursor);
984 QCursor rotCursor(rotatePixmap);
985 if (setTransformRequested(ROTATE))
986 myViewPort->setCursor(rotCursor);
991 \brief Reset the viewport to its initial state
992 ( no transformations in process etc. )
994 void XGUI_ViewWindow::resetState()
998 if (myRotationPointSelection) {
999 QCursor handCursor(Qt::PointingHandCursor);
1000 myViewPort->setCursor(handCursor);
1002 if (transformRequested() || myCursorIsHand)
1003 myViewPort->setCursor(myCursor);
1004 myCursorIsHand = false;
1007 if (transformRequested())
1008 emit vpTransformationFinished(myOperation);
1010 setTransformInProcess(false);
1011 setTransformRequested(NOTHING);
1014 Qtx::BackgroundData XGUI_ViewWindow::background() const
1016 return myViewPort ? myViewPort->background() : Qtx::BackgroundData();
1019 void XGUI_ViewWindow::setBackground(const Qtx::BackgroundData& theBackground)
1022 myViewPort->setBackground(theBackground);
1026 \brief Create one more window with same content.
1028 void XGUI_ViewWindow::cloneView()
1030 QMdiSubWindow* vw = myViewer->createView();
1031 XGUI_ViewWindow* aNewWnd = static_cast<XGUI_ViewWindow*>(vw->widget());
1032 aNewWnd->viewPort()->syncronizeWith(myViewPort);
1034 emit viewCloned(vw);
1036 // In order to avoid frosen background in toolbars when it shown as a second view
1037 QTimer::singleShot(20, vw, SLOT(setFocus()));
1040 void XGUI_ViewWindow::dumpView()
1042 QString aFilter(tr("Images Files (*.bmp *.png *.jpg *.jpeg *.eps *.ps)"));
1043 QString aSelectedFilter;
1044 QString aFileName = QFileDialog::getSaveFileName(this, "Save picture", QString(), aFilter,
1046 if (!aFileName.isNull()) {
1047 QApplication::setOverrideCursor(Qt::WaitCursor);
1048 QImage aPicture = myViewPort->dumpView();
1050 QString aFmt = XGUI_Tools::extension(aFileName).toUpper();
1052 aFmt = QString("BMP"); // default format
1053 else if (aFmt == "JPG")
1056 Handle(Visual3d_View) a3dView = myViewPort->getView()->View();
1059 a3dView->Export(_strdup(qPrintable(aFileName)), Graphic3d_EF_PostScript);
1061 a3dView->Export(strdup(qPrintable(aFileName)), Graphic3d_EF_PostScript);
1063 else if (aFmt == "EPS")
1065 a3dView->Export(_strdup(qPrintable(aFileName)), Graphic3d_EF_EnhPostScript);
1067 a3dView->Export(strdup(qPrintable(aFileName)), Graphic3d_EF_EnhPostScript);
1070 aPicture.save(aFileName, aFmt.toLatin1());
1071 QApplication::restoreOverrideCursor();
1075 void XGUI_ViewWindow::fitAll()
1077 emit vpTransformationStarted(FITALLVIEW);
1078 myViewPort->fitAll();
1079 emit vpTransformationFinished(FITALLVIEW);
1083 \brief Starts fit operation.
1085 Sets the corresponding cursor for the widget.
1087 void XGUI_ViewWindow::activateWindowFit()
1089 if (!transformRequested() && !myCursorIsHand)
1090 myCursor = cursor(); /* save old cursor */
1092 if (myOperation != WINDOWFIT) {
1093 QCursor handCursor(Qt::PointingHandCursor);
1094 if (setTransformRequested(WINDOWFIT)) {
1095 myViewPort->setCursor(handCursor);
1096 myCursorIsHand = true;
1102 \brief Perform "front view" transformation.
1104 void XGUI_ViewWindow::frontView()
1106 emit vpTransformationStarted(FRONTVIEW);
1107 Handle(V3d_View) aView3d = myViewPort->getView();
1108 if (!aView3d.IsNull())
1109 aView3d->SetProj(V3d_Xpos);
1110 myViewPort->fitAll();
1111 emit vpTransformationFinished(FRONTVIEW);
1115 \brief Perform "back view" transformation.
1117 void XGUI_ViewWindow::backView()
1119 emit vpTransformationStarted(BACKVIEW);
1120 Handle(V3d_View) aView3d = myViewPort->getView();
1121 if (!aView3d.IsNull())
1122 aView3d->SetProj(V3d_Xneg);
1123 myViewPort->fitAll();
1124 emit vpTransformationFinished(BACKVIEW);
1128 \brief Perform "top view" transformation.
1130 void XGUI_ViewWindow::topView()
1132 emit vpTransformationStarted(TOPVIEW);
1133 Handle(V3d_View) aView3d = myViewPort->getView();
1134 if (!aView3d.IsNull())
1135 aView3d->SetProj(V3d_Zpos);
1136 myViewPort->fitAll();
1137 emit vpTransformationFinished(TOPVIEW);
1141 \brief Perform "bottom view" transformation.
1143 void XGUI_ViewWindow::bottomView()
1145 emit vpTransformationStarted(BOTTOMVIEW);
1146 Handle(V3d_View) aView3d = myViewPort->getView();
1147 if (!aView3d.IsNull())
1148 aView3d->SetProj(V3d_Zneg);
1149 myViewPort->fitAll();
1150 emit vpTransformationFinished(BOTTOMVIEW);
1154 \brief Perform "left view" transformation.
1156 void XGUI_ViewWindow::leftView()
1158 emit vpTransformationStarted(LEFTVIEW);
1159 Handle(V3d_View) aView3d = myViewPort->getView();
1160 if (!aView3d.IsNull())
1161 aView3d->SetProj(V3d_Yneg);
1162 myViewPort->fitAll();
1163 emit vpTransformationFinished(LEFTVIEW);
1167 \brief Perform "right view" transformation.
1169 void XGUI_ViewWindow::rightView()
1171 emit vpTransformationStarted(RIGHTVIEW);
1172 Handle(V3d_View) aView3d = myViewPort->getView();
1173 if (!aView3d.IsNull())
1174 aView3d->SetProj(V3d_Ypos);
1175 myViewPort->fitAll();
1176 emit vpTransformationFinished(RIGHTVIEW);
1179 void XGUI_ViewWindow::reset()
1181 emit vpTransformationStarted(RESETVIEW);
1182 bool upd = myViewPort->getView()->SetImmediateUpdate(false);
1183 myViewPort->getView()->Reset(false);
1184 myViewPort->fitAll(false, true, false);
1185 myViewPort->getView()->SetImmediateUpdate(upd);
1186 myViewPort->getView()->Update();
1187 emit vpTransformationFinished(RESETVIEW);
1190 void XGUI_ViewWindow::updateToolBar()
1192 myGripWgt->update();
1193 myViewBar->update();
1194 myWindowBar->update();
1198 \brief Update state of enable draw mode state.
1200 void XGUI_ViewWindow::updateEnabledDrawMode()
1202 myEnableDrawMode = myViewer->isSelectionEnabled() && myViewer->isMultiSelectionEnabled();