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 unsigned char* aData = 0;
102 QImage aImg = myVPort->dumpView(aData, aImgRect, myResize);
104 aPainter.drawImage(aRect, aImg);
108 QStyle *style = this->style();
109 QStyleOptionToolBar aOpt;
110 initStyleOption(&aOpt);
112 aOpt.rect = style->subElementRect(QStyle::SE_ToolBarHandle, &aOpt, this);
113 if (aOpt.rect.isValid())
114 style->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &aOpt, &aPainter, this);
119 //**************************************************************************
120 ViewerLabel::ViewerLabel(QWidget* theParent, XGUI_ViewPort* thePort)
125 connect(myVPort, SIGNAL(resized()), this, SLOT(onViewPortResized()));
128 void ViewerLabel::paintEvent(QPaintEvent* theEvent)
130 QRect aRect = rect();
131 QRect aVPRect = myVPort->rect();
132 QPoint aGlobPnt = mapToGlobal(aRect.topLeft());
133 QPoint aPnt = myVPort->mapFromGlobal(aGlobPnt);
136 QRect(aPnt.x(), aPnt.y() + aVPRect.height() - aRect.height(), aRect.width(), aRect.height()));
137 unsigned char* aData = 0;
138 QImage aImg = myVPort->dumpView(aData, aImgRect, myResize);
140 QPainter(this).drawImage(aRect, aImg);
142 QLabel::paintEvent(theEvent);
147 //**************************************************************************
148 //**************************************************************************
149 //**************************************************************************
150 XGUI_ViewWindow::XGUI_ViewWindow(XGUI_Viewer* theViewer, V3d_TypeOfView theType)
154 MinimizeIco(":pictures/wnd_minimize.png"),
155 MaximizeIco(":pictures/wnd_maximize.png"),
156 CloseIco(":pictures/wnd_close.png"),
157 RestoreIco(":pictures/wnd_restore.png"),
158 myInteractionStyle(XGUI::STANDARD),
161 my2dMode(XGUI::No2dMode),
162 myCurrPointType(XGUI::GRAVITY),
163 myPrevPointType(XGUI::GRAVITY),
164 myRotationPointSelection(false),
173 myEnableDrawMode(false),
174 myCursorIsHand(false),
175 myEventStarted(false),
177 myLastState(WindowNormalState),
180 mySelectedPoint = gp_Pnt(0., 0., 0.);
181 setFrameStyle(QFrame::Raised);
182 setFrameShape(QFrame::Panel);
183 setLineWidth(BORDER_SIZE);
184 setMouseTracking(true);
186 QVBoxLayout* aLay = new QVBoxLayout(this);
187 aLay->setContentsMargins(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE);
188 myViewPort = new XGUI_ViewPort(this, myViewer->v3dViewer(), theType);
189 myViewPort->installEventFilter(this);
190 myViewPort->setCursor(Qt::ArrowCursor);
191 aLay->addWidget(myViewPort);
193 myPicture = new QLabel(this);
194 myPicture->setFrameStyle(QFrame::Sunken);
195 myPicture->setFrameShape(QFrame::Panel);
196 myPicture->setMouseTracking(true);
197 myPicture->installEventFilter(this);
198 aLay->addWidget(myPicture);
201 QVBoxLayout* aVPLay = new QVBoxLayout(myViewPort);
202 aVPLay->setMargin(0);
203 aVPLay->setSpacing(0);
204 aVPLay->setContentsMargins(0, 0, 0, 0);
206 QHBoxLayout* aToolLay = new QHBoxLayout();
207 aToolLay->setMargin(0);
208 aToolLay->setSpacing(0);
209 aToolLay->setContentsMargins(0, 0, 0, 0);
210 aVPLay->addLayout(aToolLay);
211 aVPLay->addStretch();
213 myGripWgt = new ViewerLabel(this, myViewPort);
214 myGripWgt->setPixmap(QPixmap(":pictures/wnd_grip.png"));
215 myGripWgt->setMouseTracking(true);
216 myGripWgt->installEventFilter(this);
217 myGripWgt->setCursor(Qt::OpenHandCursor);
218 aToolLay->addWidget(myGripWgt);
220 // Create Viewer management buttons
221 myViewBar = new ViewerToolbar(this, myViewPort);
222 myViewBar->setCursor(Qt::PointingHandCursor);
223 aToolLay->addWidget(myViewBar);
224 aToolLay->addStretch();
229 aBtn = new QAction(QIcon(":pictures/occ_view_camera_dump.png"), tr("Dump view"), myViewBar);
230 connect(aBtn, SIGNAL(triggered()), SLOT(dumpView()));
231 myViewBar->addAction(aBtn);
233 aBtn = new QAction(QIcon(":pictures/occ_view_fitall.png"), tr("Fit all"), myViewBar);
234 connect(aBtn, SIGNAL(triggered()), SLOT(fitAll()));
235 myViewBar->addAction(aBtn);
237 aBtn = new QAction(QIcon(":pictures/occ_view_fitarea.png"), tr("Fit area"), myViewBar);
238 connect(aBtn, SIGNAL(triggered()), SLOT(activateWindowFit()));
239 myViewBar->addAction(aBtn);
241 aBtn = new QAction(QIcon(":pictures/occ_view_zoom.png"), tr("Zoom"), myViewBar);
242 connect(aBtn, SIGNAL(triggered()), SLOT(activateZoom()));
243 myViewBar->addAction(aBtn);
245 aBtn = new QAction(QIcon(":pictures/occ_view_pan.png"), tr("Panning"), myViewBar);
246 connect(aBtn, SIGNAL(triggered()), SLOT(activatePanning()));
247 myViewBar->addAction(aBtn);
249 aBtn = new QAction(QIcon(":pictures/occ_view_glpan.png"), tr("Global panning"), myViewBar);
250 connect(aBtn, SIGNAL(triggered()), SLOT(activateGlobalPanning()));
251 myViewBar->addAction(aBtn);
253 aBtn = new QAction(QIcon(":pictures/occ_view_rotate.png"), tr("Rotate"), myViewBar);
254 connect(aBtn, SIGNAL(triggered()), SLOT(activateRotation()));
255 myViewBar->addAction(aBtn);
257 aBtn = new QAction(QIcon(":pictures/occ_view_reset.png"), tr("Reset"), myViewBar);
258 connect(aBtn, SIGNAL(triggered()), SLOT(reset()));
259 myViewBar->addAction(aBtn);
261 aBtn = new QAction(QIcon(":pictures/occ_view_front.png"), tr("Front"), myViewBar);
262 connect(aBtn, SIGNAL(triggered()), SLOT(frontView()));
263 myViewBar->addAction(aBtn);
265 aBtn = new QAction(QIcon(":pictures/occ_view_back.png"), tr("Back"), myViewBar);
266 connect(aBtn, SIGNAL(triggered()), SLOT(backView()));
267 myViewBar->addAction(aBtn);
269 aBtn = new QAction(QIcon(":pictures/occ_view_top.png"), tr("Top"), myViewBar);
270 connect(aBtn, SIGNAL(triggered()), SLOT(topView()));
271 myViewBar->addAction(aBtn);
273 aBtn = new QAction(QIcon(":pictures/occ_view_bottom.png"), tr("Bottom"), myViewBar);
274 connect(aBtn, SIGNAL(triggered()), SLOT(bottomView()));
275 myViewBar->addAction(aBtn);
277 aBtn = new QAction(QIcon(":pictures/occ_view_left.png"), tr("Left"), myViewBar);
278 connect(aBtn, SIGNAL(triggered()), SLOT(leftView()));
279 myViewBar->addAction(aBtn);
281 aBtn = new QAction(QIcon(":pictures/occ_view_right.png"), tr("Right"), myViewBar);
282 connect(aBtn, SIGNAL(triggered()), SLOT(rightView()));
283 myViewBar->addAction(aBtn);
285 aBtn = new QAction(QIcon(":pictures/occ_view_clone.png"), tr("Clone"), myViewBar);
286 connect(aBtn, SIGNAL(triggered()), SLOT(cloneView()));
287 myViewBar->addAction(aBtn);
289 // Create Window management buttons
290 myWindowBar = new ViewerToolbar(this, myViewPort);
291 myWindowBar->setCursor(Qt::PointingHandCursor);
292 aToolLay->addWidget(myWindowBar);
294 myMinimizeBtn = new QAction(myWindowBar);
295 myMinimizeBtn->setIcon(MinimizeIco);
296 myWindowBar->addAction(myMinimizeBtn);
297 connect(myMinimizeBtn, SIGNAL(triggered()), SLOT(onMinimize()));
299 myMaximizeBtn = new QAction(myWindowBar);
300 myMaximizeBtn->setIcon(MaximizeIco);
301 myWindowBar->addAction(myMaximizeBtn);
302 connect(myMaximizeBtn, SIGNAL(triggered()), SLOT(onMaximize()));
304 aBtn = new QAction(myWindowBar);
305 aBtn->setIcon(CloseIco);
306 myWindowBar->addAction(aBtn);
307 connect(aBtn, SIGNAL(triggered()), SLOT(onClose()));
309 //Support copy of background on updating of viewer
310 connect(myViewPort, SIGNAL(vpTransformed()), this, SLOT(updateToolBar()));
311 connect(myViewPort, SIGNAL(vpUpdated()), this, SLOT(updateToolBar()));
312 connect(this, SIGNAL(vpTransformationFinished(XGUI_ViewWindow::OperationType)), this,
313 SLOT(updateToolBar()));
316 //****************************************************************
317 XGUI_ViewWindow::~XGUI_ViewWindow()
321 //****************************************************************
322 void XGUI_ViewWindow::showEvent(QShowEvent* theEvent)
324 QFrame::showEvent(theEvent);
325 myWindowBar->setFixedSize(myWindowBar->sizeHint());
328 //****************************************************************
329 void XGUI_ViewWindow::changeEvent(QEvent* theEvent)
332 if (theEvent->type() == QEvent::WindowStateChange) {
334 if (myPicture->isHidden()) {
342 if (myPicture->isVisible()) {
347 myMinimizeBtn->setIcon(MinimizeIco);
348 myMaximizeBtn->setIcon(RestoreIco);
350 myViewBar->setVisible(myIsActive);
351 myWindowBar->setVisible(myIsActive);
352 myGripWgt->setVisible(myIsActive && (!isMaximized()));
355 QWidget::changeEvent(theEvent);
358 //****************************************************************
359 void XGUI_ViewWindow::windowActivated()
361 if (!(isMinimized() || parentWidget()->isMinimized())) {
363 if (isMaximized() || parentWidget()->isMaximized()) {
364 myMaximizeBtn->setIcon(RestoreIco);
366 myMaximizeBtn->setIcon(MaximizeIco);
370 myGripWgt->setVisible(
371 !(isMaximized() || isMinimized() || parentWidget()->isMaximized()
372 || parentWidget()->isMinimized()));
377 //****************************************************************
378 void XGUI_ViewWindow::windowDeactivated()
381 if (!(isMinimized() || parentWidget()->isMinimized())) {
382 if (isMaximized() || parentWidget()->isMaximized()) {
383 myMaximizeBtn->setIcon(RestoreIco);
385 myMaximizeBtn->setIcon(MaximizeIco);
393 //****************************************************************
394 void XGUI_ViewWindow::onClose()
396 if (parentWidget()) {
397 emit tryClosing(this);
399 emit closed(static_cast<QMdiSubWindow*>(parentWidget()));
400 parentWidget()->close();
405 //****************************************************************
406 void XGUI_ViewWindow::onMinimize()
408 unsigned char* aData = 0;
409 QPixmap aPMap = QPixmap::fromImage(myViewPort->dumpView(aData));
412 double aR = aW / 100.;
413 int aNewH = int(aH / aR);
414 myPicture->setPixmap(aPMap.scaled(100, aNewH));
417 (isMaximized() || parentWidget()->isMaximized()) ? MaximizedState : WindowNormalState;
419 parentWidget()->showMinimized();
420 parentWidget()->setGeometry(parentWidget()->x(), parentWidget()->y(), 100, aNewH);
421 parentWidget()->lower();
423 myViewer->onWindowMinimized((QMdiSubWindow*) parentWidget());
427 //****************************************************************
428 void XGUI_ViewWindow::onMaximize()
430 if (isMaximized() || parentWidget()->isMaximized()) {
431 myMaximizeBtn->setIcon(MaximizeIco);
434 parentWidget()->showNormal();
436 myMaximizeBtn->setIcon(RestoreIco);
439 parentWidget()->showMaximized();
441 parentWidget()->activateWindow();
442 myMinimizeBtn->setIcon(MinimizeIco);
444 // In order to avoid frosen background in toolbars when it shown as a second view
445 QTimer::singleShot(50, parentWidget(), SLOT(setFocus()));
448 //****************************************************************
449 bool XGUI_ViewWindow::processWindowControls(QObject *theObj, QEvent *theEvent)
451 switch (theEvent->type()) {
452 case QEvent::MouseButtonPress: {
453 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
454 if ((aEvent->button() == Qt::LeftButton) && (!myMoving)) {
456 myMousePnt = aEvent->globalPos();
461 case QEvent::MouseButtonRelease: {
462 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
463 if ((aEvent->button() == Qt::LeftButton) && myMoving) {
469 case QEvent::MouseMove: {
470 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
472 QMdiSubWindow* aParent = static_cast<QMdiSubWindow*>(parentWidget());
473 QMdiArea* aMDIArea = aParent->mdiArea();
475 QPoint aPnt = aEvent->globalPos();
476 QPoint aMDIPnt = aMDIArea->mapFromGlobal(aPnt);
477 if (aMDIArea->rect().contains(aMDIPnt)) {
478 int aX = aParent->x() + (aPnt.x() - myMousePnt.x());
479 int aY = aParent->y() + (aPnt.y() - myMousePnt.y());
480 aParent->move(aX, aY);
487 case QEvent::MouseButtonDblClick:
488 if (theObj == myPicture) {
490 if (myLastState == MaximizedState) {
495 myViewer->onWindowActivated((QMdiSubWindow*) parentWidget());
497 // In order to avoid frosen background in toolbars when it shown as a second view
498 QTimer::singleShot(20, parentWidget(), SLOT(setFocus()));
506 //****************************************************************
507 bool XGUI_ViewWindow::processViewPort(QEvent *theEvent)
509 switch (theEvent->type()) {
510 case QEvent::MouseButtonPress:
511 vpMousePressEvent((QMouseEvent*) theEvent);
514 case QEvent::MouseButtonRelease:
515 vpMouseReleaseEvent((QMouseEvent*) theEvent);
518 case QEvent::MouseMove:
519 vpMouseMoveEvent((QMouseEvent*) theEvent);
522 case QEvent::MouseButtonDblClick:
523 emit mouseDoubleClicked(this, (QMouseEvent*) theEvent);
525 case QEvent::Wheel: {
526 QWheelEvent* aEvent = (QWheelEvent*) theEvent;
527 myViewPort->startZoomAtPoint(aEvent->x(), aEvent->y());
528 double aDelta = (double) (aEvent->delta()) / (15 * 8);
531 int x1 = (int) (aEvent->x() + width() * aDelta / 100);
532 int y1 = (int) (aEvent->y() + height() * aDelta / 100);
533 myViewPort->zoom(x, y, x1, y1);
540 //****************************************************************
541 bool XGUI_ViewWindow::eventFilter(QObject *theObj, QEvent *theEvent)
543 if ((theObj == myGripWgt) || (theObj == myPicture)) {
544 if (processWindowControls(theObj, theEvent))
546 } else if (theObj == myViewPort) {
547 if (processViewPort(theEvent)) {
550 if (theEvent->type() == QEvent::KeyRelease) {
551 emit keyReleased(this, (QKeyEvent*) theEvent);
555 return QFrame::eventFilter(theObj, theEvent);
558 //****************************************************************
559 XGUI_ViewWindow::OperationType XGUI_ViewWindow::getButtonState(
560 QMouseEvent* theEvent, XGUI::InteractionStyle theInteractionStyle)
562 OperationType aOp = NOTHING;
563 XGUI::InteractionStyle aStyle = (XGUI::InteractionStyle) theInteractionStyle;
564 if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ZOOM])
565 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ZOOM]))
567 else if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::PAN])
568 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::PAN]))
570 else if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ROTATE])
571 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ROTATE])
572 && (my2dMode == XGUI::No2dMode))
578 //****************************************************************
579 void XGUI_ViewWindow::vpMousePressEvent(QMouseEvent* theEvent)
581 myStartX = theEvent->x();
582 myStartY = theEvent->y();
583 XGUI::InteractionStyle anInteractionStyle = interactionStyle();
585 // in "key free" interaction style zoom operation is activated by two buttons (simultaneously pressed),
586 // which are assigned for pan and rotate - these operations are activated immediately after pressing
587 // of the first button, so it is necessary to switch to zoom when the second button is pressed
588 bool aSwitchToZoom = false;
589 if ((anInteractionStyle == XGUI::KEY_FREE) && (myOperation == PANVIEW || myOperation == ROTATE)) {
590 aSwitchToZoom = getButtonState(theEvent, anInteractionStyle) == ZOOMVIEW;
593 switch (myOperation) {
595 if (theEvent->button() == Qt::LeftButton)
596 emit vpTransformationStarted(WINDOWFIT);
600 if (theEvent->button() == Qt::LeftButton)
601 emit vpTransformationStarted(PANGLOBAL);
605 if (theEvent->button() == Qt::LeftButton) {
606 myViewPort->startZoomAtPoint(myStartX, myStartY);
607 emit vpTransformationStarted(ZOOMVIEW);
613 myViewPort->startZoomAtPoint(myStartX, myStartY);
615 } else if (theEvent->button() == Qt::LeftButton)
616 emit vpTransformationStarted(PANVIEW);
621 myViewPort->startZoomAtPoint(myStartX, myStartY);
623 } else if (theEvent->button() == Qt::LeftButton) {
624 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
625 emit vpTransformationStarted(ROTATE);
630 /* Try to activate a transformation */
631 OperationType aState;
632 if (interactionStyle() == XGUI::STANDARD)
633 aState = getButtonState(theEvent, anInteractionStyle);
635 aState = XGUI_ViewWindow::NOTHING;
640 myViewPort->startZoomAtPoint(myStartX, myStartY);
648 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
651 if (myRotationPointSelection) {
652 if (theEvent->button() == Qt::LeftButton) {
653 Handle(AIS_InteractiveContext) ic = myViewer->AISContext();
655 for (ic->InitSelected(); ic->MoreSelected(); ic->NextSelected()) {
656 TopoDS_Shape aShape = ic->SelectedShape();
657 if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) {
658 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(ic->SelectedShape()));
659 /*if ( mySetRotationPointDlg ) {
660 myRotationPointSelection = false;
661 mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z());
664 myCurrPointType = myPrevPointType;
668 if (ic->NbSelected() == 0)
669 myCurrPointType = myPrevPointType;
670 //if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange();
671 ic->CloseAllContexts();
672 myOperation = NOTHING;
673 myViewPort->setCursor(myCursor);
674 myCursorIsHand = false;
675 myRotationPointSelection = false;
678 emit mousePressed(this, theEvent);
681 /* notify that we start a transformation */
682 if (transformRequested())
683 emit vpTransformationStarted(myOperation);
685 if (transformRequested())
686 setTransformInProcess(true);
688 /* we may need it for sketching... */
689 /* if ( l_mbPressEvent )
690 delete l_mbPressEvent;
691 l_mbPressEvent = new QMouseEvent( *theEvent );*/
694 //****************************************************************
695 void XGUI_ViewWindow::contextMenuEvent(QContextMenuEvent* theEvent)
697 if (theEvent->modifiers() == Qt::NoModifier) {
698 // Temporary: has to be removed when viewer popup will be defined
699 //QFrame::contextMenuEvent(theEvent);
700 emit contextMenuRequested(theEvent);
704 //****************************************************************
705 void XGUI_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
707 switch (myOperation) {
709 int prevState = myCurSketch;
710 /* if(theEvent->button() == Qt::RightButton) {
711 QList<OCCViewer_ViewSketcher*>::Iterator it;
712 for ( it = mySketchers.begin(); it != mySketchers.end() && myCurSketch != -1; ++it ) {
713 OCCViewer_ViewSketcher* sk = (*it);
714 if( ( sk->sketchButton() & theEvent->button() ) && sk->sketchButton() == myCurSketch )
719 emit mouseReleased(this, theEvent);
723 myViewPort->endRotation();
733 if (theEvent->button() == Qt::LeftButton) {
734 myViewPort->setCenter(theEvent->x(), theEvent->y());
735 myViewPort->getView()->SetScale(myCurScale);
741 if (theEvent->button() == Qt::LeftButton) {
742 myCurrX = theEvent->x();
743 myCurrY = theEvent->y();
745 QRect rect = XGUI_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
747 myViewPort->fitRect(rect);
754 // NOTE: viewer 3D detects a rectangle of selection using this event
755 // so we must emit it BEFORE resetting the selection rectangle
756 if (theEvent->button() == Qt::LeftButton && myDrawRect) {
760 myViewPort->update();
762 /* if ( l_mbPressEvent ) {
763 delete l_mbPressEvent;
768 //****************************************************************
769 void XGUI_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent)
771 if (myIsKeyFree && interactionStyle() == XGUI::KEY_FREE) {
773 switch (getButtonState(theEvent, interactionStyle())) {
775 myViewPort->startZoomAtPoint(myStartX, myStartY);
783 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
790 myCurrX = theEvent->x();
791 myCurrY = theEvent->y();
792 switch (myOperation) {
794 myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint);
798 myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY);
804 myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY);
813 if (myRotationPointSelection /*|| isSketcherStyle()*/) {
814 emit mouseMoving(this, theEvent);
816 int aState = theEvent->modifiers();
817 int aButton = theEvent->buttons();
818 int anInteractionStyle = interactionStyle();
819 if (((anInteractionStyle == XGUI::STANDARD) && (aButton == Qt::LeftButton)
820 && (aState == Qt::NoModifier || Qt::ShiftModifier))
821 || ((anInteractionStyle == XGUI::KEY_FREE) && (aButton == Qt::LeftButton)
822 && (aState == Qt::ControlModifier
823 || aState == (Qt::ControlModifier | Qt::ShiftModifier)))) {
824 myDrawRect = myEnableDrawMode;
827 if (!myCursorIsHand) { // we are going to sketch a rectangle
828 QCursor handCursor(Qt::PointingHandCursor);
829 myCursorIsHand = true;
831 myViewPort->setCursor(handCursor);
834 emit mouseMoving(this, theEvent);
835 } /* else if ( ( (anInteractionStyle == XGUI::STANDARD) &&
836 (aButton == Qt::RightButton) &&
837 ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) ||
838 ( (anInteractionStyle == XGUI::KEY_FREE) &&
839 (aButton == Qt::RightButton) &&
840 ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) {
841 OCCViewer_ViewSketcher* sketcher = 0;
842 QList<OCCViewer_ViewSketcher*>::Iterator it;
843 for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) {
844 OCCViewer_ViewSketcher* sk = (*it);
845 if( sk->isDefault() && sk->sketchButton() == aButton )
848 if ( sketcher && myCurSketch == -1 ) {
849 activateSketching( sketcher->type() );
851 myCurSketch = mypSketcher->sketchButton();
853 if ( l_mbPressEvent ) {
854 QApplication::sendEvent( getViewPort(), l_mbPressEvent );
855 delete l_mbPressEvent;
858 QApplication::sendEvent( getViewPort(), theEvent );
862 emit mouseMoving(this, theEvent);
868 \brief Draw rubber band rectangle.
870 void XGUI_ViewWindow::drawRect()
873 myRectBand = new XGUI_RectRubberBand(myViewPort);
876 myRectBand->setUpdatesEnabled(false);
877 QRect aRect = XGUI_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
878 myRectBand->initGeometry(aRect);
880 if (!myRectBand->isVisible())
883 myRectBand->setUpdatesEnabled(true);
887 \brief Clear rubber band rectangle on the end on the dragging operation.
889 void XGUI_ViewWindow::endDrawRect()
892 myRectBand->clearGeometry();
897 void XGUI_ViewWindow::activateZoom()
899 if (!transformRequested() && !myCursorIsHand)
900 myCursor = cursor(); /* save old cursor */
902 if (myOperation != ZOOMVIEW) {
903 QPixmap zoomPixmap(imageZoomCursor);
904 QCursor zoomCursor(zoomPixmap);
905 if (setTransformRequested(ZOOMVIEW))
906 myViewPort->setCursor(zoomCursor);
910 bool XGUI_ViewWindow::transformRequested() const
912 return (myOperation != NOTHING);
916 \brief Start delayed viewer operation.
918 bool XGUI_ViewWindow::setTransformRequested(OperationType op)
920 bool ok = transformEnabled(op);
921 myOperation = ok ? op : NOTHING;
922 myViewPort->setMouseTracking(myOperation == NOTHING);
927 Set enabled state of transformation (rotate, zoom, etc)
929 void XGUI_ViewWindow::setTransformEnabled(const OperationType id, const bool on)
932 myStatus.insert(id, on);
936 \return enabled state of transformation (rotate, zoom, etc)
938 bool XGUI_ViewWindow::transformEnabled(const OperationType id) const
940 return myStatus.contains(id) ? myStatus[id] : true;
944 \brief Start panning operation.
946 Sets the corresponding cursor for the widget.
948 void XGUI_ViewWindow::activatePanning()
950 if (!transformRequested() && !myCursorIsHand)
951 myCursor = cursor(); // save old cursor
953 if (myOperation != PANVIEW) {
954 QCursor panCursor(Qt::SizeAllCursor);
955 if (setTransformRequested(PANVIEW))
956 myViewPort->setCursor(panCursor);
961 \brief Start global panning operation
963 Sets the corresponding cursor for the widget.
965 void XGUI_ViewWindow::activateGlobalPanning()
967 Handle(V3d_View) aView3d = myViewPort->getView();
968 if (!aView3d.IsNull()) {
969 QPixmap globalPanPixmap(imageCrossCursor);
970 QCursor glPanCursor(globalPanPixmap);
971 myCurScale = aView3d->Scale();
972 aView3d->FitAll(0.01, false);
973 myCursor = cursor(); // save old cursor
974 myViewPort->fitAll(); // fits view before selecting a new scene center
975 if (setTransformRequested(PANGLOBAL))
976 myViewPort->setCursor(glPanCursor);
981 \brief Start rotation operation
983 Sets the corresponding cursor for the widget.
985 void XGUI_ViewWindow::activateRotation()
987 if (!transformRequested() && !myCursorIsHand)
988 myCursor = cursor(); // save old cursor
990 if (myOperation != ROTATE) {
991 QPixmap rotatePixmap(imageRotateCursor);
992 QCursor rotCursor(rotatePixmap);
993 if (setTransformRequested(ROTATE))
994 myViewPort->setCursor(rotCursor);
999 \brief Reset the viewport to its initial state
1000 ( no transformations in process etc. )
1002 void XGUI_ViewWindow::resetState()
1006 if (myRotationPointSelection) {
1007 QCursor handCursor(Qt::PointingHandCursor);
1008 myViewPort->setCursor(handCursor);
1010 if (transformRequested() || myCursorIsHand)
1011 myViewPort->setCursor(myCursor);
1012 myCursorIsHand = false;
1015 if (transformRequested())
1016 emit vpTransformationFinished(myOperation);
1018 setTransformInProcess(false);
1019 setTransformRequested(NOTHING);
1022 Qtx::BackgroundData XGUI_ViewWindow::background() const
1024 return myViewPort ? myViewPort->background() : Qtx::BackgroundData();
1027 void XGUI_ViewWindow::setBackground(const Qtx::BackgroundData& theBackground)
1030 myViewPort->setBackground(theBackground);
1034 \brief Create one more window with same content.
1036 void XGUI_ViewWindow::cloneView()
1038 QMdiSubWindow* vw = myViewer->createView();
1039 XGUI_ViewWindow* aNewWnd = static_cast<XGUI_ViewWindow*>(vw->widget());
1040 aNewWnd->viewPort()->syncronizeWith(myViewPort);
1042 emit viewCloned(vw);
1044 // In order to avoid frosen background in toolbars when it shown as a second view
1045 QTimer::singleShot(20, vw, SLOT(setFocus()));
1048 void XGUI_ViewWindow::dumpView()
1050 QString aFilter(tr("Images Files (*.bmp *.png *.jpg *.jpeg *.eps *.ps)"));
1051 QString aSelectedFilter;
1052 QString aFileName = QFileDialog::getSaveFileName(this, "Save picture", QString(), aFilter,
1054 if (!aFileName.isNull()) {
1055 QApplication::setOverrideCursor(Qt::WaitCursor);
1056 unsigned char* aData = 0;
1057 QImage aPicture = myViewPort->dumpView(aData);
1059 QString aFmt = XGUI_Tools::extension(aFileName).toUpper();
1061 aFmt = QString("BMP"); // default format
1062 else if (aFmt == "JPG")
1065 Handle(Visual3d_View) a3dView = myViewPort->getView()->View();
1068 a3dView->Export(_strdup(qPrintable(aFileName)), Graphic3d_EF_PostScript);
1070 a3dView->Export(strdup(qPrintable(aFileName)), Graphic3d_EF_PostScript);
1072 else if (aFmt == "EPS")
1074 a3dView->Export(_strdup(qPrintable(aFileName)), Graphic3d_EF_EnhPostScript);
1076 a3dView->Export(strdup(qPrintable(aFileName)), Graphic3d_EF_EnhPostScript);
1079 aPicture.save(aFileName, aFmt.toLatin1());
1081 QApplication::restoreOverrideCursor();
1085 void XGUI_ViewWindow::fitAll()
1087 emit vpTransformationStarted(FITALLVIEW);
1088 myViewPort->fitAll();
1089 emit vpTransformationFinished(FITALLVIEW);
1093 \brief Starts fit operation.
1095 Sets the corresponding cursor for the widget.
1097 void XGUI_ViewWindow::activateWindowFit()
1099 if (!transformRequested() && !myCursorIsHand)
1100 myCursor = cursor(); /* save old cursor */
1102 if (myOperation != WINDOWFIT) {
1103 QCursor handCursor(Qt::PointingHandCursor);
1104 if (setTransformRequested(WINDOWFIT)) {
1105 myViewPort->setCursor(handCursor);
1106 myCursorIsHand = true;
1112 \brief Perform "front view" transformation.
1114 void XGUI_ViewWindow::frontView()
1116 emit vpTransformationStarted(FRONTVIEW);
1117 Handle(V3d_View) aView3d = myViewPort->getView();
1118 if (!aView3d.IsNull())
1119 aView3d->SetProj(V3d_Xpos);
1120 myViewPort->fitAll();
1121 emit vpTransformationFinished(FRONTVIEW);
1125 \brief Perform "back view" transformation.
1127 void XGUI_ViewWindow::backView()
1129 emit vpTransformationStarted(BACKVIEW);
1130 Handle(V3d_View) aView3d = myViewPort->getView();
1131 if (!aView3d.IsNull())
1132 aView3d->SetProj(V3d_Xneg);
1133 myViewPort->fitAll();
1134 emit vpTransformationFinished(BACKVIEW);
1138 \brief Perform "top view" transformation.
1140 void XGUI_ViewWindow::topView()
1142 emit vpTransformationStarted(TOPVIEW);
1143 Handle(V3d_View) aView3d = myViewPort->getView();
1144 if (!aView3d.IsNull())
1145 aView3d->SetProj(V3d_Zpos);
1146 myViewPort->fitAll();
1147 emit vpTransformationFinished(TOPVIEW);
1151 \brief Perform "bottom view" transformation.
1153 void XGUI_ViewWindow::bottomView()
1155 emit vpTransformationStarted(BOTTOMVIEW);
1156 Handle(V3d_View) aView3d = myViewPort->getView();
1157 if (!aView3d.IsNull())
1158 aView3d->SetProj(V3d_Zneg);
1159 myViewPort->fitAll();
1160 emit vpTransformationFinished(BOTTOMVIEW);
1164 \brief Perform "left view" transformation.
1166 void XGUI_ViewWindow::leftView()
1168 emit vpTransformationStarted(LEFTVIEW);
1169 Handle(V3d_View) aView3d = myViewPort->getView();
1170 if (!aView3d.IsNull())
1171 aView3d->SetProj(V3d_Yneg);
1172 myViewPort->fitAll();
1173 emit vpTransformationFinished(LEFTVIEW);
1177 \brief Perform "right view" transformation.
1179 void XGUI_ViewWindow::rightView()
1181 emit vpTransformationStarted(RIGHTVIEW);
1182 Handle(V3d_View) aView3d = myViewPort->getView();
1183 if (!aView3d.IsNull())
1184 aView3d->SetProj(V3d_Ypos);
1185 myViewPort->fitAll();
1186 emit vpTransformationFinished(RIGHTVIEW);
1189 void XGUI_ViewWindow::reset()
1191 emit vpTransformationStarted(RESETVIEW);
1192 bool upd = myViewPort->getView()->SetImmediateUpdate(false);
1193 myViewPort->getView()->Reset(false);
1194 myViewPort->fitAll(false, true, false);
1195 myViewPort->getView()->SetImmediateUpdate(upd);
1196 myViewPort->getView()->Update();
1197 emit vpTransformationFinished(RESETVIEW);
1200 void XGUI_ViewWindow::updateToolBar()
1202 myGripWgt->update();
1203 myViewBar->update();
1204 myWindowBar->update();
1208 \brief Update state of enable draw mode state.
1210 void XGUI_ViewWindow::updateEnabledDrawMode()
1212 myEnableDrawMode = myViewer->isSelectionEnabled() && myViewer->isMultiSelectionEnabled();