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>
29 const char* imageZoomCursor[] = { "32 32 3 1", ". c None", "a c #000000", "# c #ffffff",
30 "................................", "................................",
31 ".#######........................", "..aaaaaaa.......................",
32 "................................", ".............#####..............",
33 "...........##.aaaa##............", "..........#.aa.....a#...........",
34 ".........#.a.........#..........", ".........#a..........#a.........",
35 "........#.a...........#.........", "........#a............#a........",
36 "........#a............#a........", "........#a............#a........",
37 "........#a............#a........", ".........#...........#.a........",
38 ".........#a..........#a.........", ".........##.........#.a.........",
39 "........#####.....##.a..........", ".......###aaa#####.aa...........",
40 "......###aa...aaaaa.......#.....", ".....###aa................#a....",
41 "....###aa.................#a....", "...###aa...............#######..",
42 "....#aa.................aa#aaaa.", ".....a....................#a....",
43 "..........................#a....", "...........................a....",
44 "................................", "................................",
45 "................................", "................................" };
47 const char* imageRotateCursor[] = { "32 32 3 1", ". c None", "a c #000000", "# c #ffffff",
48 "................................", "................................",
49 "................................", "................................",
50 "........#.......................", ".......#.a......................",
51 "......#######...................", ".......#aaaaa#####..............",
52 "........#..##.a#aa##........##..", ".........a#.aa..#..a#.....##.aa.",
53 ".........#.a.....#...#..##.aa...", ".........#a.......#..###.aa.....",
54 "........#.a.......#a..#aa.......", "........#a.........#..#a........",
55 "........#a.........#a.#a........", "........#a.........#a.#a........",
56 "........#a.........#a.#a........", ".........#.........#a#.a........",
57 "........##a........#a#a.........", "......##.a#.......#.#.a.........",
58 "....##.aa..##.....##.a..........", "..##.aa.....a#####.aa...........",
59 "...aa.........aaa#a.............", "................#.a.............",
60 "...............#.a..............", "..............#.a...............",
61 "...............a................", "................................",
62 "................................", "................................",
63 "................................", "................................" };
65 const char* imageCrossCursor[] = { "32 32 3 1", ". c None", "a c #000000", "# c #ffffff",
66 "................................", "................................",
67 "................................", "................................",
68 "................................", "................................",
69 "................................", "...............#................",
70 "...............#a...............", "...............#a...............",
71 "...............#a...............", "...............#a...............",
72 "...............#a...............", "...............#a...............",
73 "...............#a...............", ".......#################........",
74 "........aaaaaaa#aaaaaaaaa.......", "...............#a...............",
75 "...............#a...............", "...............#a...............",
76 "...............#a...............", "...............#a...............",
77 "...............#a...............", "...............#a...............",
78 "................a...............", "................................",
79 "................................", "................................",
80 "................................", "................................",
81 "................................", "................................" };
83 ViewerToolbar::ViewerToolbar(QWidget* theParent, XGUI_ViewPort* thePort)
84 : QToolBar(theParent),
88 connect(myVPort, SIGNAL(resized()), this, SLOT(onViewPortResized()));
91 void ViewerToolbar::paintEvent(QPaintEvent* theEvent)
93 //QToolBar::paintEvent(theEvent);
95 QPainter aPainter(this);
97 QRect aVPRect = myVPort->rect();
98 QPoint aGlobPnt = mapToGlobal(aRect.topLeft());
99 QPoint aPnt = myVPort->mapFromGlobal(aGlobPnt);
102 QRect(aPnt.x(), aPnt.y() + aVPRect.height() - aRect.height(), aRect.width(), aRect.height()));
103 unsigned char* aData = 0;
104 QImage aImg = myVPort->dumpView(aData, aImgRect, myResize);
106 aPainter.drawImage(aRect, aImg);
110 QStyle *style = this->style();
111 QStyleOptionToolBar aOpt;
112 initStyleOption(&aOpt);
114 aOpt.rect = style->subElementRect(QStyle::SE_ToolBarHandle, &aOpt, this);
115 if (aOpt.rect.isValid())
116 style->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &aOpt, &aPainter, this);
121 //**************************************************************************
122 ViewerLabel::ViewerLabel(QWidget* theParent, XGUI_ViewPort* thePort)
127 connect(myVPort, SIGNAL(resized()), this, SLOT(onViewPortResized()));
130 void ViewerLabel::paintEvent(QPaintEvent* theEvent)
132 QRect aRect = rect();
133 QRect aVPRect = myVPort->rect();
134 QPoint aGlobPnt = mapToGlobal(aRect.topLeft());
135 QPoint aPnt = myVPort->mapFromGlobal(aGlobPnt);
138 QRect(aPnt.x(), aPnt.y() + aVPRect.height() - aRect.height(), aRect.width(), aRect.height()));
139 unsigned char* aData = 0;
140 QImage aImg = myVPort->dumpView(aData, aImgRect, myResize);
142 QPainter(this).drawImage(aRect, aImg);
144 QLabel::paintEvent(theEvent);
149 //**************************************************************************
150 //**************************************************************************
151 //**************************************************************************
152 XGUI_ViewWindow::XGUI_ViewWindow(XGUI_Viewer* theViewer, V3d_TypeOfView theType)
156 MinimizeIco(":pictures/wnd_minimize.png"),
157 MaximizeIco(":pictures/wnd_maximize.png"),
158 CloseIco(":pictures/wnd_close.png"),
159 RestoreIco(":pictures/wnd_restore.png"),
160 myInteractionStyle(XGUI::STANDARD),
163 my2dMode(XGUI::No2dMode),
164 myCurrPointType(XGUI::GRAVITY),
165 myPrevPointType(XGUI::GRAVITY),
166 myRotationPointSelection(false),
175 myEnableDrawMode(false),
176 myCursorIsHand(false),
177 myEventStarted(false),
179 myLastState(WindowNormalState),
180 myOperation(NOTHING),
184 mySelectedPoint = gp_Pnt(0., 0., 0.);
185 setFrameStyle(QFrame::Raised);
186 setFrameShape(QFrame::Panel);
187 setLineWidth(BORDER_SIZE);
188 setMouseTracking(true);
190 QVBoxLayout* aLay = new QVBoxLayout(this);
191 aLay->setContentsMargins(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE);
192 myViewPort = new XGUI_ViewPort(this, myViewer->v3dViewer(), theType);
193 myViewPort->installEventFilter(this);
194 myViewPort->setCursor(Qt::ArrowCursor);
195 aLay->addWidget(myViewPort);
197 myPicture = new QLabel(this);
198 myPicture->setFrameStyle(QFrame::Sunken);
199 myPicture->setFrameShape(QFrame::Panel);
200 myPicture->setMouseTracking(true);
201 myPicture->installEventFilter(this);
202 aLay->addWidget(myPicture);
205 QVBoxLayout* aVPLay = new QVBoxLayout(myViewPort);
206 aVPLay->setMargin(0);
207 aVPLay->setSpacing(0);
208 aVPLay->setContentsMargins(0, 0, 0, 0);
210 QHBoxLayout* aToolLay = new QHBoxLayout();
211 aToolLay->setMargin(0);
212 aToolLay->setSpacing(0);
213 aToolLay->setContentsMargins(0, 0, 0, 0);
214 aVPLay->addLayout(aToolLay);
215 aVPLay->addStretch();
217 myGripWgt = new ViewerLabel(this, myViewPort);
218 myGripWgt->setPixmap(QPixmap(":pictures/wnd_grip.png"));
219 myGripWgt->setMouseTracking(true);
220 myGripWgt->installEventFilter(this);
221 myGripWgt->setCursor(Qt::OpenHandCursor);
222 aToolLay->addWidget(myGripWgt);
224 // Create Viewer management buttons
225 myViewBar = new ViewerToolbar(this, myViewPort);
226 myViewBar->setCursor(Qt::PointingHandCursor);
227 aToolLay->addWidget(myViewBar);
228 aToolLay->addStretch();
233 aBtn = new QAction(QIcon(":pictures/occ_view_camera_dump.png"), tr("Dump view"), myViewBar);
234 connect(aBtn, SIGNAL(triggered()), SLOT(dumpView()));
235 myViewBar->addAction(aBtn);
237 aBtn = new QAction(QIcon(":pictures/occ_view_fitall.png"), tr("Fit all"), myViewBar);
238 connect(aBtn, SIGNAL(triggered()), SLOT(fitAll()));
239 myViewBar->addAction(aBtn);
241 aBtn = new QAction(QIcon(":pictures/occ_view_fitarea.png"), tr("Fit area"), myViewBar);
242 connect(aBtn, SIGNAL(triggered()), SLOT(activateWindowFit()));
243 myViewBar->addAction(aBtn);
245 aBtn = new QAction(QIcon(":pictures/occ_view_zoom.png"), tr("Zoom"), myViewBar);
246 connect(aBtn, SIGNAL(triggered()), SLOT(activateZoom()));
247 myViewBar->addAction(aBtn);
249 aBtn = new QAction(QIcon(":pictures/occ_view_pan.png"), tr("Panning"), myViewBar);
250 connect(aBtn, SIGNAL(triggered()), SLOT(activatePanning()));
251 myViewBar->addAction(aBtn);
253 aBtn = new QAction(QIcon(":pictures/occ_view_glpan.png"), tr("Global panning"), myViewBar);
254 connect(aBtn, SIGNAL(triggered()), SLOT(activateGlobalPanning()));
255 myViewBar->addAction(aBtn);
257 aBtn = new QAction(QIcon(":pictures/occ_view_rotate.png"), tr("Rotate"), myViewBar);
258 connect(aBtn, SIGNAL(triggered()), SLOT(activateRotation()));
259 myViewBar->addAction(aBtn);
261 aBtn = new QAction(QIcon(":pictures/occ_view_reset.png"), tr("Reset"), myViewBar);
262 connect(aBtn, SIGNAL(triggered()), SLOT(reset()));
263 myViewBar->addAction(aBtn);
265 aBtn = new QAction(QIcon(":pictures/occ_view_front.png"), tr("Front"), myViewBar);
266 connect(aBtn, SIGNAL(triggered()), SLOT(frontView()));
267 myViewBar->addAction(aBtn);
269 aBtn = new QAction(QIcon(":pictures/occ_view_back.png"), tr("Back"), myViewBar);
270 connect(aBtn, SIGNAL(triggered()), SLOT(backView()));
271 myViewBar->addAction(aBtn);
273 aBtn = new QAction(QIcon(":pictures/occ_view_top.png"), tr("Top"), myViewBar);
274 connect(aBtn, SIGNAL(triggered()), SLOT(topView()));
275 myViewBar->addAction(aBtn);
277 aBtn = new QAction(QIcon(":pictures/occ_view_bottom.png"), tr("Bottom"), myViewBar);
278 connect(aBtn, SIGNAL(triggered()), SLOT(bottomView()));
279 myViewBar->addAction(aBtn);
281 aBtn = new QAction(QIcon(":pictures/occ_view_left.png"), tr("Left"), myViewBar);
282 connect(aBtn, SIGNAL(triggered()), SLOT(leftView()));
283 myViewBar->addAction(aBtn);
285 aBtn = new QAction(QIcon(":pictures/occ_view_right.png"), tr("Right"), myViewBar);
286 connect(aBtn, SIGNAL(triggered()), SLOT(rightView()));
287 myViewBar->addAction(aBtn);
289 aBtn = new QAction(QIcon(":pictures/occ_view_clone.png"), tr("Clone"), myViewBar);
290 connect(aBtn, SIGNAL(triggered()), SLOT(cloneView()));
291 myViewBar->addAction(aBtn);
293 // Create Window management buttons
294 myWindowBar = new ViewerToolbar(this, myViewPort);
295 myWindowBar->setCursor(Qt::PointingHandCursor);
296 aToolLay->addWidget(myWindowBar);
298 myMinimizeBtn = new QAction(myWindowBar);
299 myMinimizeBtn->setIcon(MinimizeIco);
300 myWindowBar->addAction(myMinimizeBtn);
301 connect(myMinimizeBtn, SIGNAL(triggered()), SLOT(onMinimize()));
303 myMaximizeBtn = new QAction(myWindowBar);
304 myMaximizeBtn->setIcon(MaximizeIco);
305 myWindowBar->addAction(myMaximizeBtn);
306 connect(myMaximizeBtn, SIGNAL(triggered()), SLOT(onMaximize()));
308 aBtn = new QAction(myWindowBar);
309 aBtn->setIcon(CloseIco);
310 myWindowBar->addAction(aBtn);
311 connect(aBtn, SIGNAL(triggered()), SLOT(onClose()));
313 //Support copy of background on updating of viewer
314 connect(myViewPort, SIGNAL(vpTransformed()), this, SLOT(updateToolBar()));
315 connect(myViewPort, SIGNAL(vpUpdated()), this, SLOT(updateToolBar()));
316 connect(this, SIGNAL(vpTransformationFinished(XGUI_ViewWindow::OperationType)), this,
317 SLOT(updateToolBar()));
320 //****************************************************************
321 XGUI_ViewWindow::~XGUI_ViewWindow()
325 //****************************************************************
326 void XGUI_ViewWindow::showEvent(QShowEvent* theEvent)
328 QFrame::showEvent(theEvent);
329 myWindowBar->setFixedSize(myWindowBar->sizeHint());
332 //****************************************************************
333 void XGUI_ViewWindow::changeEvent(QEvent* theEvent)
336 if (theEvent->type() == QEvent::WindowStateChange) {
338 if (myPicture->isHidden()) {
346 if (myPicture->isVisible()) {
351 myMinimizeBtn->setIcon(MinimizeIco);
352 myMaximizeBtn->setIcon(RestoreIco);
354 myViewBar->setVisible(myIsActive);
355 myWindowBar->setVisible(myIsActive);
356 myGripWgt->setVisible(myIsActive && (!isMaximized()));
359 QWidget::changeEvent(theEvent);
362 //****************************************************************
363 void XGUI_ViewWindow::windowActivated()
365 if (!(isMinimized() || parentWidget()->isMinimized())) {
367 if (isMaximized() || parentWidget()->isMaximized()) {
368 myMaximizeBtn->setIcon(RestoreIco);
370 myMaximizeBtn->setIcon(MaximizeIco);
374 myGripWgt->setVisible(
375 !(isMaximized() || isMinimized() || parentWidget()->isMaximized()
376 || parentWidget()->isMinimized()));
381 //****************************************************************
382 void XGUI_ViewWindow::windowDeactivated()
385 if (!(isMinimized() || parentWidget()->isMinimized())) {
386 if (isMaximized() || parentWidget()->isMaximized()) {
387 myMaximizeBtn->setIcon(RestoreIco);
389 myMaximizeBtn->setIcon(MaximizeIco);
397 //****************************************************************
398 void XGUI_ViewWindow::onClose()
400 if (parentWidget()) {
401 emit tryClosing(this);
403 emit closed(static_cast<QMdiSubWindow*>(parentWidget()));
404 parentWidget()->close();
409 //****************************************************************
410 void XGUI_ViewWindow::onMinimize()
412 unsigned char* aData = 0;
413 QPixmap aPMap = QPixmap::fromImage(myViewPort->dumpView(aData));
416 double aR = aW / 100.;
417 int aNewH = int(aH / aR);
418 myPicture->setPixmap(aPMap.scaled(100, aNewH));
421 (isMaximized() || parentWidget()->isMaximized()) ? MaximizedState : WindowNormalState;
423 parentWidget()->showMinimized();
424 parentWidget()->setGeometry(parentWidget()->x(), parentWidget()->y(), 100, aNewH);
425 parentWidget()->lower();
427 myViewer->onWindowMinimized((QMdiSubWindow*) parentWidget());
431 //****************************************************************
432 void XGUI_ViewWindow::onMaximize()
434 if (isMaximized() || parentWidget()->isMaximized()) {
435 myMaximizeBtn->setIcon(MaximizeIco);
438 parentWidget()->showNormal();
440 myMaximizeBtn->setIcon(RestoreIco);
443 parentWidget()->showMaximized();
445 parentWidget()->activateWindow();
446 myMinimizeBtn->setIcon(MinimizeIco);
448 // In order to avoid frosen background in toolbars when it shown as a second view
449 QTimer::singleShot(50, parentWidget(), SLOT(setFocus()));
452 //****************************************************************
453 bool XGUI_ViewWindow::processWindowControls(QObject *theObj, QEvent *theEvent)
455 switch (theEvent->type()) {
456 case QEvent::MouseButtonPress: {
457 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
458 if ((aEvent->button() == Qt::LeftButton) && (!myMoving)) {
460 myMousePnt = aEvent->globalPos();
465 case QEvent::MouseButtonRelease: {
466 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
467 if ((aEvent->button() == Qt::LeftButton) && myMoving) {
473 case QEvent::MouseMove: {
474 QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
476 QMdiSubWindow* aParent = static_cast<QMdiSubWindow*>(parentWidget());
477 QMdiArea* aMDIArea = aParent->mdiArea();
479 QPoint aPnt = aEvent->globalPos();
480 QPoint aMDIPnt = aMDIArea->mapFromGlobal(aPnt);
481 if (aMDIArea->rect().contains(aMDIPnt)) {
482 int aX = aParent->x() + (aPnt.x() - myMousePnt.x());
483 int aY = aParent->y() + (aPnt.y() - myMousePnt.y());
484 aParent->move(aX, aY);
491 case QEvent::MouseButtonDblClick:
492 if (theObj == myPicture) {
494 if (myLastState == MaximizedState) {
499 myViewer->onWindowActivated((QMdiSubWindow*) parentWidget());
501 // In order to avoid frosen background in toolbars when it shown as a second view
502 QTimer::singleShot(20, parentWidget(), SLOT(setFocus()));
510 //****************************************************************
511 bool XGUI_ViewWindow::processViewPort(QEvent *theEvent)
513 switch (theEvent->type()) {
514 case QEvent::MouseButtonPress:
515 vpMousePressEvent((QMouseEvent*) theEvent);
518 case QEvent::MouseButtonRelease:
519 vpMouseReleaseEvent((QMouseEvent*) theEvent);
522 case QEvent::MouseMove:
523 vpMouseMoveEvent((QMouseEvent*) theEvent);
526 case QEvent::MouseButtonDblClick:
527 emit mouseDoubleClicked(this, (QMouseEvent*) theEvent);
529 case QEvent::Wheel: {
530 QWheelEvent* aEvent = (QWheelEvent*) theEvent;
531 myViewPort->startZoomAtPoint(aEvent->x(), aEvent->y());
532 double aDelta = (double) (aEvent->delta()) / (15 * 8);
535 int x1 = (int) (aEvent->x() + width() * aDelta / 100);
536 int y1 = (int) (aEvent->y() + height() * aDelta / 100);
537 myViewPort->zoom(x, y, x1, y1);
544 //****************************************************************
545 bool XGUI_ViewWindow::eventFilter(QObject *theObj, QEvent *theEvent)
547 if ((theObj == myGripWgt) || (theObj == myPicture)) {
548 if (processWindowControls(theObj, theEvent))
550 } else if (theObj == myViewPort) {
551 if (processViewPort(theEvent)) {
554 if (theEvent->type() == QEvent::KeyRelease) {
555 emit keyReleased(this, (QKeyEvent*) theEvent);
559 return QFrame::eventFilter(theObj, theEvent);
562 //****************************************************************
563 XGUI_ViewWindow::OperationType XGUI_ViewWindow::getButtonState(
564 QMouseEvent* theEvent, XGUI::InteractionStyle theInteractionStyle)
566 OperationType aOp = NOTHING;
567 XGUI::InteractionStyle aStyle = (XGUI::InteractionStyle) theInteractionStyle;
568 if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ZOOM])
569 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ZOOM]))
571 else if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::PAN])
572 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::PAN]))
574 else if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ROTATE])
575 && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ROTATE])
576 && (my2dMode == XGUI::No2dMode))
582 //****************************************************************
583 void XGUI_ViewWindow::vpMousePressEvent(QMouseEvent* theEvent)
585 myStartX = theEvent->x();
586 myStartY = theEvent->y();
587 XGUI::InteractionStyle anInteractionStyle = interactionStyle();
589 // in "key free" interaction style zoom operation is activated by two buttons (simultaneously pressed),
590 // which are assigned for pan and rotate - these operations are activated immediately after pressing
591 // of the first button, so it is necessary to switch to zoom when the second button is pressed
592 bool aSwitchToZoom = false;
593 if ((anInteractionStyle == XGUI::KEY_FREE) && (myOperation == PANVIEW || myOperation == ROTATE)) {
594 aSwitchToZoom = getButtonState(theEvent, anInteractionStyle) == ZOOMVIEW;
597 switch (myOperation) {
599 if (theEvent->button() == Qt::LeftButton)
600 emit vpTransformationStarted(WINDOWFIT);
604 if (theEvent->button() == Qt::LeftButton)
605 emit vpTransformationStarted(PANGLOBAL);
609 if (theEvent->button() == Qt::LeftButton) {
610 myViewPort->startZoomAtPoint(myStartX, myStartY);
611 emit vpTransformationStarted(ZOOMVIEW);
617 myViewPort->startZoomAtPoint(myStartX, myStartY);
619 } else if (theEvent->button() == Qt::LeftButton)
620 emit vpTransformationStarted(PANVIEW);
625 myViewPort->startZoomAtPoint(myStartX, myStartY);
627 } else if (theEvent->button() == Qt::LeftButton) {
628 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
629 emit vpTransformationStarted(ROTATE);
634 /* Try to activate a transformation */
635 OperationType aState;
636 if (interactionStyle() == XGUI::STANDARD)
637 aState = getButtonState(theEvent, anInteractionStyle);
639 aState = XGUI_ViewWindow::NOTHING;
644 myViewPort->startZoomAtPoint(myStartX, myStartY);
652 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
655 if (myRotationPointSelection) {
656 if (theEvent->button() == Qt::LeftButton) {
657 Handle(AIS_InteractiveContext) ic = myViewer->AISContext();
659 for (ic->InitSelected(); ic->MoreSelected(); ic->NextSelected()) {
660 TopoDS_Shape aShape = ic->SelectedShape();
661 if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) {
662 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(ic->SelectedShape()));
663 /*if ( mySetRotationPointDlg ) {
664 myRotationPointSelection = false;
665 mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z());
668 myCurrPointType = myPrevPointType;
672 if (ic->NbSelected() == 0)
673 myCurrPointType = myPrevPointType;
674 //if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange();
675 ic->CloseAllContexts();
676 myOperation = NOTHING;
677 myViewPort->setCursor(myCursor);
678 myCursorIsHand = false;
679 myRotationPointSelection = false;
682 emit mousePressed(this, theEvent);
685 /* notify that we start a transformation */
686 if (transformRequested())
687 emit vpTransformationStarted(myOperation);
689 if (transformRequested())
690 setTransformInProcess(true);
692 /* we may need it for sketching... */
693 /* if ( l_mbPressEvent )
694 delete l_mbPressEvent;
695 l_mbPressEvent = new QMouseEvent( *theEvent );*/
698 //****************************************************************
699 void XGUI_ViewWindow::contextMenuEvent(QContextMenuEvent* theEvent)
701 if (theEvent->modifiers() == Qt::NoModifier) {
702 // Temporary: has to be removed when viewer popup will be defined
703 //QFrame::contextMenuEvent(theEvent);
704 emit contextMenuRequested(theEvent);
708 //****************************************************************
709 void XGUI_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
711 switch (myOperation) {
713 int prevState = myCurSketch;
714 /* if(theEvent->button() == Qt::RightButton) {
715 QList<OCCViewer_ViewSketcher*>::Iterator it;
716 for ( it = mySketchers.begin(); it != mySketchers.end() && myCurSketch != -1; ++it ) {
717 OCCViewer_ViewSketcher* sk = (*it);
718 if( ( sk->sketchButton() & theEvent->button() ) && sk->sketchButton() == myCurSketch )
723 emit mouseReleased(this, theEvent);
727 myViewPort->endRotation();
737 if (theEvent->button() == Qt::LeftButton) {
738 myViewPort->setCenter(theEvent->x(), theEvent->y());
739 myViewPort->getView()->SetScale(myCurScale);
745 if (theEvent->button() == Qt::LeftButton) {
746 myCurrX = theEvent->x();
747 myCurrY = theEvent->y();
749 QRect rect = XGUI_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
751 myViewPort->fitRect(rect);
758 // NOTE: viewer 3D detects a rectangle of selection using this event
759 // so we must emit it BEFORE resetting the selection rectangle
760 if (theEvent->button() == Qt::LeftButton && myDrawRect) {
764 myViewPort->update();
766 /* if ( l_mbPressEvent ) {
767 delete l_mbPressEvent;
772 //****************************************************************
773 void XGUI_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent)
775 if (myIsKeyFree && interactionStyle() == XGUI::KEY_FREE) {
777 switch (getButtonState(theEvent, interactionStyle())) {
779 myViewPort->startZoomAtPoint(myStartX, myStartY);
787 myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
794 myCurrX = theEvent->x();
795 myCurrY = theEvent->y();
796 switch (myOperation) {
798 myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint);
802 myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY);
808 myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY);
817 if (myRotationPointSelection /*|| isSketcherStyle()*/) {
818 emit mouseMoving(this, theEvent);
820 int aState = theEvent->modifiers();
821 int aButton = theEvent->buttons();
822 int anInteractionStyle = interactionStyle();
823 if (((anInteractionStyle == XGUI::STANDARD) && (aButton == Qt::LeftButton)
824 && (aState == Qt::NoModifier || Qt::ShiftModifier))
825 || ((anInteractionStyle == XGUI::KEY_FREE) && (aButton == Qt::LeftButton)
826 && (aState == Qt::ControlModifier
827 || aState == (Qt::ControlModifier | Qt::ShiftModifier)))) {
828 myDrawRect = myEnableDrawMode;
831 if (!myCursorIsHand) { // we are going to sketch a rectangle
832 QCursor handCursor(Qt::PointingHandCursor);
833 myCursorIsHand = true;
835 myViewPort->setCursor(handCursor);
838 emit mouseMoving(this, theEvent);
839 } /* else if ( ( (anInteractionStyle == XGUI::STANDARD) &&
840 (aButton == Qt::RightButton) &&
841 ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) ||
842 ( (anInteractionStyle == XGUI::KEY_FREE) &&
843 (aButton == Qt::RightButton) &&
844 ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) {
845 OCCViewer_ViewSketcher* sketcher = 0;
846 QList<OCCViewer_ViewSketcher*>::Iterator it;
847 for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) {
848 OCCViewer_ViewSketcher* sk = (*it);
849 if( sk->isDefault() && sk->sketchButton() == aButton )
852 if ( sketcher && myCurSketch == -1 ) {
853 activateSketching( sketcher->type() );
855 myCurSketch = mypSketcher->sketchButton();
857 if ( l_mbPressEvent ) {
858 QApplication::sendEvent( getViewPort(), l_mbPressEvent );
859 delete l_mbPressEvent;
862 QApplication::sendEvent( getViewPort(), theEvent );
866 emit mouseMoving(this, theEvent);
872 \brief Draw rubber band rectangle.
874 void XGUI_ViewWindow::drawRect()
876 // there is a fix for a black-colored window
877 // the rubber band is valid if the values delta is less than 1
878 // TODO: move this fix to the RectRubberBand according to SALOME 7.5
879 double aDeltaX = fabs((float)(myStartX-myCurrX));
880 double aDeltaY = fabs((float)(myStartY-myCurrY));
881 if (aDeltaX <= 1 || aDeltaY == 1) {
887 myRectBand = new XGUI_RectRubberBand(myViewPort);
890 myRectBand->setUpdatesEnabled(false);
891 QRect aRect = XGUI_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
892 myRectBand->initGeometry(aRect);
894 if (!myRectBand->isVisible())
897 myRectBand->setUpdatesEnabled(true);
901 \brief Clear rubber band rectangle on the end on the dragging operation.
903 void XGUI_ViewWindow::endDrawRect()
906 myRectBand->clearGeometry();
911 void XGUI_ViewWindow::activateZoom()
913 if (!transformRequested() && !myCursorIsHand)
914 myCursor = cursor(); /* save old cursor */
916 if (myOperation != ZOOMVIEW) {
917 QPixmap zoomPixmap(imageZoomCursor);
918 QCursor zoomCursor(zoomPixmap);
919 if (setTransformRequested(ZOOMVIEW))
920 myViewPort->setCursor(zoomCursor);
924 bool XGUI_ViewWindow::transformRequested() const
926 return (myOperation != NOTHING);
930 \brief Start delayed viewer operation.
932 bool XGUI_ViewWindow::setTransformRequested(OperationType op)
934 bool ok = transformEnabled(op);
935 myOperation = ok ? op : NOTHING;
936 myViewPort->setMouseTracking(myOperation == NOTHING);
941 Set enabled state of transformation (rotate, zoom, etc)
943 void XGUI_ViewWindow::setTransformEnabled(const OperationType id, const bool on)
946 myStatus.insert(id, on);
950 \return enabled state of transformation (rotate, zoom, etc)
952 bool XGUI_ViewWindow::transformEnabled(const OperationType id) const
954 return myStatus.contains(id) ? myStatus[id] : true;
958 \brief Start panning operation.
960 Sets the corresponding cursor for the widget.
962 void XGUI_ViewWindow::activatePanning()
964 if (!transformRequested() && !myCursorIsHand)
965 myCursor = cursor(); // save old cursor
967 if (myOperation != PANVIEW) {
968 QCursor panCursor(Qt::SizeAllCursor);
969 if (setTransformRequested(PANVIEW))
970 myViewPort->setCursor(panCursor);
975 \brief Start global panning operation
977 Sets the corresponding cursor for the widget.
979 void XGUI_ViewWindow::activateGlobalPanning()
981 Handle(V3d_View) aView3d = myViewPort->getView();
982 if (!aView3d.IsNull()) {
983 QPixmap globalPanPixmap(imageCrossCursor);
984 QCursor glPanCursor(globalPanPixmap);
985 myCurScale = aView3d->Scale();
986 aView3d->FitAll(0.01, false);
987 myCursor = cursor(); // save old cursor
988 myViewPort->fitAll(); // fits view before selecting a new scene center
989 if (setTransformRequested(PANGLOBAL))
990 myViewPort->setCursor(glPanCursor);
995 \brief Start rotation operation
997 Sets the corresponding cursor for the widget.
999 void XGUI_ViewWindow::activateRotation()
1001 if (!transformRequested() && !myCursorIsHand)
1002 myCursor = cursor(); // save old cursor
1004 if (myOperation != ROTATE) {
1005 QPixmap rotatePixmap(imageRotateCursor);
1006 QCursor rotCursor(rotatePixmap);
1007 if (setTransformRequested(ROTATE))
1008 myViewPort->setCursor(rotCursor);
1013 \brief Reset the viewport to its initial state
1014 ( no transformations in process etc. )
1016 void XGUI_ViewWindow::resetState()
1020 if (myRotationPointSelection) {
1021 QCursor handCursor(Qt::PointingHandCursor);
1022 myViewPort->setCursor(handCursor);
1024 if (transformRequested() || myCursorIsHand)
1025 myViewPort->setCursor(myCursor);
1026 myCursorIsHand = false;
1029 if (transformRequested())
1030 emit vpTransformationFinished(myOperation);
1032 setTransformInProcess(false);
1033 setTransformRequested(NOTHING);
1036 Qtx::BackgroundData XGUI_ViewWindow::background() const
1038 return myViewPort ? myViewPort->background() : Qtx::BackgroundData();
1041 void XGUI_ViewWindow::setBackground(const Qtx::BackgroundData& theBackground)
1044 myViewPort->setBackground(theBackground);
1048 \brief Create one more window with same content.
1050 void XGUI_ViewWindow::cloneView()
1052 QMdiSubWindow* vw = myViewer->createView();
1053 XGUI_ViewWindow* aNewWnd = static_cast<XGUI_ViewWindow*>(vw->widget());
1054 aNewWnd->viewPort()->syncronizeWith(myViewPort);
1056 emit viewCloned(vw);
1058 // In order to avoid frosen background in toolbars when it shown as a second view
1059 QTimer::singleShot(20, vw, SLOT(setFocus()));
1062 void XGUI_ViewWindow::dumpView()
1064 QString aFilter(tr("Images Files (*.bmp *.png *.jpg *.jpeg *.eps *.ps)"));
1065 QString aSelectedFilter;
1066 QString aFileName = QFileDialog::getSaveFileName(this, "Save picture", QString(), aFilter,
1068 if (!aFileName.isNull()) {
1069 QApplication::setOverrideCursor(Qt::WaitCursor);
1070 unsigned char* aData = 0;
1071 QImage aPicture = myViewPort->dumpView(aData);
1073 QString aFmt = XGUI_Tools::extension(aFileName).toUpper();
1075 aFmt = QString("BMP"); // default format
1076 else if (aFmt == "JPG")
1079 Handle(Visual3d_View) a3dView = myViewPort->getView()->View();
1082 a3dView->Export(_strdup(qPrintable(aFileName)), Graphic3d_EF_PostScript);
1084 a3dView->Export(strdup(qPrintable(aFileName)), Graphic3d_EF_PostScript);
1086 else if (aFmt == "EPS")
1088 a3dView->Export(_strdup(qPrintable(aFileName)), Graphic3d_EF_EnhPostScript);
1090 a3dView->Export(strdup(qPrintable(aFileName)), Graphic3d_EF_EnhPostScript);
1093 aPicture.save(aFileName, aFmt.toLatin1());
1095 QApplication::restoreOverrideCursor();
1099 void XGUI_ViewWindow::fitAll()
1101 emit vpTransformationStarted(FITALLVIEW);
1102 myViewPort->fitAll();
1103 emit vpTransformationFinished(FITALLVIEW);
1107 \brief Starts fit operation.
1109 Sets the corresponding cursor for the widget.
1111 void XGUI_ViewWindow::activateWindowFit()
1113 if (!transformRequested() && !myCursorIsHand)
1114 myCursor = cursor(); /* save old cursor */
1116 if (myOperation != WINDOWFIT) {
1117 QCursor handCursor(Qt::PointingHandCursor);
1118 if (setTransformRequested(WINDOWFIT)) {
1119 myViewPort->setCursor(handCursor);
1120 myCursorIsHand = true;
1126 \brief Perform "front view" transformation.
1128 void XGUI_ViewWindow::frontView()
1130 emit vpTransformationStarted(FRONTVIEW);
1131 Handle(V3d_View) aView3d = myViewPort->getView();
1132 if (!aView3d.IsNull())
1133 aView3d->SetProj(V3d_Xpos);
1134 myViewPort->fitAll();
1135 emit vpTransformationFinished(FRONTVIEW);
1139 \brief Perform "back view" transformation.
1141 void XGUI_ViewWindow::backView()
1143 emit vpTransformationStarted(BACKVIEW);
1144 Handle(V3d_View) aView3d = myViewPort->getView();
1145 if (!aView3d.IsNull())
1146 aView3d->SetProj(V3d_Xneg);
1147 myViewPort->fitAll();
1148 emit vpTransformationFinished(BACKVIEW);
1152 \brief Perform "top view" transformation.
1154 void XGUI_ViewWindow::topView()
1156 emit vpTransformationStarted(TOPVIEW);
1157 Handle(V3d_View) aView3d = myViewPort->getView();
1158 if (!aView3d.IsNull())
1159 aView3d->SetProj(V3d_Zpos);
1160 myViewPort->fitAll();
1161 emit vpTransformationFinished(TOPVIEW);
1165 \brief Perform "bottom view" transformation.
1167 void XGUI_ViewWindow::bottomView()
1169 emit vpTransformationStarted(BOTTOMVIEW);
1170 Handle(V3d_View) aView3d = myViewPort->getView();
1171 if (!aView3d.IsNull())
1172 aView3d->SetProj(V3d_Zneg);
1173 myViewPort->fitAll();
1174 emit vpTransformationFinished(BOTTOMVIEW);
1178 \brief Perform "left view" transformation.
1180 void XGUI_ViewWindow::leftView()
1182 emit vpTransformationStarted(LEFTVIEW);
1183 Handle(V3d_View) aView3d = myViewPort->getView();
1184 if (!aView3d.IsNull())
1185 aView3d->SetProj(V3d_Yneg);
1186 myViewPort->fitAll();
1187 emit vpTransformationFinished(LEFTVIEW);
1191 \brief Perform "right view" transformation.
1193 void XGUI_ViewWindow::rightView()
1195 emit vpTransformationStarted(RIGHTVIEW);
1196 Handle(V3d_View) aView3d = myViewPort->getView();
1197 if (!aView3d.IsNull())
1198 aView3d->SetProj(V3d_Ypos);
1199 myViewPort->fitAll();
1200 emit vpTransformationFinished(RIGHTVIEW);
1203 void XGUI_ViewWindow::reset()
1205 emit vpTransformationStarted(RESETVIEW);
1206 bool upd = myViewPort->getView()->SetImmediateUpdate(false);
1207 myViewPort->getView()->Reset(false);
1208 myViewPort->fitAll(false, true, false);
1209 myViewPort->getView()->SetImmediateUpdate(upd);
1210 myViewPort->getView()->Update();
1211 emit vpTransformationFinished(RESETVIEW);
1214 void XGUI_ViewWindow::updateToolBar()
1216 myGripWgt->update();
1217 myViewBar->update();
1218 myWindowBar->update();
1222 \brief Update state of enable draw mode state.
1224 void XGUI_ViewWindow::updateEnabledDrawMode()
1226 myEnableDrawMode = myViewer->isSelectionEnabled() && myViewer->isMultiSelectionEnabled();