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 "................................", "................................" };
82 ViewerToolbar::ViewerToolbar(QWidget* theParent, XGUI_ViewPort* thePort)
83 : QToolBar(theParent), myVPort(thePort), myResize(false)
85 connect(myVPort, SIGNAL(resized()), this, SLOT(onViewPortResized()));
88 void ViewerToolbar::paintEvent(QPaintEvent* theEvent)
90 //QToolBar::paintEvent(theEvent);
92 QPainter aPainter(this);
94 QRect aVPRect = myVPort->rect();
95 QPoint aGlobPnt = mapToGlobal(aRect.topLeft());
96 QPoint aPnt = myVPort->mapFromGlobal(aGlobPnt);
98 QRect aImgRect(QRect(aPnt.x(), aPnt.y() + aVPRect.height() - aRect.height(),
99 aRect.width(), aRect.height()));
100 QImage aImg = myVPort->dumpView(aImgRect, myResize);
102 aPainter.drawImage(aRect, aImg);
106 QStyle *style = this->style();
107 QStyleOptionToolBar aOpt;
108 initStyleOption(&aOpt);
110 aOpt.rect = style->subElementRect(QStyle::SE_ToolBarHandle, &aOpt, this);
111 if (aOpt.rect.isValid())
112 style->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &aOpt, &aPainter, this);
117 //**************************************************************************
118 ViewerLabel::ViewerLabel(QWidget* theParent, XGUI_ViewPort* thePort)
119 : QLabel(theParent), myVPort(thePort), myResize(false)
121 connect(myVPort, SIGNAL(resized()), this, SLOT(onViewPortResized()));
124 void ViewerLabel::paintEvent(QPaintEvent* theEvent)
126 QRect aRect = rect();
127 QRect aVPRect = myVPort->rect();
128 QPoint aGlobPnt = mapToGlobal(aRect.topLeft());
129 QPoint aPnt = myVPort->mapFromGlobal(aGlobPnt);
131 QRect aImgRect(QRect(aPnt.x(), aPnt.y() + aVPRect.height() - aRect.height(),
132 aRect.width(), aRect.height()));
133 QImage aImg = myVPort->dumpView(aImgRect, myResize);
135 QPainter(this).drawImage(aRect, aImg);
137 QLabel::paintEvent(theEvent);
140 //**************************************************************************
141 //**************************************************************************
142 //**************************************************************************
143 XGUI_ViewWindow::XGUI_ViewWindow(XGUI_Viewer* theViewer, V3d_TypeOfView theType)
147 MinimizeIco(":pictures/wnd_minimize.png"),
148 MaximizeIco(":pictures/wnd_maximize.png"),
149 CloseIco(":pictures/wnd_close.png"),
150 RestoreIco(":pictures/wnd_restore.png"),
151 myInteractionStyle(XGUI::STANDARD),
154 my2dMode(XGUI::No2dMode),
155 myCurrPointType(XGUI::GRAVITY),
156 myPrevPointType(XGUI::GRAVITY),
157 myRotationPointSelection(false),
159 myStartX(0), myStartY(0), myCurrX(0), myCurrY(0), myCurScale(0.0), myCurSketch(0),
160 myDrawRect(false), myEnableDrawMode(false), myCursorIsHand(false), myEventStarted(false),
162 myLastState(WindowNormalState), myOperation(NOTHING)
164 mySelectedPoint = gp_Pnt(0., 0., 0.);
165 setFrameStyle(QFrame::Raised);
166 setFrameShape(QFrame::Panel);
167 setLineWidth(BORDER_SIZE);
168 setMouseTracking(true);
170 QVBoxLayout* aLay = new QVBoxLayout(this);
171 aLay->setContentsMargins(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE);
172 myViewPort = new XGUI_ViewPort(this, myViewer->v3dViewer(), theType);
173 myViewPort->installEventFilter(this);
174 myViewPort->setCursor(Qt::ArrowCursor);
175 aLay->addWidget(myViewPort);
177 myPicture = new QLabel(this);
178 myPicture->setFrameStyle(QFrame::Sunken);
179 myPicture->setFrameShape(QFrame::Panel);
180 myPicture->setMouseTracking(true);
181 myPicture->installEventFilter(this);
182 aLay->addWidget(myPicture);
185 QVBoxLayout* aVPLay = new QVBoxLayout(myViewPort);
186 aVPLay->setMargin(0);
187 aVPLay->setSpacing(0);
188 aVPLay->setContentsMargins(0,0,0,0);
190 QHBoxLayout* aToolLay = new QHBoxLayout();
191 aToolLay->setMargin(0);
192 aToolLay->setSpacing(0);
193 aToolLay->setContentsMargins(0,0,0,0);
194 aVPLay->addLayout(aToolLay);
195 aVPLay->addStretch();
197 myGripWgt = new ViewerLabel(this, myViewPort);
198 myGripWgt->setPixmap(QPixmap(":pictures/wnd_grip.png"));
199 myGripWgt->setMouseTracking(true);
200 myGripWgt->installEventFilter(this);
201 myGripWgt->setCursor(Qt::OpenHandCursor);
202 aToolLay->addWidget(myGripWgt);
204 // Create Viewer management buttons
205 myViewBar = new ViewerToolbar(this, myViewPort);
206 myViewBar->setCursor(Qt::PointingHandCursor);
207 aToolLay->addWidget(myViewBar);
208 aToolLay->addStretch();
213 aBtn = new QAction(QIcon(":pictures/occ_view_camera_dump.png"), tr("Dump view"), myViewBar);
214 connect(aBtn, SIGNAL(triggered()), SLOT(dumpView()));
215 myViewBar->addAction(aBtn);
217 aBtn = new QAction(QIcon(":pictures/occ_view_fitall.png"), tr("Fit all"), myViewBar);
218 connect(aBtn, SIGNAL(triggered()), SLOT(fitAll()));
219 myViewBar->addAction(aBtn);
221 aBtn = new QAction(QIcon(":pictures/occ_view_fitarea.png"), tr("Fit area"), myViewBar);
222 connect(aBtn, SIGNAL(triggered()), SLOT(activateWindowFit()));
223 myViewBar->addAction(aBtn);
225 aBtn = new QAction(QIcon(":pictures/occ_view_zoom.png"), tr("Zoom"), myViewBar);
226 connect(aBtn, SIGNAL(triggered()), SLOT(activateZoom()));
227 myViewBar->addAction(aBtn);
229 aBtn = new QAction(QIcon(":pictures/occ_view_pan.png"), tr("Panning"), myViewBar);
230 connect(aBtn, SIGNAL(triggered()), SLOT(activatePanning()));
231 myViewBar->addAction(aBtn);
233 aBtn = new QAction(QIcon(":pictures/occ_view_glpan.png"), tr("Global panning"), myViewBar);
234 connect(aBtn, SIGNAL(triggered()), SLOT(activateGlobalPanning()));
235 myViewBar->addAction(aBtn);
237 aBtn = new QAction(QIcon(":pictures/occ_view_rotate.png"), tr("Rotate"), myViewBar);
238 connect(aBtn, SIGNAL(triggered()), SLOT(activateRotation()));
239 myViewBar->addAction(aBtn);
241 aBtn = new QAction(QIcon(":pictures/occ_view_reset.png"), tr("Reset"), myViewBar);
242 connect(aBtn, SIGNAL(triggered()), SLOT(reset()));
243 myViewBar->addAction(aBtn);
245 aBtn = new QAction(QIcon(":pictures/occ_view_front.png"), tr("Front"), myViewBar);
246 connect(aBtn, SIGNAL(triggered()), SLOT(frontView()));
247 myViewBar->addAction(aBtn);
249 aBtn = new QAction(QIcon(":pictures/occ_view_back.png"), tr("Back"), myViewBar);
250 connect(aBtn, SIGNAL(triggered()), SLOT(backView()));
251 myViewBar->addAction(aBtn);
253 aBtn = new QAction(QIcon(":pictures/occ_view_top.png"), tr("Top"), myViewBar);
254 connect(aBtn, SIGNAL(triggered()), SLOT(topView()));
255 myViewBar->addAction(aBtn);
257 aBtn = new QAction(QIcon(":pictures/occ_view_bottom.png"), tr("Bottom"), myViewBar);
258 connect(aBtn, SIGNAL(triggered()), SLOT(bottomView()));
259 myViewBar->addAction(aBtn);
261 aBtn = new QAction(QIcon(":pictures/occ_view_left.png"), tr("Left"), myViewBar);
262 connect(aBtn, SIGNAL(triggered()), SLOT(leftView()));
263 myViewBar->addAction(aBtn);
265 aBtn = new QAction(QIcon(":pictures/occ_view_right.png"), tr("Right"), myViewBar);
266 connect(aBtn, SIGNAL(triggered()), SLOT(rightView()));
267 myViewBar->addAction(aBtn);
269 aBtn = new QAction(QIcon(":pictures/occ_view_clone.png"), tr("Clone"), myViewBar);
270 connect(aBtn, SIGNAL(triggered()), SLOT(cloneView()));
271 myViewBar->addAction(aBtn);
273 // Create Window management buttons
274 myWindowBar = new ViewerToolbar(this, myViewPort);
275 myWindowBar->setCursor(Qt::PointingHandCursor);
276 aToolLay->addWidget(myWindowBar);
278 myMinimizeBtn = new QAction(myWindowBar);
279 myMinimizeBtn->setIcon(MinimizeIco);
280 myWindowBar->addAction(myMinimizeBtn);
281 connect(myMinimizeBtn, SIGNAL(triggered()), SLOT(onMinimize()));
283 myMaximizeBtn = new QAction(myWindowBar);
284 myMaximizeBtn->setIcon(MaximizeIco);
285 myWindowBar->addAction(myMaximizeBtn);
286 connect(myMaximizeBtn, SIGNAL(triggered()), SLOT(onMaximize()));
288 aBtn = new QAction(myWindowBar);
289 aBtn->setIcon(CloseIco);
290 myWindowBar->addAction(aBtn);
291 connect(aBtn, SIGNAL(triggered()), SLOT(onClose()));
293 //Support copy of background on updating of viewer
294 connect(myViewPort, SIGNAL(vpTransformed()), this, SLOT(updateToolBar()));
295 connect(myViewPort, SIGNAL(vpUpdated()), this, SLOT(updateToolBar()));
296 connect(this, SIGNAL(vpTransformationFinished(XGUI_ViewWindow::OperationType)),
297 this, SLOT(updateToolBar()));
301 //****************************************************************
302 XGUI_ViewWindow::~XGUI_ViewWindow()
307 //****************************************************************
308 void XGUI_ViewWindow::showEvent(QShowEvent* theEvent)
310 QFrame::showEvent(theEvent);
311 myWindowBar->setFixedSize(myWindowBar->sizeHint());
314 //****************************************************************
315 void XGUI_ViewWindow::changeEvent(QEvent* theEvent)
318 if (theEvent->type() == QEvent::WindowStateChange) {
320 if (myPicture->isHidden()) {
328 if (myPicture->isVisible()) {
333 myMinimizeBtn->setIcon(MinimizeIco);
334 myMaximizeBtn->setIcon(RestoreIco);
336 myViewBar->setVisible(myIsActive);
337 myWindowBar->setVisible(myIsActive);
338 myGripWgt->setVisible(myIsActive && (!isMaximized()));
341 QWidget::changeEvent(theEvent);
346 //****************************************************************
347 void XGUI_ViewWindow::windowActivated()
349 if (!(isMinimized() || parentWidget()->isMinimized())) {
351 if (isMaximized() || parentWidget()->isMaximized()) {
352 myMaximizeBtn->setIcon(RestoreIco);
354 myMaximizeBtn->setIcon(MaximizeIco);
358 myGripWgt->setVisible(!(isMaximized() || isMinimized() ||
359 parentWidget()->isMaximized() || parentWidget()->isMinimized()));
364 //****************************************************************
365 void XGUI_ViewWindow::windowDeactivated()
368 if (!(isMinimized() || parentWidget()->isMinimized())) {
369 if (isMaximized() || parentWidget()->isMaximized()) {
370 myMaximizeBtn->setIcon(RestoreIco);
372 myMaximizeBtn->setIcon(MaximizeIco);
381 //****************************************************************
382 void XGUI_ViewWindow::onClose()
384 if (parentWidget()) {
385 emit tryClosing(this);
387 emit closed(static_cast<QMdiSubWindow*>(parentWidget()));
388 parentWidget()->close();
393 //****************************************************************
394 void XGUI_ViewWindow::onMinimize()
396 QPixmap aPMap = QPixmap::fromImage(myViewPort->dumpView());
399 double aR = aW / 100.;
400 int aNewH = int(aH / aR);
401 myPicture->setPixmap(aPMap.scaled(100, aNewH));
403 myLastState = (isMaximized() || parentWidget()->isMaximized()) ? MaximizedState : WindowNormalState;
405 parentWidget()->showMinimized();
406 parentWidget()->setGeometry(parentWidget()->x(), parentWidget()->y(), 100, aNewH);
407 parentWidget()->lower();
409 myViewer->onWindowMinimized((QMdiSubWindow*)parentWidget());
412 //****************************************************************
413 void XGUI_ViewWindow::onMaximize()
415 if (isMaximized() || parentWidget()->isMaximized()) {
416 myMaximizeBtn->setIcon(MaximizeIco);
419 parentWidget()->showNormal();
421 myMaximizeBtn->setIcon(RestoreIco);
424 parentWidget()->showMaximized();
426 parentWidget()->activateWindow();
427 myMinimizeBtn->setIcon(MinimizeIco);
429 // In order to avoid frosen background in toolbars when it shown as a second view
430 QTimer::singleShot(50, parentWidget(), SLOT(setFocus()));
433 //****************************************************************
434 bool XGUI_ViewWindow::processWindowControls(QObject *theObj, QEvent *theEvent)
436 switch(theEvent->type()) {
437 case QEvent::MouseButtonPress: {
438 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
439 if ((aEvent->button() == Qt::LeftButton) && (!myMoving)) {
441 myMousePnt = aEvent->globalPos();
446 case QEvent::MouseButtonRelease: {
447 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
448 if ((aEvent->button() == Qt::LeftButton) && myMoving) {
454 case QEvent::MouseMove: {
455 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
457 QMdiSubWindow* aParent = static_cast<QMdiSubWindow*>(parentWidget());
458 QMdiArea* aMDIArea = aParent->mdiArea();
460 QPoint aPnt = aEvent->globalPos();
461 QPoint aMDIPnt = aMDIArea->mapFromGlobal(aPnt);
462 if (aMDIArea->rect().contains(aMDIPnt)) {
463 int aX = aParent->x() + (aPnt.x() - myMousePnt.x());
464 int aY = aParent->y() + (aPnt.y() - myMousePnt.y());
465 aParent->move(aX, aY);
472 case QEvent::MouseButtonDblClick:
473 if (theObj == myPicture) {
475 if (myLastState == MaximizedState) {
480 myViewer->onWindowActivated((QMdiSubWindow*)parentWidget());
482 // In order to avoid frosen background in toolbars when it shown as a second view
483 QTimer::singleShot(20, parentWidget(), SLOT(setFocus()));
491 //****************************************************************
492 bool XGUI_ViewWindow::processViewPort(QEvent *theEvent)
494 switch(theEvent->type()) {
495 case QEvent::MouseButtonPress:
496 vpMousePressEvent((QMouseEvent*) theEvent);
499 case QEvent::MouseButtonRelease:
500 vpMouseReleaseEvent((QMouseEvent*) theEvent);
503 case QEvent::MouseMove:
504 vpMouseMoveEvent((QMouseEvent*) theEvent);
507 case QEvent::MouseButtonDblClick:
508 emit mouseDoubleClicked(this, (QMouseEvent*) theEvent);
512 QWheelEvent* aEvent = (QWheelEvent*) theEvent;
513 myViewPort->startZoomAtPoint( aEvent->x(), aEvent->y() );
514 double aDelta = (double)( aEvent->delta() ) / ( 15 * 8 );
517 int x1 = (int)( aEvent->x() + width()*aDelta/100 );
518 int y1 = (int)( aEvent->y() + height()*aDelta/100 );
519 myViewPort->zoom( x, y, x1, y1 );
526 //****************************************************************
527 bool XGUI_ViewWindow::eventFilter(QObject *theObj, QEvent *theEvent)
529 if ((theObj == myGripWgt) || (theObj == myPicture)) {
530 if (processWindowControls(theObj, theEvent))
532 } else if (theObj == myViewPort) {
533 if (processViewPort(theEvent)) {
536 if (theEvent->type() == QEvent::KeyRelease) {
537 emit keyReleased(this, (QKeyEvent*) theEvent);
541 return QFrame::eventFilter(theObj, theEvent);
544 //****************************************************************
545 XGUI_ViewWindow::OperationType XGUI_ViewWindow::getButtonState(
546 QMouseEvent* theEvent, XGUI::InteractionStyle theInteractionStyle)
548 OperationType aOp = NOTHING;
549 XGUI::InteractionStyle aStyle = (XGUI::InteractionStyle) theInteractionStyle;
550 if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ZOOM])
551 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ZOOM]))
553 else if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::PAN])
554 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::PAN]))
556 else if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ROTATE])
557 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ROTATE])
558 && (my2dMode == XGUI::No2dMode))
564 //****************************************************************
565 void XGUI_ViewWindow::vpMousePressEvent(QMouseEvent* theEvent)
567 myStartX = theEvent->x();
568 myStartY = theEvent->y();
569 XGUI::InteractionStyle anInteractionStyle = interactionStyle();
571 // in "key free" interaction style zoom operation is activated by two buttons (simultaneously pressed),
572 // which are assigned for pan and rotate - these operations are activated immediately after pressing
573 // of the first button, so it is necessary to switch to zoom when the second button is pressed
574 bool aSwitchToZoom = false;
575 if ((anInteractionStyle == XGUI::KEY_FREE) && (myOperation == PANVIEW || myOperation == ROTATE)) {
576 aSwitchToZoom = getButtonState(theEvent, anInteractionStyle) == ZOOMVIEW;
579 switch(myOperation) {
581 if (theEvent->button() == Qt::LeftButton)
582 emit vpTransformationStarted(WINDOWFIT);
586 if (theEvent->button() == Qt::LeftButton)
587 emit vpTransformationStarted(PANGLOBAL);
591 if (theEvent->button() == Qt::LeftButton) {
592 myViewPort->startZoomAtPoint(myStartX, myStartY);
593 emit vpTransformationStarted(ZOOMVIEW);
599 myViewPort->startZoomAtPoint(myStartX, myStartY);
601 } else if (theEvent->button() == Qt::LeftButton)
602 emit vpTransformationStarted(PANVIEW);
607 myViewPort->startZoomAtPoint(myStartX, myStartY);
609 } else if (theEvent->button() == Qt::LeftButton) {
610 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
611 emit vpTransformationStarted(ROTATE);
616 /* Try to activate a transformation */
617 OperationType aState;
618 if (interactionStyle() == XGUI::STANDARD)
619 aState = getButtonState(theEvent, anInteractionStyle);
621 aState = XGUI_ViewWindow::NOTHING;
626 myViewPort->startZoomAtPoint(myStartX, myStartY);
634 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
637 if (myRotationPointSelection) {
638 if (theEvent->button() == Qt::LeftButton) {
639 Handle(AIS_InteractiveContext) ic = myViewer->AISContext();
641 for(ic->InitSelected(); ic->MoreSelected(); ic->NextSelected()) {
642 TopoDS_Shape aShape = ic->SelectedShape();
643 if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) {
644 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(ic->SelectedShape()));
645 /*if ( mySetRotationPointDlg ) {
646 myRotationPointSelection = false;
647 mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z());
650 myCurrPointType = myPrevPointType;
654 if (ic->NbSelected() == 0)
655 myCurrPointType = myPrevPointType;
656 //if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange();
657 ic->CloseAllContexts();
658 myOperation = NOTHING;
659 myViewPort->setCursor(myCursor);
660 myCursorIsHand = false;
661 myRotationPointSelection = false;
664 emit mousePressed(this, theEvent);
667 /* notify that we start a transformation */
668 if (transformRequested())
669 emit vpTransformationStarted(myOperation);
671 if (transformRequested())
672 setTransformInProcess(true);
674 /* we may need it for sketching... */
675 /* if ( l_mbPressEvent )
676 delete l_mbPressEvent;
677 l_mbPressEvent = new QMouseEvent( *theEvent );*/
680 //****************************************************************
681 void XGUI_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
683 switch(myOperation) {
685 int prevState = myCurSketch;
686 /* if(theEvent->button() == Qt::RightButton) {
687 QList<OCCViewer_ViewSketcher*>::Iterator it;
688 for ( it = mySketchers.begin(); it != mySketchers.end() && myCurSketch != -1; ++it ) {
689 OCCViewer_ViewSketcher* sk = (*it);
690 if( ( sk->sketchButton() & theEvent->button() ) && sk->sketchButton() == myCurSketch )
695 emit mouseReleased(this, theEvent);
696 if (theEvent->button() == Qt::RightButton && prevState == -1) {
697 QContextMenuEvent aEvent(QContextMenuEvent::Mouse, theEvent->pos(), theEvent->globalPos());
698 emit contextMenuRequested(&aEvent);
703 myViewPort->endRotation();
713 if (theEvent->button() == Qt::LeftButton) {
714 myViewPort->setCenter(theEvent->x(), theEvent->y());
715 myViewPort->getView()->SetScale(myCurScale);
721 if (theEvent->button() == Qt::LeftButton) {
722 myCurrX = theEvent->x();
723 myCurrY = theEvent->y();
725 QRect rect = makeRect(myStartX, myStartY, myCurrX, myCurrY);
727 myViewPort->fitRect(rect);
734 // NOTE: viewer 3D detects a rectangle of selection using this event
735 // so we must emit it BEFORE resetting the selection rectangle
736 if (theEvent->button() == Qt::LeftButton && myDrawRect) {
740 myViewPort->update();
742 /* if ( l_mbPressEvent ) {
743 delete l_mbPressEvent;
748 //****************************************************************
749 void XGUI_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent)
751 if (myIsKeyFree && interactionStyle() == XGUI::KEY_FREE) {
753 switch(getButtonState(theEvent, interactionStyle())) {
755 myViewPort->startZoomAtPoint(myStartX, myStartY);
763 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
770 myCurrX = theEvent->x();
771 myCurrY = theEvent->y();
772 switch(myOperation) {
774 myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint);
778 myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY);
784 myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY);
793 if (myRotationPointSelection /*|| isSketcherStyle()*/) {
794 emit mouseMoving(this, theEvent);
796 int aState = theEvent->modifiers();
797 int aButton = theEvent->buttons();
798 int anInteractionStyle = interactionStyle();
799 if (((anInteractionStyle == XGUI::STANDARD) && (aButton == Qt::LeftButton)
800 && (aState == Qt::NoModifier || Qt::ShiftModifier))
801 || ((anInteractionStyle == XGUI::KEY_FREE) && (aButton == Qt::LeftButton)
802 && (aState == Qt::ControlModifier
803 || aState == (Qt::ControlModifier | Qt::ShiftModifier)))) {
804 myDrawRect = myEnableDrawMode;
807 if (!myCursorIsHand) { // we are going to sketch a rectangle
808 QCursor handCursor(Qt::PointingHandCursor);
809 myCursorIsHand = true;
811 myViewPort->setCursor(handCursor);
814 emit mouseMoving(this, theEvent);
815 } /* else if ( ( (anInteractionStyle == XGUI::STANDARD) &&
816 (aButton == Qt::RightButton) &&
817 ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) ||
818 ( (anInteractionStyle == XGUI::KEY_FREE) &&
819 (aButton == Qt::RightButton) &&
820 ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) {
821 OCCViewer_ViewSketcher* sketcher = 0;
822 QList<OCCViewer_ViewSketcher*>::Iterator it;
823 for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) {
824 OCCViewer_ViewSketcher* sk = (*it);
825 if( sk->isDefault() && sk->sketchButton() == aButton )
828 if ( sketcher && myCurSketch == -1 ) {
829 activateSketching( sketcher->type() );
831 myCurSketch = mypSketcher->sketchButton();
833 if ( l_mbPressEvent ) {
834 QApplication::sendEvent( getViewPort(), l_mbPressEvent );
835 delete l_mbPressEvent;
838 QApplication::sendEvent( getViewPort(), theEvent );
842 emit mouseMoving(this, theEvent);
848 \brief Draw rubber band rectangle.
850 void XGUI_ViewWindow::drawRect()
853 myRectBand = new XGUI_RectRubberBand(myViewPort);
856 myRectBand->setUpdatesEnabled(false);
857 QRect aRect = makeRect(myStartX, myStartY, myCurrX, myCurrY);
858 myRectBand->initGeometry(aRect);
860 if (!myRectBand->isVisible())
863 myRectBand->setUpdatesEnabled(true);
867 \brief Clear rubber band rectangle on the end on the dragging operation.
869 void XGUI_ViewWindow::endDrawRect()
872 myRectBand->clearGeometry();
877 void XGUI_ViewWindow::activateZoom()
879 if (!transformRequested() && !myCursorIsHand)
880 myCursor = cursor(); /* save old cursor */
882 if (myOperation != ZOOMVIEW) {
883 QPixmap zoomPixmap(imageZoomCursor);
884 QCursor zoomCursor(zoomPixmap);
885 if (setTransformRequested(ZOOMVIEW))
886 myViewPort->setCursor(zoomCursor);
890 bool XGUI_ViewWindow::transformRequested() const
892 return (myOperation != NOTHING);
896 \brief Start delayed viewer operation.
898 bool XGUI_ViewWindow::setTransformRequested(OperationType op)
900 bool ok = transformEnabled(op);
901 myOperation = ok ? op : NOTHING;
902 myViewPort->setMouseTracking(myOperation == NOTHING);
907 Set enabled state of transformation (rotate, zoom, etc)
909 void XGUI_ViewWindow::setTransformEnabled(const OperationType id, const bool on)
912 myStatus.insert(id, on);
916 \return enabled state of transformation (rotate, zoom, etc)
918 bool XGUI_ViewWindow::transformEnabled(const OperationType id) const
920 return myStatus.contains(id) ? myStatus[id] : true;
924 \brief Start panning operation.
926 Sets the corresponding cursor for the widget.
928 void XGUI_ViewWindow::activatePanning()
930 if (!transformRequested() && !myCursorIsHand)
931 myCursor = cursor(); // save old cursor
933 if (myOperation != PANVIEW) {
934 QCursor panCursor(Qt::SizeAllCursor);
935 if (setTransformRequested(PANVIEW))
936 myViewPort->setCursor(panCursor);
941 \brief Start global panning operation
943 Sets the corresponding cursor for the widget.
945 void XGUI_ViewWindow::activateGlobalPanning()
947 Handle(V3d_View) aView3d = myViewPort->getView();
948 if ( !aView3d.IsNull() ) {
949 QPixmap globalPanPixmap (imageCrossCursor);
950 QCursor glPanCursor (globalPanPixmap);
951 myCurScale = aView3d->Scale();
952 aView3d->FitAll(0.01, false);
953 myCursor = cursor(); // save old cursor
954 myViewPort->fitAll(); // fits view before selecting a new scene center
955 if( setTransformRequested( PANGLOBAL ) )
956 myViewPort->setCursor( glPanCursor );
961 \brief Start rotation operation
963 Sets the corresponding cursor for the widget.
965 void XGUI_ViewWindow::activateRotation()
967 if (!transformRequested() && !myCursorIsHand)
968 myCursor = cursor(); // save old cursor
970 if (myOperation != ROTATE) {
971 QPixmap rotatePixmap(imageRotateCursor);
972 QCursor rotCursor(rotatePixmap);
973 if (setTransformRequested(ROTATE))
974 myViewPort->setCursor(rotCursor);
979 \brief Reset the viewport to its initial state
980 ( no transformations in process etc. )
982 void XGUI_ViewWindow::resetState()
986 if (myRotationPointSelection) {
987 QCursor handCursor(Qt::PointingHandCursor);
988 myViewPort->setCursor(handCursor);
990 if (transformRequested() || myCursorIsHand)
991 myViewPort->setCursor(myCursor);
992 myCursorIsHand = false;
995 if (transformRequested())
996 emit vpTransformationFinished(myOperation);
998 setTransformInProcess(false);
999 setTransformRequested(NOTHING);
1002 XGUI_ViewBackground XGUI_ViewWindow::background() const
1004 return myViewPort ? myViewPort->background() : XGUI_ViewBackground();
1007 void XGUI_ViewWindow::setBackground(const XGUI_ViewBackground& theBackground)
1010 myViewPort->setBackground( theBackground );
1014 \brief Create one more window with same content.
1016 void XGUI_ViewWindow::cloneView()
1018 QMdiSubWindow* vw = myViewer->createView();
1019 XGUI_ViewWindow* aNewWnd = static_cast<XGUI_ViewWindow*>(vw->widget());
1020 aNewWnd->viewPort()->syncronizeWith(myViewPort);
1022 emit viewCloned( vw );
1024 // In order to avoid frosen background in toolbars when it shown as a second view
1025 QTimer::singleShot(20, vw, SLOT(setFocus()));
1028 void XGUI_ViewWindow::dumpView()
1030 QString aFilter(tr("Images Files (*.bmp *.png *.jpg *.jpeg *.eps *.ps)"));
1031 QString aSelectedFilter;
1032 QString aFileName = QFileDialog::getSaveFileName(this, "Save picture", QString(), aFilter, &aSelectedFilter);
1033 if (!aFileName.isNull()) {
1034 QApplication::setOverrideCursor( Qt::WaitCursor );
1035 QImage aPicture = myViewPort->dumpView();
1037 QString aFmt = extension(aFileName).toUpper();
1038 if( aFmt.isEmpty() )
1039 aFmt = QString( "BMP" ); // default format
1040 else if( aFmt == "JPG" )
1043 Handle(Visual3d_View) a3dView = myViewPort->getView()->View();
1045 a3dView->Export(strdup(qPrintable(aFileName)), Graphic3d_EF_PostScript);
1046 else if (aFmt == "EPS")
1047 a3dView->Export(strdup(qPrintable(aFileName)), Graphic3d_EF_EnhPostScript);
1049 aPicture.save( aFileName, aFmt.toLatin1() );
1050 QApplication::restoreOverrideCursor();
1054 void XGUI_ViewWindow::fitAll()
1056 emit vpTransformationStarted( FITALLVIEW );
1057 myViewPort->fitAll();
1058 emit vpTransformationFinished( FITALLVIEW );
1062 \brief Starts fit operation.
1064 Sets the corresponding cursor for the widget.
1066 void XGUI_ViewWindow::activateWindowFit()
1068 if ( !transformRequested() && !myCursorIsHand )
1069 myCursor = cursor(); /* save old cursor */
1071 if ( myOperation != WINDOWFIT ) {
1072 QCursor handCursor (Qt::PointingHandCursor);
1073 if( setTransformRequested ( WINDOWFIT ) ) {
1074 myViewPort->setCursor ( handCursor );
1075 myCursorIsHand = true;
1082 \brief Perform "front view" transformation.
1084 void XGUI_ViewWindow::frontView()
1086 emit vpTransformationStarted ( FRONTVIEW );
1087 Handle(V3d_View) aView3d = myViewPort->getView();
1088 if ( !aView3d.IsNull() )
1089 aView3d->SetProj (V3d_Xpos);
1090 myViewPort->fitAll();
1091 emit vpTransformationFinished ( FRONTVIEW );
1095 \brief Perform "back view" transformation.
1097 void XGUI_ViewWindow::backView()
1099 emit vpTransformationStarted ( BACKVIEW );
1100 Handle(V3d_View) aView3d = myViewPort->getView();
1101 if ( !aView3d.IsNull() )
1102 aView3d->SetProj (V3d_Xneg);
1103 myViewPort->fitAll();
1104 emit vpTransformationFinished ( BACKVIEW );
1108 \brief Perform "top view" transformation.
1110 void XGUI_ViewWindow::topView()
1112 emit vpTransformationStarted ( TOPVIEW );
1113 Handle(V3d_View) aView3d = myViewPort->getView();
1114 if ( !aView3d.IsNull() )
1115 aView3d->SetProj (V3d_Zpos);
1116 myViewPort->fitAll();
1117 emit vpTransformationFinished ( TOPVIEW );
1121 \brief Perform "bottom view" transformation.
1123 void XGUI_ViewWindow::bottomView()
1125 emit vpTransformationStarted ( BOTTOMVIEW );
1126 Handle(V3d_View) aView3d = myViewPort->getView();
1127 if ( !aView3d.IsNull() )
1128 aView3d->SetProj (V3d_Zneg);
1129 myViewPort->fitAll();
1130 emit vpTransformationFinished ( BOTTOMVIEW );
1134 \brief Perform "left view" transformation.
1136 void XGUI_ViewWindow::leftView()
1138 emit vpTransformationStarted ( LEFTVIEW );
1139 Handle(V3d_View) aView3d = myViewPort->getView();
1140 if ( !aView3d.IsNull() )
1141 aView3d->SetProj (V3d_Yneg);
1142 myViewPort->fitAll();
1143 emit vpTransformationFinished ( LEFTVIEW );
1147 \brief Perform "right view" transformation.
1149 void XGUI_ViewWindow::rightView()
1151 emit vpTransformationStarted ( RIGHTVIEW );
1152 Handle(V3d_View) aView3d = myViewPort->getView();
1153 if ( !aView3d.IsNull() )
1154 aView3d->SetProj (V3d_Ypos);
1155 myViewPort->fitAll();
1156 emit vpTransformationFinished ( RIGHTVIEW );
1159 void XGUI_ViewWindow::reset()
1161 emit vpTransformationStarted( RESETVIEW );
1162 bool upd = myViewPort->getView()->SetImmediateUpdate( false );
1163 myViewPort->getView()->Reset( false );
1164 myViewPort->fitAll( false, true, false );
1165 myViewPort->getView()->SetImmediateUpdate( upd );
1166 myViewPort->getView()->Update();
1167 emit vpTransformationFinished( RESETVIEW );
1171 void XGUI_ViewWindow::updateToolBar()
1173 myGripWgt->update();
1174 myViewBar->update();
1175 myWindowBar->update();
1179 \brief Update state of enable draw mode state.
1181 void XGUI_ViewWindow::updateEnabledDrawMode()
1183 myEnableDrawMode = myViewer->isSelectionEnabled() &&
1184 myViewer->isMultiSelectionEnabled();