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);
115 //**************************************************************************
116 ViewerLabel::ViewerLabel(QWidget* theParent, XGUI_ViewPort* thePort)
117 : QLabel(theParent), myVPort(thePort), myResize(false)
119 connect(myVPort, SIGNAL(resized()), this, SLOT(onViewPortResized()));
122 void ViewerLabel::paintEvent(QPaintEvent* theEvent)
124 QRect aRect = rect();
125 QRect aVPRect = myVPort->rect();
126 QPoint aGlobPnt = mapToGlobal(aRect.topLeft());
127 QPoint aPnt = myVPort->mapFromGlobal(aGlobPnt);
129 QRect aImgRect(QRect(aPnt.x(), aPnt.y() + aVPRect.height() - aRect.height(),
130 aRect.width(), aRect.height()));
131 QImage aImg = myVPort->dumpView(aImgRect, myResize);
133 QPainter(this).drawImage(aRect, aImg);
134 QLabel::paintEvent(theEvent);
137 //**************************************************************************
138 //**************************************************************************
139 //**************************************************************************
140 XGUI_ViewWindow::XGUI_ViewWindow(XGUI_Viewer* theViewer, V3d_TypeOfView theType)
144 MinimizeIco(":pictures/wnd_minimize.png"),
145 MaximizeIco(":pictures/wnd_maximize.png"),
146 CloseIco(":pictures/wnd_close.png"),
147 RestoreIco(":pictures/wnd_restore.png"),
148 myInteractionStyle(XGUI::STANDARD),
151 my2dMode(XGUI::No2dMode),
152 myCurrPointType(XGUI::GRAVITY),
153 myPrevPointType(XGUI::GRAVITY),
154 myRotationPointSelection(false),
156 myStartX(0), myStartY(0), myCurrX(0), myCurrY(0), myCurScale(0.0), myCurSketch(0),
157 myDrawRect(false), myEnableDrawMode(true), myCursorIsHand(false), myEventStarted(false),
159 myLastState(WindowNormalState), myOperation(NOTHING)
161 mySelectedPoint = gp_Pnt(0., 0., 0.);
162 setFrameStyle(QFrame::Raised);
163 setFrameShape(QFrame::Panel);
164 setLineWidth(BORDER_SIZE);
165 setMouseTracking(true);
167 QVBoxLayout* aLay = new QVBoxLayout(this);
168 aLay->setContentsMargins(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE);
169 myViewPort = new XGUI_ViewPort(this, myViewer->v3dViewer(), theType);
170 myViewPort->installEventFilter(this);
171 myViewPort->setCursor(Qt::ArrowCursor);
172 aLay->addWidget(myViewPort);
174 myPicture = new QLabel(this);
175 myPicture->setFrameStyle(QFrame::Sunken);
176 myPicture->setFrameShape(QFrame::Panel);
177 myPicture->setMouseTracking(true);
178 myPicture->installEventFilter(this);
179 aLay->addWidget(myPicture);
182 QVBoxLayout* aVPLay = new QVBoxLayout(myViewPort);
183 aVPLay->setMargin(0);
184 aVPLay->setSpacing(0);
185 aVPLay->setContentsMargins(0,0,0,0);
187 QHBoxLayout* aToolLay = new QHBoxLayout();
188 aToolLay->setMargin(0);
189 aToolLay->setSpacing(0);
190 aToolLay->setContentsMargins(0,0,0,0);
191 aVPLay->addLayout(aToolLay);
192 aVPLay->addStretch();
194 myGripWgt = new ViewerLabel(this, myViewPort);
195 myGripWgt->setPixmap(QPixmap(":pictures/wnd_grip.png"));
196 myGripWgt->setMouseTracking(true);
197 myGripWgt->installEventFilter(this);
198 myGripWgt->setCursor(Qt::OpenHandCursor);
199 aToolLay->addWidget(myGripWgt);
201 // Create Viewer management buttons
202 myViewBar = new ViewerToolbar(this, myViewPort);
203 myViewBar->setCursor(Qt::PointingHandCursor);
204 aToolLay->addWidget(myViewBar);
205 aToolLay->addStretch();
210 aBtn = new QAction(QIcon(":pictures/occ_view_camera_dump.png"), tr("Dump view"), myViewBar);
211 connect(aBtn, SIGNAL(triggered()), SLOT(dumpView()));
212 myViewBar->addAction(aBtn);
214 aBtn = new QAction(QIcon(":pictures/occ_view_fitall.png"), tr("Fit all"), myViewBar);
215 connect(aBtn, SIGNAL(triggered()), SLOT(fitAll()));
216 myViewBar->addAction(aBtn);
218 aBtn = new QAction(QIcon(":pictures/occ_view_fitarea.png"), tr("Fit area"), myViewBar);
219 connect(aBtn, SIGNAL(triggered()), SLOT(activateWindowFit()));
220 myViewBar->addAction(aBtn);
222 aBtn = new QAction(QIcon(":pictures/occ_view_zoom.png"), tr("Zoom"), myViewBar);
223 connect(aBtn, SIGNAL(triggered()), SLOT(activateZoom()));
224 myViewBar->addAction(aBtn);
226 aBtn = new QAction(QIcon(":pictures/occ_view_pan.png"), tr("Panning"), myViewBar);
227 connect(aBtn, SIGNAL(triggered()), SLOT(activatePanning()));
228 myViewBar->addAction(aBtn);
230 aBtn = new QAction(QIcon(":pictures/occ_view_glpan.png"), tr("Global panning"), myViewBar);
231 connect(aBtn, SIGNAL(triggered()), SLOT(activateGlobalPanning()));
232 myViewBar->addAction(aBtn);
234 aBtn = new QAction(QIcon(":pictures/occ_view_rotate.png"), tr("Rotate"), myViewBar);
235 connect(aBtn, SIGNAL(triggered()), SLOT(activateRotation()));
236 myViewBar->addAction(aBtn);
238 aBtn = new QAction(QIcon(":pictures/occ_view_reset.png"), tr("Reset"), myViewBar);
239 connect(aBtn, SIGNAL(triggered()), SLOT(reset()));
240 myViewBar->addAction(aBtn);
242 aBtn = new QAction(QIcon(":pictures/occ_view_front.png"), tr("Front"), myViewBar);
243 connect(aBtn, SIGNAL(triggered()), SLOT(frontView()));
244 myViewBar->addAction(aBtn);
246 aBtn = new QAction(QIcon(":pictures/occ_view_back.png"), tr("Back"), myViewBar);
247 connect(aBtn, SIGNAL(triggered()), SLOT(backView()));
248 myViewBar->addAction(aBtn);
250 aBtn = new QAction(QIcon(":pictures/occ_view_top.png"), tr("Top"), myViewBar);
251 connect(aBtn, SIGNAL(triggered()), SLOT(topView()));
252 myViewBar->addAction(aBtn);
254 aBtn = new QAction(QIcon(":pictures/occ_view_bottom.png"), tr("Bottom"), myViewBar);
255 connect(aBtn, SIGNAL(triggered()), SLOT(bottomView()));
256 myViewBar->addAction(aBtn);
258 aBtn = new QAction(QIcon(":pictures/occ_view_left.png"), tr("Left"), myViewBar);
259 connect(aBtn, SIGNAL(triggered()), SLOT(leftView()));
260 myViewBar->addAction(aBtn);
262 aBtn = new QAction(QIcon(":pictures/occ_view_right.png"), tr("Right"), myViewBar);
263 connect(aBtn, SIGNAL(triggered()), SLOT(rightView()));
264 myViewBar->addAction(aBtn);
266 aBtn = new QAction(QIcon(":pictures/occ_view_clone.png"), tr("Clone"), myViewBar);
267 connect(aBtn, SIGNAL(triggered()), SLOT(cloneView()));
268 myViewBar->addAction(aBtn);
270 // Create Window management buttons
271 myWindowBar = new ViewerToolbar(this, myViewPort);
272 myWindowBar->setCursor(Qt::PointingHandCursor);
273 aToolLay->addWidget(myWindowBar);
275 myMinimizeBtn = new QAction(myWindowBar);
276 myMinimizeBtn->setIcon(MinimizeIco);
277 myWindowBar->addAction(myMinimizeBtn);
278 connect(myMinimizeBtn, SIGNAL(triggered()), SLOT(onMinimize()));
280 myMaximizeBtn = new QAction(myWindowBar);
281 myMaximizeBtn->setIcon(MaximizeIco);
282 myWindowBar->addAction(myMaximizeBtn);
283 connect(myMaximizeBtn, SIGNAL(triggered()), SLOT(onMaximize()));
285 aBtn = new QAction(myWindowBar);
286 aBtn->setIcon(CloseIco);
287 myWindowBar->addAction(aBtn);
288 connect(aBtn, SIGNAL(triggered()), SLOT(onClose()));
290 //Support copy of background on updating of viewer
291 connect(myViewPort, SIGNAL(vpTransformed()), this, SLOT(updateToolBar()));
292 connect(myViewPort, SIGNAL(vpUpdated()), this, SLOT(updateToolBar()));
293 connect(this, SIGNAL(vpTransformationFinished(XGUI_ViewWindow::OperationType)),
294 this, SLOT(updateToolBar()));
298 //****************************************************************
299 XGUI_ViewWindow::~XGUI_ViewWindow()
304 //****************************************************************
305 void XGUI_ViewWindow::showEvent(QShowEvent* theEvent)
307 QFrame::showEvent(theEvent);
308 myWindowBar->setFixedSize(myWindowBar->sizeHint());
311 //****************************************************************
312 void XGUI_ViewWindow::changeEvent(QEvent* theEvent)
315 if (theEvent->type() == QEvent::WindowStateChange) {
317 if (myPicture->isHidden()) {
325 if (myPicture->isVisible()) {
330 myMinimizeBtn->setIcon(MinimizeIco);
331 myMaximizeBtn->setIcon(RestoreIco);
333 myViewBar->setVisible(myIsActive);
334 myWindowBar->setVisible(myIsActive);
335 myGripWgt->setVisible(myIsActive && (!isMaximized()));
338 QWidget::changeEvent(theEvent);
343 //****************************************************************
344 void XGUI_ViewWindow::windowActivated()
346 if (!(isMinimized() || parentWidget()->isMinimized())) {
348 if (isMaximized() || parentWidget()->isMaximized()) {
349 myMaximizeBtn->setIcon(RestoreIco);
351 myMaximizeBtn->setIcon(MaximizeIco);
355 myGripWgt->setVisible(!(isMaximized() || isMinimized() ||
356 parentWidget()->isMaximized() || parentWidget()->isMinimized()));
361 //****************************************************************
362 void XGUI_ViewWindow::windowDeactivated()
365 if (!(isMinimized() || parentWidget()->isMinimized())) {
366 if (isMaximized() || parentWidget()->isMaximized()) {
367 myMaximizeBtn->setIcon(RestoreIco);
369 myMaximizeBtn->setIcon(MaximizeIco);
378 //****************************************************************
379 void XGUI_ViewWindow::onClose()
381 if (parentWidget()) {
382 emit tryClosing(this);
384 emit closed(static_cast<QMdiSubWindow*>(parentWidget()));
385 parentWidget()->close();
390 //****************************************************************
391 void XGUI_ViewWindow::onMinimize()
393 QPixmap aPMap = QPixmap::fromImage(myViewPort->dumpView());
396 double aR = aW / 100.;
397 int aNewH = int(aH / aR);
398 myPicture->setPixmap(aPMap.scaled(100, aNewH));
400 myLastState = (isMaximized() || parentWidget()->isMaximized()) ? MaximizedState : WindowNormalState;
402 parentWidget()->showMinimized();
403 parentWidget()->setGeometry(parentWidget()->x(), parentWidget()->y(), 100, aNewH);
404 parentWidget()->lower();
406 myViewer->onWindowMinimized((QMdiSubWindow*)parentWidget());
409 //****************************************************************
410 void XGUI_ViewWindow::onMaximize()
412 if (isMaximized() || parentWidget()->isMaximized()) {
413 myMaximizeBtn->setIcon(MaximizeIco);
416 parentWidget()->showNormal();
418 myMaximizeBtn->setIcon(RestoreIco);
421 parentWidget()->showMaximized();
423 parentWidget()->activateWindow();
424 myMinimizeBtn->setIcon(MinimizeIco);
426 // In order to avoid frosen background in toolbars when it shown as a second view
427 QTimer::singleShot(50, parentWidget(), SLOT(setFocus()));
430 //****************************************************************
431 bool XGUI_ViewWindow::processWindowControls(QObject *theObj, QEvent *theEvent)
433 switch(theEvent->type()) {
434 case QEvent::MouseButtonPress: {
435 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
436 if ((aEvent->button() == Qt::LeftButton) && (!myMoving)) {
438 myMousePnt = aEvent->globalPos();
443 case QEvent::MouseButtonRelease: {
444 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
445 if ((aEvent->button() == Qt::LeftButton) && myMoving) {
451 case QEvent::MouseMove: {
452 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
454 QMdiSubWindow* aParent = static_cast<QMdiSubWindow*>(parentWidget());
455 QMdiArea* aMDIArea = aParent->mdiArea();
457 QPoint aPnt = aEvent->globalPos();
458 QPoint aMDIPnt = aMDIArea->mapFromGlobal(aPnt);
459 if (aMDIArea->rect().contains(aMDIPnt)) {
460 int aX = aParent->x() + (aPnt.x() - myMousePnt.x());
461 int aY = aParent->y() + (aPnt.y() - myMousePnt.y());
462 aParent->move(aX, aY);
469 case QEvent::MouseButtonDblClick:
470 if (theObj == myPicture) {
472 if (myLastState == MaximizedState) {
477 myViewer->onWindowActivated((QMdiSubWindow*)parentWidget());
479 // In order to avoid frosen background in toolbars when it shown as a second view
480 QTimer::singleShot(20, parentWidget(), SLOT(setFocus()));
488 //****************************************************************
489 bool XGUI_ViewWindow::processViewPort(QEvent *theEvent)
491 switch(theEvent->type()) {
492 case QEvent::MouseButtonPress:
493 vpMousePressEvent((QMouseEvent*) theEvent);
496 case QEvent::MouseButtonRelease:
497 vpMouseReleaseEvent((QMouseEvent*) theEvent);
500 case QEvent::MouseMove:
501 vpMouseMoveEvent((QMouseEvent*) theEvent);
504 case QEvent::MouseButtonDblClick:
505 emit mouseDoubleClicked(this, (QMouseEvent*) theEvent);
509 QWheelEvent* aEvent = (QWheelEvent*) theEvent;
510 myViewPort->startZoomAtPoint( aEvent->x(), aEvent->y() );
511 double aDelta = (double)( aEvent->delta() ) / ( 15 * 8 );
514 int x1 = (int)( aEvent->x() + width()*aDelta/100 );
515 int y1 = (int)( aEvent->y() + height()*aDelta/100 );
516 myViewPort->zoom( x, y, x1, y1 );
523 //****************************************************************
524 bool XGUI_ViewWindow::eventFilter(QObject *theObj, QEvent *theEvent)
526 if ((theObj == myGripWgt) || (theObj == myPicture)) {
527 if (processWindowControls(theObj, theEvent))
529 } else if (theObj == myViewPort) {
530 if (processViewPort(theEvent)) {
533 if (theEvent->type() == QEvent::KeyRelease) {
534 emit keyReleased(this, (QKeyEvent*) theEvent);
538 return QFrame::eventFilter(theObj, theEvent);
541 //****************************************************************
542 XGUI_ViewWindow::OperationType XGUI_ViewWindow::getButtonState(
543 QMouseEvent* theEvent, XGUI::InteractionStyle theInteractionStyle)
545 OperationType aOp = NOTHING;
546 XGUI::InteractionStyle aStyle = (XGUI::InteractionStyle) theInteractionStyle;
547 if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ZOOM])
548 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ZOOM]))
550 else if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::PAN])
551 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::PAN]))
553 else if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ROTATE])
554 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ROTATE])
555 && (my2dMode == XGUI::No2dMode))
561 //****************************************************************
562 void XGUI_ViewWindow::vpMousePressEvent(QMouseEvent* theEvent)
564 myStartX = theEvent->x();
565 myStartY = theEvent->y();
566 XGUI::InteractionStyle anInteractionStyle = interactionStyle();
568 // in "key free" interaction style zoom operation is activated by two buttons (simultaneously pressed),
569 // which are assigned for pan and rotate - these operations are activated immediately after pressing
570 // of the first button, so it is necessary to switch to zoom when the second button is pressed
571 bool aSwitchToZoom = false;
572 if ((anInteractionStyle == XGUI::KEY_FREE) && (myOperation == PANVIEW || myOperation == ROTATE)) {
573 aSwitchToZoom = getButtonState(theEvent, anInteractionStyle) == ZOOMVIEW;
576 switch(myOperation) {
578 if (theEvent->button() == Qt::LeftButton)
579 emit vpTransformationStarted(WINDOWFIT);
583 if (theEvent->button() == Qt::LeftButton)
584 emit vpTransformationStarted(PANGLOBAL);
588 if (theEvent->button() == Qt::LeftButton) {
589 myViewPort->startZoomAtPoint(myStartX, myStartY);
590 emit vpTransformationStarted(ZOOMVIEW);
596 myViewPort->startZoomAtPoint(myStartX, myStartY);
598 } else if (theEvent->button() == Qt::LeftButton)
599 emit vpTransformationStarted(PANVIEW);
604 myViewPort->startZoomAtPoint(myStartX, myStartY);
606 } else if (theEvent->button() == Qt::LeftButton) {
607 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
608 emit vpTransformationStarted(ROTATE);
613 /* Try to activate a transformation */
614 OperationType aState;
615 if (interactionStyle() == XGUI::STANDARD)
616 aState = getButtonState(theEvent, anInteractionStyle);
618 aState = XGUI_ViewWindow::NOTHING;
623 myViewPort->startZoomAtPoint(myStartX, myStartY);
631 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
634 if (myRotationPointSelection) {
635 if (theEvent->button() == Qt::LeftButton) {
636 Handle(AIS_InteractiveContext) ic = myViewer->AISContext();
638 for(ic->InitSelected(); ic->MoreSelected(); ic->NextSelected()) {
639 TopoDS_Shape aShape = ic->SelectedShape();
640 if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) {
641 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(ic->SelectedShape()));
642 /*if ( mySetRotationPointDlg ) {
643 myRotationPointSelection = false;
644 mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z());
647 myCurrPointType = myPrevPointType;
651 if (ic->NbSelected() == 0)
652 myCurrPointType = myPrevPointType;
653 //if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange();
654 ic->CloseAllContexts();
655 myOperation = NOTHING;
656 myViewPort->setCursor(myCursor);
657 myCursorIsHand = false;
658 myRotationPointSelection = false;
661 emit mousePressed(this, theEvent);
664 /* notify that we start a transformation */
665 if (transformRequested())
666 emit vpTransformationStarted(myOperation);
668 if (transformRequested())
669 setTransformInProcess(true);
671 /* we may need it for sketching... */
672 /* if ( l_mbPressEvent )
673 delete l_mbPressEvent;
674 l_mbPressEvent = new QMouseEvent( *theEvent );*/
677 //****************************************************************
678 void XGUI_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
680 switch(myOperation) {
682 int prevState = myCurSketch;
683 /* if(theEvent->button() == Qt::RightButton) {
684 QList<OCCViewer_ViewSketcher*>::Iterator it;
685 for ( it = mySketchers.begin(); it != mySketchers.end() && myCurSketch != -1; ++it ) {
686 OCCViewer_ViewSketcher* sk = (*it);
687 if( ( sk->sketchButton() & theEvent->button() ) && sk->sketchButton() == myCurSketch )
692 emit mouseReleased(this, theEvent);
693 if (theEvent->button() == Qt::RightButton && prevState == -1) {
694 QContextMenuEvent aEvent(QContextMenuEvent::Mouse, theEvent->pos(), theEvent->globalPos());
695 emit contextMenuRequested(&aEvent);
700 myViewPort->endRotation();
710 if (theEvent->button() == Qt::LeftButton) {
711 myViewPort->setCenter(theEvent->x(), theEvent->y());
712 myViewPort->getView()->SetScale(myCurScale);
718 if (theEvent->button() == Qt::LeftButton) {
719 myCurrX = theEvent->x();
720 myCurrY = theEvent->y();
722 QRect rect = makeRect(myStartX, myStartY, myCurrX, myCurrY);
724 myViewPort->fitRect(rect);
731 // NOTE: viewer 3D detects a rectangle of selection using this event
732 // so we must emit it BEFORE resetting the selection rectangle
733 if (theEvent->button() == Qt::LeftButton && myDrawRect) {
737 myViewPort->update();
739 /* if ( l_mbPressEvent ) {
740 delete l_mbPressEvent;
745 //****************************************************************
746 void XGUI_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent)
748 if (myIsKeyFree && interactionStyle() == XGUI::KEY_FREE) {
750 switch(getButtonState(theEvent, interactionStyle())) {
752 myViewPort->startZoomAtPoint(myStartX, myStartY);
760 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
767 myCurrX = theEvent->x();
768 myCurrY = theEvent->y();
769 switch(myOperation) {
771 myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint);
775 myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY);
781 myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY);
790 if (myRotationPointSelection /*|| isSketcherStyle()*/) {
791 emit mouseMoving(this, theEvent);
793 int aState = theEvent->modifiers();
794 int aButton = theEvent->buttons();
795 int anInteractionStyle = interactionStyle();
796 if (((anInteractionStyle == XGUI::STANDARD) && (aButton == Qt::LeftButton)
797 && (aState == Qt::NoModifier || Qt::ShiftModifier))
798 || ((anInteractionStyle == XGUI::KEY_FREE) && (aButton == Qt::LeftButton)
799 && (aState == Qt::ControlModifier
800 || aState == (Qt::ControlModifier | Qt::ShiftModifier)))) {
801 myDrawRect = myEnableDrawMode;
804 if (!myCursorIsHand) { // we are going to sketch a rectangle
805 QCursor handCursor(Qt::PointingHandCursor);
806 myCursorIsHand = true;
808 myViewPort->setCursor(handCursor);
811 emit mouseMoving(this, theEvent);
812 } /* else if ( ( (anInteractionStyle == XGUI::STANDARD) &&
813 (aButton == Qt::RightButton) &&
814 ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) ||
815 ( (anInteractionStyle == XGUI::KEY_FREE) &&
816 (aButton == Qt::RightButton) &&
817 ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) {
818 OCCViewer_ViewSketcher* sketcher = 0;
819 QList<OCCViewer_ViewSketcher*>::Iterator it;
820 for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) {
821 OCCViewer_ViewSketcher* sk = (*it);
822 if( sk->isDefault() && sk->sketchButton() == aButton )
825 if ( sketcher && myCurSketch == -1 ) {
826 activateSketching( sketcher->type() );
828 myCurSketch = mypSketcher->sketchButton();
830 if ( l_mbPressEvent ) {
831 QApplication::sendEvent( getViewPort(), l_mbPressEvent );
832 delete l_mbPressEvent;
835 QApplication::sendEvent( getViewPort(), theEvent );
839 emit mouseMoving(this, theEvent);
845 \brief Draw rubber band rectangle.
847 void XGUI_ViewWindow::drawRect()
850 myRectBand = new XGUI_RectRubberBand(myViewPort);
853 myRectBand->setUpdatesEnabled(false);
854 QRect aRect = makeRect(myStartX, myStartY, myCurrX, myCurrY);
855 myRectBand->initGeometry(aRect);
857 if (!myRectBand->isVisible())
860 myRectBand->setUpdatesEnabled(true);
864 \brief Clear rubber band rectangle on the end on the dragging operation.
866 void XGUI_ViewWindow::endDrawRect()
869 myRectBand->clearGeometry();
874 void XGUI_ViewWindow::activateZoom()
876 if (!transformRequested() && !myCursorIsHand)
877 myCursor = cursor(); /* save old cursor */
879 if (myOperation != ZOOMVIEW) {
880 QPixmap zoomPixmap(imageZoomCursor);
881 QCursor zoomCursor(zoomPixmap);
882 if (setTransformRequested(ZOOMVIEW))
883 myViewPort->setCursor(zoomCursor);
887 bool XGUI_ViewWindow::transformRequested() const
889 return (myOperation != NOTHING);
893 \brief Start delayed viewer operation.
895 bool XGUI_ViewWindow::setTransformRequested(OperationType op)
897 bool ok = transformEnabled(op);
898 myOperation = ok ? op : NOTHING;
899 myViewPort->setMouseTracking(myOperation == NOTHING);
904 Set enabled state of transformation (rotate, zoom, etc)
906 void XGUI_ViewWindow::setTransformEnabled(const OperationType id, const bool on)
909 myStatus.insert(id, on);
913 \return enabled state of transformation (rotate, zoom, etc)
915 bool XGUI_ViewWindow::transformEnabled(const OperationType id) const
917 return myStatus.contains(id) ? myStatus[id] : true;
921 \brief Start panning operation.
923 Sets the corresponding cursor for the widget.
925 void XGUI_ViewWindow::activatePanning()
927 if (!transformRequested() && !myCursorIsHand)
928 myCursor = cursor(); // save old cursor
930 if (myOperation != PANVIEW) {
931 QCursor panCursor(Qt::SizeAllCursor);
932 if (setTransformRequested(PANVIEW))
933 myViewPort->setCursor(panCursor);
938 \brief Start global panning operation
940 Sets the corresponding cursor for the widget.
942 void XGUI_ViewWindow::activateGlobalPanning()
944 Handle(V3d_View) aView3d = myViewPort->getView();
945 if ( !aView3d.IsNull() ) {
946 QPixmap globalPanPixmap (imageCrossCursor);
947 QCursor glPanCursor (globalPanPixmap);
948 myCurScale = aView3d->Scale();
949 aView3d->FitAll(0.01, false);
950 myCursor = cursor(); // save old cursor
951 myViewPort->fitAll(); // fits view before selecting a new scene center
952 if( setTransformRequested( PANGLOBAL ) )
953 myViewPort->setCursor( glPanCursor );
958 \brief Start rotation operation
960 Sets the corresponding cursor for the widget.
962 void XGUI_ViewWindow::activateRotation()
964 if (!transformRequested() && !myCursorIsHand)
965 myCursor = cursor(); // save old cursor
967 if (myOperation != ROTATE) {
968 QPixmap rotatePixmap(imageRotateCursor);
969 QCursor rotCursor(rotatePixmap);
970 if (setTransformRequested(ROTATE))
971 myViewPort->setCursor(rotCursor);
976 \brief Reset the viewport to its initial state
977 ( no transformations in process etc. )
979 void XGUI_ViewWindow::resetState()
983 if (myRotationPointSelection) {
984 QCursor handCursor(Qt::PointingHandCursor);
985 myViewPort->setCursor(handCursor);
987 if (transformRequested() || myCursorIsHand)
988 myViewPort->setCursor(myCursor);
989 myCursorIsHand = false;
992 if (transformRequested())
993 emit vpTransformationFinished(myOperation);
995 setTransformInProcess(false);
996 setTransformRequested(NOTHING);
999 XGUI_ViewBackground XGUI_ViewWindow::background() const
1001 return myViewPort ? myViewPort->background() : XGUI_ViewBackground();
1004 void XGUI_ViewWindow::setBackground(const XGUI_ViewBackground& theBackground)
1007 myViewPort->setBackground( theBackground );
1011 \brief Create one more window with same content.
1013 void XGUI_ViewWindow::cloneView()
1015 QMdiSubWindow* vw = myViewer->createView();
1016 XGUI_ViewWindow* aNewWnd = static_cast<XGUI_ViewWindow*>(vw->widget());
1017 aNewWnd->viewPort()->syncronizeWith(myViewPort);
1019 emit viewCloned( vw );
1021 // In order to avoid frosen background in toolbars when it shown as a second view
1022 QTimer::singleShot(20, vw, SLOT(setFocus()));
1025 void XGUI_ViewWindow::dumpView()
1027 QString aFilter(tr("Images Files (*.bmp *.png *.jpg *.jpeg *.eps *.ps)"));
1028 QString aSelectedFilter;
1029 QString aFileName = QFileDialog::getSaveFileName(this, "Save picture", QString(), aFilter, &aSelectedFilter);
1030 if (!aFileName.isNull()) {
1031 QApplication::setOverrideCursor( Qt::WaitCursor );
1032 QImage aPicture = myViewPort->dumpView();
1034 QString aFmt = extension(aFileName).toUpper();
1035 if( aFmt.isEmpty() )
1036 aFmt = QString( "BMP" ); // default format
1037 else if( aFmt == "JPG" )
1040 Handle(Visual3d_View) a3dView = myViewPort->getView()->View();
1042 a3dView->Export(strdup(qPrintable(aFileName)), Graphic3d_EF_PostScript);
1043 else if (aFmt == "EPS")
1044 a3dView->Export(strdup(qPrintable(aFileName)), Graphic3d_EF_EnhPostScript);
1046 aPicture.save( aFileName, aFmt.toLatin1() );
1047 QApplication::restoreOverrideCursor();
1051 void XGUI_ViewWindow::fitAll()
1053 emit vpTransformationStarted( FITALLVIEW );
1054 myViewPort->fitAll();
1055 emit vpTransformationFinished( FITALLVIEW );
1059 \brief Starts fit operation.
1061 Sets the corresponding cursor for the widget.
1063 void XGUI_ViewWindow::activateWindowFit()
1065 if ( !transformRequested() && !myCursorIsHand )
1066 myCursor = cursor(); /* save old cursor */
1068 if ( myOperation != WINDOWFIT ) {
1069 QCursor handCursor (Qt::PointingHandCursor);
1070 if( setTransformRequested ( WINDOWFIT ) ) {
1071 myViewPort->setCursor ( handCursor );
1072 myCursorIsHand = true;
1079 \brief Perform "front view" transformation.
1081 void XGUI_ViewWindow::frontView()
1083 emit vpTransformationStarted ( FRONTVIEW );
1084 Handle(V3d_View) aView3d = myViewPort->getView();
1085 if ( !aView3d.IsNull() )
1086 aView3d->SetProj (V3d_Xpos);
1087 myViewPort->fitAll();
1088 emit vpTransformationFinished ( FRONTVIEW );
1092 \brief Perform "back view" transformation.
1094 void XGUI_ViewWindow::backView()
1096 emit vpTransformationStarted ( BACKVIEW );
1097 Handle(V3d_View) aView3d = myViewPort->getView();
1098 if ( !aView3d.IsNull() )
1099 aView3d->SetProj (V3d_Xneg);
1100 myViewPort->fitAll();
1101 emit vpTransformationFinished ( BACKVIEW );
1105 \brief Perform "top view" transformation.
1107 void XGUI_ViewWindow::topView()
1109 emit vpTransformationStarted ( TOPVIEW );
1110 Handle(V3d_View) aView3d = myViewPort->getView();
1111 if ( !aView3d.IsNull() )
1112 aView3d->SetProj (V3d_Zpos);
1113 myViewPort->fitAll();
1114 emit vpTransformationFinished ( TOPVIEW );
1118 \brief Perform "bottom view" transformation.
1120 void XGUI_ViewWindow::bottomView()
1122 emit vpTransformationStarted ( BOTTOMVIEW );
1123 Handle(V3d_View) aView3d = myViewPort->getView();
1124 if ( !aView3d.IsNull() )
1125 aView3d->SetProj (V3d_Zneg);
1126 myViewPort->fitAll();
1127 emit vpTransformationFinished ( BOTTOMVIEW );
1131 \brief Perform "left view" transformation.
1133 void XGUI_ViewWindow::leftView()
1135 emit vpTransformationStarted ( LEFTVIEW );
1136 Handle(V3d_View) aView3d = myViewPort->getView();
1137 if ( !aView3d.IsNull() )
1138 aView3d->SetProj (V3d_Yneg);
1139 myViewPort->fitAll();
1140 emit vpTransformationFinished ( LEFTVIEW );
1144 \brief Perform "right view" transformation.
1146 void XGUI_ViewWindow::rightView()
1148 emit vpTransformationStarted ( RIGHTVIEW );
1149 Handle(V3d_View) aView3d = myViewPort->getView();
1150 if ( !aView3d.IsNull() )
1151 aView3d->SetProj (V3d_Ypos);
1152 myViewPort->fitAll();
1153 emit vpTransformationFinished ( RIGHTVIEW );
1156 void XGUI_ViewWindow::reset()
1158 emit vpTransformationStarted( RESETVIEW );
1159 bool upd = myViewPort->getView()->SetImmediateUpdate( false );
1160 myViewPort->getView()->Reset( false );
1161 myViewPort->fitAll( false, true, false );
1162 myViewPort->getView()->SetImmediateUpdate( upd );
1163 myViewPort->getView()->Update();
1164 emit vpTransformationFinished( RESETVIEW );
1168 void XGUI_ViewWindow::updateToolBar()
1170 myGripWgt->update();
1171 myViewBar->update();
1172 myWindowBar->update();