XGUI_ViewWindow.h
XGUI_ViewPort.h
XGUI_Viewer.h
+ XGUI_RubberBand.h
+ XGUI_Constants.h
)
SET(PROJECT_AUTOMOC
XGUI_ViewWindow.cpp
XGUI_ViewPort.cpp
XGUI_Viewer.cpp
+ XGUI_RubberBand.cpp
)
SET(PROJECT_RESOURCES
--- /dev/null
+
+#ifndef XGUI_Constants_H
+#define XGUI_Constants_H
+
+namespace XGUI
+{
+
+enum GradientType {
+ HorizontalGradient, VerticalGradient,
+ Diagonal1Gradient, Diagonal2Gradient,
+ Corner1Gradient, Corner2Gradient,
+ Corner3Gradient, Corner4Gradient,
+ LastGradient = Corner4Gradient
+};
+
+enum RotationPointType{ GRAVITY, SELECTED };
+
+enum SketchingType { NoSketching, Rect, Polygon };
+
+enum HotOperation { PAN, ZOOM, ROTATE, FIT_AREA };
+
+enum InteractionStyle { STANDARD, KEY_FREE };
+
+enum Mode2dType { No2dMode, XYPlane, XZPlane, YZPlane};
+
+};
+
+#endif
\ No newline at end of file
--- /dev/null
+#include "XGUI_RubberBand.h"
+
+#include <QBitmap>
+#include <QImage>
+#include <QPaintEvent>
+#include <QPainter>
+#include <QPalette>
+#include <QShowEvent>
+#include <QVectorIterator>
+
+/*!
+ \class QtxAbstractRubberBand
+ \brief Analog of class QRubberBand with possibility of creation non-rectangular contour for selection.
+
+ Currently this class does not support Style functionality in full.
+*/
+
+/*!
+ \brief Constructor
+ \param theParent parent widget
+ */
+
+XGUI_AbstractRubberBand::XGUI_AbstractRubberBand( QWidget* theParent)
+ : QWidget( theParent ),
+ myPoints(),
+ myIsClosed( false )
+{
+ setAttribute(Qt::WA_TransparentForMouseEvents);
+#ifndef WIN32
+ setAttribute(Qt::WA_NoSystemBackground);
+#endif //WIN32
+ setAttribute(Qt::WA_WState_ExplicitShowHide);
+ setVisible(false);
+ theParent->installEventFilter(this);
+ setGeometry( QRect(QPoint(0,0), theParent->size() ) );
+}
+
+/*!
+ \brief Destructor
+ */
+XGUI_AbstractRubberBand::~XGUI_AbstractRubberBand()
+{
+}
+
+void XGUI_AbstractRubberBand::clearGeometry()
+{
+ myPoints.clear();
+}
+
+bool XGUI_AbstractRubberBand::isClosed()
+{
+ return myIsClosed;
+}
+
+void XGUI_AbstractRubberBand::paintEvent( QPaintEvent* theEvent )
+{
+ if ( !myPoints.empty() ) {
+ QPixmap tiledPixmap(16, 16);
+
+ QPainter pixmapPainter(&tiledPixmap);
+ pixmapPainter.setPen(Qt::NoPen);
+ pixmapPainter.setBrush(QBrush( Qt::black, Qt::Dense4Pattern ));
+ pixmapPainter.setBackground(QBrush( Qt::white ));
+ pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
+ pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
+ pixmapPainter.end();
+ // ### workaround for borked XRENDER
+ tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
+
+ QPainter aPainter( this );
+ aPainter.setRenderHint( QPainter::Antialiasing );
+ QRect r = myPoints.boundingRect();
+ aPainter.setClipRegion( r.normalized().adjusted( -1, -1, 2, 2 ) );
+ aPainter.drawTiledPixmap( 0, 0, width(), height(), tiledPixmap);
+
+ aPainter.end();
+ }
+}
+
+void XGUI_AbstractRubberBand::showEvent( QShowEvent* theEvent )
+{
+ raise();
+ theEvent->ignore();
+}
+
+void XGUI_AbstractRubberBand::moveEvent( QMoveEvent* )
+{
+}
+
+void XGUI_AbstractRubberBand::resizeEvent( QResizeEvent* )
+{
+}
+
+bool XGUI_AbstractRubberBand::eventFilter( QObject* obj, QEvent* e )
+{
+ if ( obj && obj == parent() && e->type() == QEvent::Resize ) {
+ QWidget* p = (QWidget*)parent();
+ setGeometry( QRect(QPoint(0,0), p->size() ) );
+ }
+ return QWidget::eventFilter( obj, e );
+}
+
+QRegion createRegion( const QPointF& p1, const QPointF& p2 )
+{
+ if ( p1 == p2 )
+ return QRegion();
+
+ QLineF n = QLineF( p1, p2 ).normalVector();//.unitVector();
+ n.setLength( 1 );
+ n.translate( p1 * -1 );
+ QPointF nPoint = n.p2();
+
+ QPolygonF p;
+ p << p1 + nPoint << p2 + nPoint << p2 - nPoint << p1 - nPoint << p1 + nPoint;
+
+ return QRegion( p.toPolygon() );
+}
+
+void XGUI_AbstractRubberBand::updateMask()
+{
+ QRegion r;
+
+ QVectorIterator<QPoint> it(myPoints);
+ while( it.hasNext() ) {
+ QPoint p = it.next();
+ if( !it.hasNext() )
+ break;
+
+ QPoint np = it.peekNext();
+
+ if ( p == np ) continue;
+
+ r += createRegion( p, np );
+ }
+
+ if ( isClosed() )
+ r += createRegion( myPoints.last(), myPoints.first() );
+
+ setMask( r );
+}
+
+
+//**********************************************************
+XGUI_RectRubberBand::XGUI_RectRubberBand(QWidget* parent)
+ :XGUI_AbstractRubberBand( parent )
+{
+ myPoints.resize( 4 );
+ myIsClosed = true;
+}
+
+XGUI_RectRubberBand::~XGUI_RectRubberBand()
+{
+}
+
+void XGUI_RectRubberBand::initGeometry( const QRect& theRect )
+{
+ myPoints.clear();
+ myPoints << theRect.topLeft() << theRect.topRight() << theRect.bottomRight() << theRect.bottomLeft();
+ //setMask( QRegion( myPoints ) );
+ updateMask();
+}
+
+void XGUI_RectRubberBand::setStartPoint( const QPoint& thePoint )
+{
+ myPoints[0] = thePoint;
+ myPoints[1].setY( thePoint.y() );
+ myPoints[3].setX( thePoint.x() );
+ updateMask();
+}
+
+void XGUI_RectRubberBand::setEndPoint( const QPoint& thePoint)
+{
+ myPoints[2] = thePoint;
+ myPoints[1].setX( thePoint.x() );
+ myPoints[3].setY( thePoint.y() );
+ updateMask();
+}
+
+void XGUI_RectRubberBand::clearGeometry()
+{
+ QMutableVectorIterator<QPoint> i(myPoints);
+ while (i.hasNext()) {
+ i.next();
+ i.setValue( QPoint( -1, -1 ) );
+ }
+}
+
+//**********************************************************
+XGUI_PolyRubberBand::XGUI_PolyRubberBand(QWidget* parent)
+ :XGUI_AbstractRubberBand( parent )
+{
+}
+
+XGUI_PolyRubberBand::~XGUI_PolyRubberBand()
+{
+}
+
+void XGUI_PolyRubberBand::initGeometry( const QPolygon& thePoints )
+{
+ myPoints = thePoints;
+ updateMask();
+}
+
+void XGUI_PolyRubberBand::initGeometry( const QPoint& thePoint )
+{
+ myPoints.clear();
+ myPoints << thePoint;
+ updateMask();
+}
+
+void XGUI_PolyRubberBand::addNode( const QPoint& thePoint )
+{
+ myPoints << thePoint;
+ updateMask();
+}
+
+void XGUI_PolyRubberBand::replaceLastNode( const QPoint& thePoint )
+{
+ if ( !myPoints.empty() ) {
+ myPoints.pop_back();
+ myPoints << thePoint;
+ updateMask();
+ }
+}
+
+void XGUI_PolyRubberBand::removeLastNode()
+{
+ if ( !myPoints.empty() ) {
+ myPoints.pop_back();
+ updateMask();
+ }
+}
+
+void XGUI_PolyRubberBand::setClosed( bool theFlag )
+{
+ if (myIsClosed != theFlag ) {
+ myIsClosed = theFlag;
+ updateMask();
+ }
+}
--- /dev/null
+
+#ifndef XGUI_RubberBand_H
+#define XGUI_RubberBand_H
+
+#include <QWidget>
+
+
+class XGUI_AbstractRubberBand : public QWidget
+{
+ Q_OBJECT
+protected:
+ XGUI_AbstractRubberBand( QWidget* );
+
+public:
+ virtual ~XGUI_AbstractRubberBand();
+
+ virtual void clearGeometry();
+
+ bool isClosed();
+
+protected:
+ virtual void paintEvent( QPaintEvent* );
+ virtual void showEvent( QShowEvent* );
+ virtual void moveEvent( QMoveEvent* );
+ virtual void resizeEvent( QResizeEvent* );
+
+ virtual bool eventFilter( QObject*, QEvent* );
+
+ virtual void updateMask();
+
+protected:
+ QPolygon myPoints;
+
+ bool myIsClosed;
+};
+
+
+class XGUI_RectRubberBand: public XGUI_AbstractRubberBand
+{
+ Q_OBJECT
+
+public:
+ XGUI_RectRubberBand( QWidget* );
+ virtual ~XGUI_RectRubberBand();
+
+ void initGeometry( const QRect& );
+ void setStartPoint( const QPoint& );
+ void setEndPoint( const QPoint& );
+
+ virtual void clearGeometry();
+};
+
+class XGUI_PolyRubberBand: public XGUI_AbstractRubberBand
+{
+ Q_OBJECT
+
+public:
+ XGUI_PolyRubberBand( QWidget* );
+ virtual ~XGUI_PolyRubberBand();
+
+ void initGeometry( const QPolygon& );
+ void initGeometry( const QPoint& );
+
+ void addNode( const QPoint& );
+ void replaceLastNode( const QPoint& );
+ void removeLastNode();
+
+ void setClosed( bool );
+};
+
+
+#endif
\ No newline at end of file
res += QDir::separator();
return res;
}
+
+//******************************************************************
+QRect makeRect( const int x1, const int y1, const int x2, const int y2 )
+{
+ return QRect( qMin( x1, x2 ), qMin( y1, y2 ), qAbs( x2 - x1 ), qAbs( y2 - y1 ) );
+}
#define XGUI_Tools_H
#include <QString>
+#include <QRect>
/*!
\brief Convert the given parameter to the platform-specific library name.
\param path file path
\param full if true complete extension (all extensions, dot separated)
is returned, otherwise (default) only last extension is returned
- \return extension part of the file path
+ \return extension part of the file path
*/
QString extension( const QString& path, bool full = false );
*/
QString addSlash( const QString& path );
+/*!
+ Creates a rect with TopLeft = ( min(x1,x2), min(y1,y2) )
+ and BottomRight = ( TopLeft + (x2-x1)(y2-y1) )
+*/
+QRect makeRect( const int x1, const int y1, const int x2, const int y2 );
+
+
#endif
\ No newline at end of file
#include "XGUI_ViewPort.h"
#include "XGUI_ViewWindow.h"
#include "XGUI_Viewer.h"
+#include "XGUI_Constants.h"
#include <QGuiApplication>
#include <QPaintEvent>
#include <GL/gl.h>
+static double rx = 0.;
+static double ry = 0.;
+static int sx = 0;
+static int sy = 0;
+static Standard_Boolean zRotation = Standard_False;
+
+
+
/*!
Create native view window for CasCade view [ static ]
*/
const Handle(V3d_Viewer)& theViewer,
V3d_TypeOfView theType) :
QWidget(theParent),
- myPaintersRedrawing(false)
+ myPaintersRedrawing(false),
+ myScale( 1.0 ),
+ myIsAdvancedZoomingEnabled( false )
{
setMouseTracking( true );
setBackgroundRole( QPalette::NoRole );
myPerspView = new V3d_PerspectiveView( theViewer );
myActiveView = myPerspView;
}
+ myActiveView->SetSurfaceDetail(V3d_TEX_ALL);
+
//setBackground( Qtx::BackgroundData( Qt::black ) ); // set default background
}
//if ( !myPaintersRedrawing ) {
//activeView()->Redraw();
activeView()->Redraw( rc.x(), rc.y(), rc.width(), rc.height() );
+ emit vpUpdated();
//}
}
//if ( myPaintersRedrawing ) {
anImage = anImage.rgbSwapped();
return anImage;
}
+
+
+/*!
+ Inits 'rotation' transformation.
+*/
+void XGUI_ViewPort::startRotation( int x, int y,
+ int theRotationPointType,
+ const gp_Pnt& theSelectedPoint )
+{
+ if ( !activeView().IsNull() ) {
+ switch ( theRotationPointType ) {
+ case XGUI::GRAVITY:
+ activeView()->StartRotation( x, y, 0.45 );
+ break;
+ case XGUI::SELECTED:
+ sx = x; sy = y;
+
+ double X,Y;
+ activeView()->Size(X,Y);
+ rx = Standard_Real(activeView()->Convert(X));
+ ry = Standard_Real(activeView()->Convert(Y));
+
+ activeView()->Rotate( 0., 0., 0.,
+ theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
+ Standard_True );
+
+ Quantity_Ratio zRotationThreshold;
+ zRotation = Standard_False;
+ zRotationThreshold = 0.45;
+ if( zRotationThreshold > 0. ) {
+ Standard_Real dx = Abs(sx - rx/2.);
+ Standard_Real dy = Abs(sy - ry/2.);
+ Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
+ if( dx > dd || dy > dd ) zRotation = Standard_True;
+ }
+ break;
+ default:
+ break;
+ }
+ activeView()->DepthFitAll();
+ }
+}
+
+/*!
+ Rotates the viewport.
+*/
+void XGUI_ViewPort::rotate( int x, int y,
+ int theRotationPointType,
+ const gp_Pnt& theSelectedPoint )
+{
+ if ( !activeView().IsNull() ) {
+ switch ( theRotationPointType ) {
+ case XGUI::GRAVITY:
+ activeView()->Rotation( x, y );
+ break;
+ case XGUI::SELECTED:
+ double dx, dy, dz;
+ if( zRotation ) {
+ dz = atan2(Standard_Real(x)-rx/2., ry/2.-Standard_Real(y)) -
+ atan2(sx-rx/2.,ry/2.-sy);
+ dx = dy = 0.;
+ }
+ else {
+ dx = (Standard_Real(x) - sx) * M_PI/rx;
+ dy = (sy - Standard_Real(y)) * M_PI/ry;
+ dz = 0.;
+ }
+
+ activeView()->Rotate( dx, dy, dz,
+ theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
+ Standard_False );
+ break;
+ default:
+ break;
+ }
+ emit vpTransformed( );
+ }
+ // setZSize( getZSize() );
+}
+
+/*!
+ Resets the viewport after 'rotation'.
+*/
+void XGUI_ViewPort::endRotation()
+{
+ if ( !activeView().IsNull() ) {
+ activeView()->ZFitAll(1.);
+ activeView()->SetZSize(0.);
+ activeView()->Update();
+ emit vpTransformed( );
+ }
+}
+
+/*!
+ Inits 'zoom' transformation.
+*/
+void XGUI_ViewPort::startZoomAtPoint( int x, int y )
+{
+ if ( !activeView().IsNull()/* && isAdvancedZoomingEnabled() */)
+ activeView()->StartZoomAtPoint( x, y );
+}
+
+/*!
+ Centers the viewport.
+*/
+void XGUI_ViewPort::setCenter( int x, int y )
+{
+ if ( !activeView().IsNull() ) {
+ activeView()->Place( x, y, myScale );
+ emit vpTransformed( );
+ }
+}
+
+/*!
+ Called at 'pan' transformation.
+ */
+void XGUI_ViewPort::pan( int dx, int dy )
+{
+ if ( !activeView().IsNull() ) {
+ activeView()->Pan( dx, dy, 1.0 );
+ emit vpTransformed( );
+ }
+}
+
+/*!
+ Called at 'window fit' transformation.
+*/
+void XGUI_ViewPort::fitRect( const QRect& rect )
+{
+ if ( !activeView().IsNull() ) {
+ activeView()->WindowFit( rect.left(), rect.top(), rect.right(), rect.bottom() );
+ emit vpTransformed( );
+ }
+}
+
+/*!
+ Called at 'zoom' transformation.
+*/
+void XGUI_ViewPort::zoom( int x0, int y0, int x, int y )
+{
+ if ( !activeView().IsNull() ) {
+ if ( isAdvancedZoomingEnabled() )
+ activeView()->ZoomAtPoint( x0, y0, x, y );
+ else
+ activeView()->Zoom( x0 + y0, 0, x + y, 0 );
+ emit vpTransformed( );
+ }
+}
#include <QWidget>
#include <V3d_Viewer.hxx>
#include <V3d_View.hxx>
+#include <gp_Pnt.hxx>
class XGUI_ViewWindow;
Handle(V3d_View) getView() const { return activeView(); }
+ void startRotation( int x, int y, int theRotationPointType, const gp_Pnt& theSelectedPoint );
+ void rotate( int, int, int, const gp_Pnt& );
+ void endRotation();
+
+ // TRANSFORMATIONS
+ void pan( int dx, int dy );
+ void setCenter( int x, int y );
+ void fitRect( const QRect& rect );
+ void startZoomAtPoint( int x, int y );
+ void zoom( int x0, int y0, int x, int y );
+
+ void setAdvancedZoomingEnabled( const bool theState ) { myIsAdvancedZoomingEnabled = theState; }
+ bool isAdvancedZoomingEnabled() const { return myIsAdvancedZoomingEnabled; }
+
signals:
//void vpChangeBackground( const Qtx::BackgroundData& );
- void vpClosed();
- void vpMapped();
-
+ void vpClosed();
+ void vpMapped();
+ void vpTransformed( );
+ void vpUpdated();
protected:
virtual void paintEvent( QPaintEvent* );
Handle(Aspect_Window) myWindow;
bool myPaintersRedrawing;
+ bool myIsAdvancedZoomingEnabled;
+
+ double myScale;
};
#include "XGUI_ViewWindow.h"
#include "XGUI_ViewPort.h"
#include "XGUI_Viewer.h"
+#include "XGUI_Tools.h"
+#include "XGUI_RubberBand.h"
#include <QLayout>
#include <QLabel>
#include <QPainter>
#include <QTime>
+#include <TopoDS_Shape.hxx>
+#include <BRep_Tool.hxx>
+#include <TopoDS.hxx>
+
#define BORDER_SIZE 2
+const char* imageZoomCursor[] = {
+"32 32 3 1",
+". c None",
+"a c #000000",
+"# c #ffffff",
+"................................",
+"................................",
+".#######........................",
+"..aaaaaaa.......................",
+"................................",
+".............#####..............",
+"...........##.aaaa##............",
+"..........#.aa.....a#...........",
+".........#.a.........#..........",
+".........#a..........#a.........",
+"........#.a...........#.........",
+"........#a............#a........",
+"........#a............#a........",
+"........#a............#a........",
+"........#a............#a........",
+".........#...........#.a........",
+".........#a..........#a.........",
+".........##.........#.a.........",
+"........#####.....##.a..........",
+".......###aaa#####.aa...........",
+"......###aa...aaaaa.......#.....",
+".....###aa................#a....",
+"....###aa.................#a....",
+"...###aa...............#######..",
+"....#aa.................aa#aaaa.",
+".....a....................#a....",
+"..........................#a....",
+"...........................a....",
+"................................",
+"................................",
+"................................",
+"................................"};
+
+const char* imageRotateCursor[] = {
+"32 32 3 1",
+". c None",
+"a c #000000",
+"# c #ffffff",
+"................................",
+"................................",
+"................................",
+"................................",
+"........#.......................",
+".......#.a......................",
+"......#######...................",
+".......#aaaaa#####..............",
+"........#..##.a#aa##........##..",
+".........a#.aa..#..a#.....##.aa.",
+".........#.a.....#...#..##.aa...",
+".........#a.......#..###.aa.....",
+"........#.a.......#a..#aa.......",
+"........#a.........#..#a........",
+"........#a.........#a.#a........",
+"........#a.........#a.#a........",
+"........#a.........#a.#a........",
+".........#.........#a#.a........",
+"........##a........#a#a.........",
+"......##.a#.......#.#.a.........",
+"....##.aa..##.....##.a..........",
+"..##.aa.....a#####.aa...........",
+"...aa.........aaa#a.............",
+"................#.a.............",
+"...............#.a..............",
+"..............#.a...............",
+"...............a................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................"};
+
+const char* imageCrossCursor[] = {
+ "32 32 3 1",
+ ". c None",
+ "a c #000000",
+ "# c #ffffff",
+ "................................",
+ "................................",
+ "................................",
+ "................................",
+ "................................",
+ "................................",
+ "................................",
+ "...............#................",
+ "...............#a...............",
+ "...............#a...............",
+ "...............#a...............",
+ "...............#a...............",
+ "...............#a...............",
+ "...............#a...............",
+ "...............#a...............",
+ ".......#################........",
+ "........aaaaaaa#aaaaaaaaa.......",
+ "...............#a...............",
+ "...............#a...............",
+ "...............#a...............",
+ "...............#a...............",
+ "...............#a...............",
+ "...............#a...............",
+ "...............#a...............",
+ "................a...............",
+ "................................",
+ "................................",
+ "................................",
+ "................................",
+ "................................",
+ "................................",
+ "................................"};
+
//**************************************************************************
void ViewerToolbar::paintEvent( QPaintEvent* theEvent)
{
- QTime aTime;
- aTime.start();
+ //QTime aTime;
+ //aTime.start();
QRect aRect = rect();
QRect aVPRect = myVPort->rect();
QPoint aGlobPnt = mapToGlobal(aRect.topLeft());
QRect aImgRect(QRect(aPnt.x(), aPnt.y() + aVPRect.height() - aRect.height(), aRect.width(), aRect.height()));
QPainter(this).drawImage(aRect, myVPort->dumpView(aImgRect, false));
- QString aMsg = QString("### Painted in %1").arg(aTime.elapsed());
- qDebug(qPrintable(aMsg));
+ //QString aMsg = QString("### Painted in %1").arg(aTime.elapsed());
+ //qDebug(qPrintable(aMsg));
}
//**************************************************************************
MinimizeIco(":pictures/wnd_minimize.png"),
MaximizeIco(":pictures/wnd_maximize.png"),
CloseIco(":pictures/wnd_close.png"),
- RestoreIco(":pictures/wnd_restore.png")
+ RestoreIco(":pictures/wnd_restore.png"),
+ myInteractionStyle(XGUI::STANDARD),
+ myRectBand(0),
+ myIsKeyFree(false),
+ my2dMode(XGUI::No2dMode),
+ myCurrPointType(XGUI::GRAVITY),
+ myPrevPointType(XGUI::GRAVITY),
+ myRotationPointSelection(false)
{
+ mySelectedPoint = gp_Pnt(0.,0.,0.);
setFrameStyle(QFrame::Raised);
setFrameShape(QFrame::Panel);
setLineWidth(BORDER_SIZE);
QVBoxLayout* aLay = new QVBoxLayout(this);
aLay->setContentsMargins(BORDER_SIZE,BORDER_SIZE,BORDER_SIZE,BORDER_SIZE);
myViewPort = new XGUI_ViewPort(this, myViewer->v3dViewer(), theType);
+ myViewPort->installEventFilter(this);
aLay->addWidget(myViewPort);
myPicture = new QLabel();
myGripWgt->setGeometry(BORDER_SIZE + 2, BORDER_SIZE + 2, 19, 32);
myGripWgt->setMouseTracking(true);
myGripWgt->installEventFilter(this);
+ connect(myViewPort, SIGNAL(vpTransformed()), myGripWgt, SLOT(update()));
+ connect(myViewPort, SIGNAL(vpUpdated()), myGripWgt, SLOT(update()));
myViewBar = new ViewerToolbar(this, myViewPort);
aBtn = new QAction(QIcon(aPictures.at(i)), aTitles.at(i), myViewBar);
myViewBar->addAction(aBtn);
}
+ connect(myViewPort, SIGNAL(vpTransformed()), myViewBar, SLOT(update()));
+ connect(myViewPort, SIGNAL(vpUpdated()), myViewBar, SLOT(update()));
myWindowBar = new ViewerToolbar(this, myViewPort);
+ connect(myViewPort, SIGNAL(vpTransformed()), myWindowBar, SLOT(update()));
+ connect(myViewPort, SIGNAL(vpUpdated()), myWindowBar, SLOT(update()));
myMinimizeBtn = new QAction(myWindowBar);
myMinimizeBtn->setIcon(MinimizeIco);
}
//****************************************************************
-bool XGUI_ViewWindow::eventFilter(QObject *theObj, QEvent *theEvent)
+bool XGUI_ViewWindow::processWindowControls(QObject *theObj, QEvent *theEvent)
{
- if ((theObj == myGripWgt) || (theObj == myPicture)) {
- QWidget* aWgt = (theObj == myPicture)? myPicture : static_cast<QWidget*>(parentWidget());
- switch (theEvent->type()) {
- case QEvent::MouseButtonPress:
- {
- QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
- if ((aEvent->button() == Qt::LeftButton) && (!myMoving)){
- myMoving = true;
- myMousePnt = aEvent->globalPos();
- return true;
- }
+ QWidget* aWgt = (theObj == myPicture)? myPicture : static_cast<QWidget*>(parentWidget());
+ switch (theEvent->type()) {
+ case QEvent::MouseButtonPress:
+ {
+ QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
+ if ((aEvent->button() == Qt::LeftButton) && (!myMoving)){
+ myMoving = true;
+ myMousePnt = aEvent->globalPos();
+ return true;
}
- break;
- case QEvent::MouseButtonRelease:
- {
- QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
- if ((aEvent->button() == Qt::LeftButton) && myMoving) {
- myMoving = false;
- return true;
- }
+ }
+ break;
+ case QEvent::MouseButtonRelease:
+ {
+ QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
+ if ((aEvent->button() == Qt::LeftButton) && myMoving) {
+ myMoving = false;
+ return true;
}
- break;
- case QEvent::MouseMove:
- {
- QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
- if (myMoving) {
- QMdiSubWindow* aParent = static_cast<QMdiSubWindow*>(parentWidget());
- QMdiArea* aMDIArea = aParent->mdiArea();
+ }
+ break;
+ case QEvent::MouseMove:
+ {
+ QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
+ if (myMoving) {
+ QMdiSubWindow* aParent = static_cast<QMdiSubWindow*>(parentWidget());
+ QMdiArea* aMDIArea = aParent->mdiArea();
- QPoint aPnt = aEvent->globalPos();
- QPoint aMDIPnt = aMDIArea->mapFromGlobal(aPnt);
- if (aMDIArea->rect().contains(aMDIPnt)) {
- int aX = aWgt->x() + (aPnt.x() - myMousePnt.x());
- int aY = aWgt->y() + (aPnt.y() - myMousePnt.y());
- aWgt->move(aX, aY);
- myMousePnt = aPnt;
- }
- return true;
+ QPoint aPnt = aEvent->globalPos();
+ QPoint aMDIPnt = aMDIArea->mapFromGlobal(aPnt);
+ if (aMDIArea->rect().contains(aMDIPnt)) {
+ int aX = aWgt->x() + (aPnt.x() - myMousePnt.x());
+ int aY = aWgt->y() + (aPnt.y() - myMousePnt.y());
+ aWgt->move(aX, aY);
+ myMousePnt = aPnt;
}
+ return true;
}
}
- if ((theObj == myPicture) && (theEvent->type() == QEvent::MouseButtonDblClick)) {
+ break;
+ case QEvent::MouseButtonDblClick:
+ if (theObj == myPicture) {
myMoving = false;
if (myLastState == MaximizedState)
showMaximized();
return true;
}
}
+ return false;
+}
+
+//****************************************************************
+bool XGUI_ViewWindow::processViewPort(QEvent *theEvent)
+{
+ switch(theEvent->type()) {
+ case QEvent::MouseButtonPress:
+ vpMousePressEvent((QMouseEvent*) theEvent);
+ return true;
+
+ case QEvent::MouseButtonRelease:
+ vpMouseReleaseEvent((QMouseEvent*) theEvent);
+ return true;
+
+ case QEvent::MouseMove:
+ vpMouseMoveEvent((QMouseEvent*) theEvent);
+ return true;
+
+ case QEvent::MouseButtonDblClick:
+ emit mouseDoubleClicked(this, (QMouseEvent*)theEvent);
+ return true;
+ }
+ return false;
+}
+
+//****************************************************************
+bool XGUI_ViewWindow::eventFilter(QObject *theObj, QEvent *theEvent)
+{
+ if ((theObj == myGripWgt) || (theObj == myPicture)) {
+ if (processWindowControls(theObj, theEvent) )
+ return true;
+ } else if (theObj == myViewPort) {
+ if (processViewPort(theEvent))
+ return true;
+ }
return QFrame::eventFilter(theObj, theEvent);
}
+//****************************************************************
+XGUI_ViewWindow::OperationType XGUI_ViewWindow::getButtonState(QMouseEvent* theEvent,
+ XGUI::InteractionStyle theInteractionStyle)
+{
+ OperationType aOp = NOTHING;
+ XGUI::InteractionStyle aStyle = (XGUI::InteractionStyle)theInteractionStyle;
+ if( (theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ZOOM]) &&
+ (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ZOOM]) )
+ aOp = ZOOMVIEW;
+ else if( (theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::PAN]) &&
+ (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::PAN]) )
+ aOp = PANVIEW;
+ else if( (theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ROTATE]) &&
+ (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ROTATE]) &&
+ (my2dMode == XGUI::No2dMode))
+ aOp = ROTATE;
+
+ return aOp;
+}
+
+//****************************************************************
+void XGUI_ViewWindow::vpMousePressEvent(QMouseEvent* theEvent)
+{
+ myStartX = theEvent->x();
+ myStartY = theEvent->y();
+ XGUI::InteractionStyle anInteractionStyle = interactionStyle();
+
+ // in "key free" interaction style zoom operation is activated by two buttons (simultaneously pressed),
+ // which are assigned for pan and rotate - these operations are activated immediately after pressing
+ // of the first button, so it is necessary to switch to zoom when the second button is pressed
+ bool aSwitchToZoom = false;
+ if ((anInteractionStyle == XGUI::KEY_FREE) && (myOperation == PANVIEW || myOperation == ROTATE)) {
+ aSwitchToZoom = getButtonState( theEvent, anInteractionStyle ) == ZOOMVIEW;
+ }
+
+ switch ( myOperation ) {
+ case WINDOWFIT:
+ if ( theEvent->button() == Qt::LeftButton )
+ emit vpTransformationStarted ( WINDOWFIT );
+ break;
+
+ case PANGLOBAL:
+ if ( theEvent->button() == Qt::LeftButton )
+ emit vpTransformationStarted ( PANGLOBAL );
+ break;
+
+ case ZOOMVIEW:
+ if ( theEvent->button() == Qt::LeftButton ) {
+ myViewPort->startZoomAtPoint( myStartX, myStartY );
+ emit vpTransformationStarted ( ZOOMVIEW );
+ }
+ break;
+
+ case PANVIEW:
+ if ( aSwitchToZoom ) {
+ myViewPort->startZoomAtPoint( myStartX, myStartY );
+ activateZoom();
+ } else if ( theEvent->button() == Qt::LeftButton )
+ emit vpTransformationStarted ( PANVIEW );
+ break;
+
+ case ROTATE:
+ if ( aSwitchToZoom ) {
+ myViewPort->startZoomAtPoint( myStartX, myStartY );
+ activateZoom();
+ } else if ( theEvent->button() == Qt::LeftButton ) {
+ myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
+ emit vpTransformationStarted ( ROTATE );
+ }
+ break;
+
+ default:
+ /* Try to activate a transformation */
+ OperationType aState;
+ if ( interactionStyle() == XGUI::STANDARD )
+ aState = getButtonState(theEvent, anInteractionStyle);
+ else {
+ aState = XGUI_ViewWindow::NOTHING;
+ myIsKeyFree = true;
+ }
+ switch ( aState ) {
+ case ZOOMVIEW:
+ myViewPort->startZoomAtPoint( myStartX, myStartY );
+ activateZoom();
+ break;
+ case PANVIEW:
+ activatePanning();
+ break;
+ case ROTATE:
+ activateRotation();
+ myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
+ break;
+ default:
+ if ( myRotationPointSelection ) {
+ if ( theEvent->button() == Qt::LeftButton ) {
+ Handle(AIS_InteractiveContext) ic = myViewer->AISContext();
+ ic->Select();
+ for ( ic->InitSelected(); ic->MoreSelected(); ic->NextSelected() ) {
+ TopoDS_Shape aShape = ic->SelectedShape();
+ if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX ) {
+ gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) );
+ /*if ( mySetRotationPointDlg ) {
+ myRotationPointSelection = false;
+ mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z());
+ }*/
+ } else {
+ myCurrPointType = myPrevPointType;
+ break;
+ }
+ }
+ if ( ic->NbSelected() == 0 ) myCurrPointType = myPrevPointType;
+ //if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange();
+ ic->CloseAllContexts();
+ myOperation = NOTHING;
+ myViewPort->setCursor( myCursor );
+ myCursorIsHand = false;
+ myRotationPointSelection = false;
+ }
+ } else
+ emit mousePressed(this, theEvent);
+ break;
+ }
+ /* notify that we start a transformation */
+ if ( transformRequested() )
+ emit vpTransformationStarted ( myOperation );
+ }
+ if ( transformRequested() )
+ setTransformInProcess( true );
+
+ /* we may need it for sketching... */
+/* if ( l_mbPressEvent )
+ delete l_mbPressEvent;
+ l_mbPressEvent = new QMouseEvent( *theEvent );*/
+}
+
+//****************************************************************
+void XGUI_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
+{
+ switch ( myOperation ) {
+ case NOTHING:
+ {
+ int prevState = myCurSketch;
+/* if(theEvent->button() == Qt::RightButton) {
+ QList<OCCViewer_ViewSketcher*>::Iterator it;
+ for ( it = mySketchers.begin(); it != mySketchers.end() && myCurSketch != -1; ++it ) {
+ OCCViewer_ViewSketcher* sk = (*it);
+ if( ( sk->sketchButton() & theEvent->button() ) && sk->sketchButton() == myCurSketch )
+ myCurSketch = -1;
+ }
+ }
+ */
+ emit mouseReleased(this, theEvent);
+ if (theEvent->button() == Qt::RightButton && prevState == -1) {
+ QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
+ theEvent->pos(), theEvent->globalPos() );
+ emit contextMenuRequested( &aEvent );
+ }
+ }
+ break;
+ case ROTATE:
+ myViewPort->endRotation();
+ resetState();
+ break;
+
+ case PANVIEW:
+ case ZOOMVIEW:
+ resetState();
+ break;
+
+ case PANGLOBAL:
+ if ( theEvent->button() == Qt::LeftButton ) {
+ myViewPort->setCenter( theEvent->x(), theEvent->y() );
+ myViewPort->getView()->SetScale(myCurScale);
+ resetState();
+ }
+ break;
+
+ case WINDOWFIT:
+ if ( theEvent->button() == Qt::LeftButton ) {
+ myCurrX = theEvent->x();
+ myCurrY = theEvent->y();
+ drawRect();
+ QRect rect = makeRect(myStartX, myStartY, myCurrX, myCurrY);
+ if ( !rect.isEmpty() ) myViewPort->fitRect(rect);
+ endDrawRect();
+ resetState();
+ }
+ break;
+ }
+
+ // NOTE: viewer 3D detects a rectangle of selection using this event
+ // so we must emit it BEFORE resetting the selection rectangle
+ if ( theEvent->button() == Qt::LeftButton && myDrawRect ) {
+ drawRect();
+ endDrawRect();
+ resetState();
+ myViewPort->update();
+ }
+/* if ( l_mbPressEvent ) {
+ delete l_mbPressEvent;
+ l_mbPressEvent = 0;
+ }*/
+}
+
+//****************************************************************
+void XGUI_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent)
+{
+ if ( myIsKeyFree && interactionStyle() == XGUI::KEY_FREE ) {
+ myIsKeyFree = false;
+ switch ( getButtonState( theEvent, interactionStyle() ) ) {
+ case ZOOMVIEW:
+ myViewPort->startZoomAtPoint( myStartX, myStartY );
+ activateZoom();
+ break;
+ case PANVIEW:
+ activatePanning();
+ break;
+ case ROTATE:
+ activateRotation();
+ myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
+ break;
+ default:
+ break;
+ }
+ }
+
+ myCurrX = theEvent->x();
+ myCurrY = theEvent->y();
+ switch (myOperation) {
+ case ROTATE:
+ myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint);
+ break;
+
+ case ZOOMVIEW:
+ myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY);
+ myStartX = myCurrX;
+ myStartY = myCurrY;
+ break;
+
+ case PANVIEW:
+ myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY);
+ myStartX = myCurrX;
+ myStartY = myCurrY;
+ break;
+
+ case PANGLOBAL:
+ break;
+
+ default:
+ if ( myRotationPointSelection /*|| isSketcherStyle()*/ ) {
+ emit mouseMoving( this, theEvent );
+ } else {
+ int aState = theEvent->modifiers();
+ int aButton = theEvent->buttons();
+ int anInteractionStyle = interactionStyle();
+ if ( ( (anInteractionStyle == XGUI::STANDARD) &&
+ (aButton == Qt::LeftButton) &&
+ (aState == Qt::NoModifier || Qt::ShiftModifier) ) ||
+ ( (anInteractionStyle == XGUI::KEY_FREE) &&
+ (aButton == Qt::LeftButton) &&
+ ( aState == Qt::ControlModifier || aState == (Qt::ControlModifier|Qt::ShiftModifier) ) ) ) {
+ myDrawRect = myEnableDrawMode;
+ if ( myDrawRect ) {
+ drawRect();
+ if ( !myCursorIsHand ) { // we are going to sketch a rectangle
+ QCursor handCursor (Qt::PointingHandCursor);
+ myCursorIsHand = true;
+ myCursor = cursor();
+ myViewPort->setCursor( handCursor );
+ }
+ }
+ emit mouseMoving( this, theEvent );
+ } /* else if ( ( (anInteractionStyle == XGUI::STANDARD) &&
+ (aButton == Qt::RightButton) &&
+ ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) ||
+ ( (anInteractionStyle == XGUI::KEY_FREE) &&
+ (aButton == Qt::RightButton) &&
+ ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) {
+ OCCViewer_ViewSketcher* sketcher = 0;
+ QList<OCCViewer_ViewSketcher*>::Iterator it;
+ for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) {
+ OCCViewer_ViewSketcher* sk = (*it);
+ if( sk->isDefault() && sk->sketchButton() == aButton )
+ sketcher = sk;
+ }
+ if ( sketcher && myCurSketch == -1 ) {
+ activateSketching( sketcher->type() );
+ if ( mypSketcher ) {
+ myCurSketch = mypSketcher->sketchButton();
+
+ if ( l_mbPressEvent ) {
+ QApplication::sendEvent( getViewPort(), l_mbPressEvent );
+ delete l_mbPressEvent;
+ l_mbPressEvent = 0;
+ }
+ QApplication::sendEvent( getViewPort(), theEvent );
+ }
+ }
+ } */else
+ emit mouseMoving( this, theEvent );
+ }
+ }
+}
+
+
+/*!
+ \brief Draw rubber band rectangle.
+*/
+void XGUI_ViewWindow::drawRect()
+{
+ if ( !myRectBand ) {
+ myRectBand = new XGUI_RectRubberBand( myViewPort );
+ }
+
+ myRectBand->setUpdatesEnabled ( false );
+ QRect aRect = makeRect(myStartX, myStartY, myCurrX, myCurrY);
+ myRectBand->initGeometry( aRect );
+
+ if ( !myRectBand->isVisible() )
+ myRectBand->show();
+
+ myRectBand->setUpdatesEnabled ( true );
+}
+
+/*!
+ \brief Clear rubber band rectangle on the end on the dragging operation.
+*/
+void XGUI_ViewWindow::endDrawRect()
+{
+ if ( myRectBand ) {
+ myRectBand->clearGeometry();
+ myRectBand->hide();
+ }
+}
+
+void XGUI_ViewWindow::activateZoom()
+{
+ if ( !transformRequested() && !myCursorIsHand )
+ myCursor = cursor(); /* save old cursor */
+
+ if ( myOperation != ZOOMVIEW ) {
+ QPixmap zoomPixmap (imageZoomCursor);
+ QCursor zoomCursor (zoomPixmap);
+ if( setTransformRequested ( ZOOMVIEW ) )
+ myViewPort->setCursor( zoomCursor );
+ }
+}
+
+bool XGUI_ViewWindow::transformRequested() const
+{
+ return ( myOperation != NOTHING );
+}
+
+/*!
+ \brief Start delayed viewer operation.
+*/
+bool XGUI_ViewWindow::setTransformRequested( OperationType op )
+{
+ bool ok = transformEnabled( op );
+ myOperation = ok ? op : NOTHING;
+ myViewPort->setMouseTracking( myOperation == NOTHING );
+ return ok;
+}
+
+/*!
+ Set enabled state of transformation (rotate, zoom, etc)
+*/
+void XGUI_ViewWindow::setTransformEnabled( const OperationType id, const bool on )
+{
+ if ( id != NOTHING ) myStatus.insert( id, on );
+}
+
+/*!
+ \return enabled state of transformation (rotate, zoom, etc)
+*/
+bool XGUI_ViewWindow::transformEnabled( const OperationType id ) const
+{
+ return myStatus.contains( id ) ? myStatus[ id ] : true;
+}
+
+
+/*!
+ \brief Start panning operation.
+
+ Sets the corresponding cursor for the widget.
+*/
+void XGUI_ViewWindow::activatePanning()
+{
+ if ( !transformRequested() && !myCursorIsHand )
+ myCursor = cursor(); // save old cursor
+
+ if ( myOperation != PANVIEW ) {
+ QCursor panCursor (Qt::SizeAllCursor);
+ if( setTransformRequested ( PANVIEW ) )
+ myViewPort->setCursor( panCursor );
+ }
+}
+
+/*!
+ \brief Start rotation operation
+
+ Sets the corresponding cursor for the widget.
+*/
+void XGUI_ViewWindow::activateRotation()
+{
+ if ( !transformRequested() && !myCursorIsHand )
+ myCursor = cursor(); // save old cursor
+
+ if ( myOperation != ROTATE ) {
+ QPixmap rotatePixmap (imageRotateCursor);
+ QCursor rotCursor (rotatePixmap);
+ if( setTransformRequested ( ROTATE ) )
+ myViewPort->setCursor( rotCursor );
+ }
+}
+
+/*!
+ \brief Reset the viewport to its initial state
+ ( no transformations in process etc. )
+*/
+void XGUI_ViewWindow::resetState()
+{
+ myDrawRect = false;
+
+ if ( myRotationPointSelection ) {
+ QCursor handCursor (Qt::PointingHandCursor);
+ myViewPort->setCursor( handCursor );
+ } else {
+ if ( transformRequested() || myCursorIsHand )
+ myViewPort->setCursor( myCursor );
+ myCursorIsHand = false;
+ }
+
+ if ( transformRequested() )
+ emit vpTransformationFinished (myOperation);
+
+ setTransformInProcess( false );
+ setTransformRequested( NOTHING );
+}
#ifndef XGUI_ViewWindow_H
#define XGUI_ViewWindow_H
+#include "XGUI_Constants.h"
+
#include <QFrame>
#include <QIcon>
#include <QToolBar>
#include <QLabel>
+#include <QMap>
#include <V3d_View.hxx>
#include <V3d_Viewer.hxx>
class XGUI_Viewer;
class ViewerToolbar;
class ViewerLabel;
+class XGUI_RectRubberBand;
class XGUI_ViewWindow : public QFrame
{
Q_OBJECT
public:
+ enum OperationType{ NOTHING, PANVIEW, ZOOMVIEW, ROTATE,
+ PANGLOBAL, WINDOWFIT, FITALLVIEW, RESETVIEW,
+ FRONTVIEW, BACKVIEW, TOPVIEW, BOTTOMVIEW, LEFTVIEW, RIGHTVIEW,
+ CLOCKWISEVIEW, ANTICLOCKWISEVIEW };
+
XGUI_ViewWindow(XGUI_Viewer* theViewer,
V3d_TypeOfView theType);
virtual ~XGUI_ViewWindow();
+ XGUI_ViewPort* viewPort() const { return myViewPort; }
+
+
+ XGUI::InteractionStyle interactionStyle() const { return myInteractionStyle; }
+
+ void setTransformEnabled( const OperationType, const bool );
+ bool transformEnabled( const OperationType ) const;
+
+signals:
+ void vpTransformationStarted(XGUI_ViewWindow::OperationType type);
+ void vpTransformationFinished(XGUI_ViewWindow::OperationType type);
+ //void viewCloned( XGUI_ViewWindow* );
+
+ void Show( QShowEvent * );
+ void Hide( QHideEvent * );
+ void maximized( XGUI_ViewWindow*, bool );
+ void returnedTo3d( );
+
+
+ void tryClosing( XGUI_ViewWindow* );
+ void closing( XGUI_ViewWindow* );
+ void mousePressed( XGUI_ViewWindow*, QMouseEvent* );
+ void mouseReleased( XGUI_ViewWindow*, QMouseEvent* );
+ void mouseDoubleClicked( XGUI_ViewWindow*, QMouseEvent* );
+ void mouseMoving( XGUI_ViewWindow*, QMouseEvent* );
+ void wheeling( XGUI_ViewWindow*, QWheelEvent* );
+ void keyPressed( XGUI_ViewWindow*, QKeyEvent* );
+ void keyReleased( XGUI_ViewWindow*, QKeyEvent* );
+ void contextMenuRequested( QContextMenuEvent *e );
+ void viewModified( XGUI_ViewWindow* );
+
+public slots:
+ void activateZoom();
+ void activateRotation();
+ void activatePanning();
+
protected:
virtual void resizeEvent(QResizeEvent* theEvent);
private:
enum WindowState { MinimizedState, MaximizedState, NormalState };
+ bool processWindowControls(QObject *theObj, QEvent *theEvent);
+ bool processViewPort(QEvent *theEvent);
+
+ void vpMousePressEvent(QMouseEvent* theEvent);
+ void vpMouseReleaseEvent(QMouseEvent* theEvent);
+ void vpMouseMoveEvent(QMouseEvent* theEvent);
+ OperationType getButtonState(QMouseEvent* theEvent, XGUI::InteractionStyle theInteractionStyle);
+
+ void resetState();
+ void drawRect();
+ void endDrawRect();
+
+ bool transformRequested() const;
+ bool setTransformRequested ( OperationType );
+
+ // Transformation is selected and already started
+ bool transformInProcess() const { return myEventStarted; }
+ void setTransformInProcess( bool bOn ) { myEventStarted = bOn; }
+
+private:
XGUI_Viewer* myViewer;
QLabel* myPicture;
WindowState myLastState;
- //QGraphicsScene* myScene;
+ int myStartX;
+ int myStartY;
+ int myCurrX;
+ int myCurrY;
+
+ XGUI::InteractionStyle myInteractionStyle;
+ OperationType myOperation;
+ XGUI::Mode2dType my2dMode;
+
+ int myCurSketch;
+ bool myDrawRect; // set when a rect is used for selection or magnify
+ bool myEnableDrawMode;
+ bool myRotationPointSelection;
+ bool myCursorIsHand;
+ bool myIsKeyFree;
+ bool myEventStarted; // set when transformation is in process
+
+ QCursor myCursor;
+
+ XGUI::RotationPointType myCurrPointType;
+ XGUI::RotationPointType myPrevPointType;
+
+ gp_Pnt mySelectedPoint;
+
+ XGUI_RectRubberBand* myRectBand; //!< selection rectangle rubber band
+
+ typedef QMap<OperationType, bool> MapOfTransformStatus;
+ MapOfTransformStatus myStatus;
+
+ double myCurScale;
};
+
+//******************************************************
class ViewerToolbar : public QToolBar
{
Q_OBJECT
XGUI_ViewPort* myVPort;
};
+//******************************************************
class ViewerLabel : public QLabel
{
Q_OBJECT
#include "XGUI_Viewer.h"
#include "XGUI_MainWindow.h"
#include "XGUI_ViewWindow.h"
+#include "XGUI_ViewPort.h"
#include <QMdiArea>
#include <QMdiSubWindow>
#include <Aspect_DisplayConnection.hxx>
#include <Graphic3d.hxx>
#include <Graphic3d_GraphicDriver.hxx>
+#include <Geom_Axis2Placement.hxx>
+#include <AIS_Drawer.hxx>
+#include <Prs3d_DatumAspect.hxx>
+#include <Prs3d_LineAspect.hxx>
+#include <V3d_View.hxx>
+#include <Visual3d_View.hxx>
#ifdef WIN32
#include <WNT_Window.hxx>
#include <Xw_Window.hxx>
#endif
+XGUI_Viewer::InteractionStyle2StatesMap XGUI_Viewer::myStateMap;
+XGUI_Viewer::InteractionStyle2ButtonsMap XGUI_Viewer::myButtonMap;
+static bool isInitialized = false;
+
/*!
Creates viewer 3d [ static ]
-XGUI_Viewer::XGUI_Viewer(XGUI_MainWindow* theParent) :
-QObject(theParent), myMainWindow(theParent)
+XGUI_Viewer::XGUI_Viewer(XGUI_MainWindow* theParent, bool DisplayTrihedron) :
+QObject(theParent),
+ myMainWindow(theParent),
+ myPreselectionEnabled(true),
+ mySelectionEnabled(true),
+ myMultiSelectionEnabled(true),
+ myIsRelative(true),
+ myInteractionStyle(XGUI::STANDARD),
+ myTrihedronSize(100)
{
+ if ( !isInitialized ) {
+ isInitialized = true;
+
+ // standard interaction style
+ XGUI_Viewer::myStateMap[XGUI::STANDARD][XGUI::ZOOM] = Qt::ControlModifier;
+ XGUI_Viewer::myButtonMap[XGUI::STANDARD][XGUI::ZOOM] = Qt::LeftButton;
+
+ XGUI_Viewer::myStateMap[XGUI::STANDARD][XGUI::PAN] = Qt::ControlModifier;
+ XGUI_Viewer::myButtonMap[XGUI::STANDARD][XGUI::PAN] = Qt::MidButton;
+
+ XGUI_Viewer::myStateMap[XGUI::STANDARD][XGUI::ROTATE] = Qt::ControlModifier;
+ XGUI_Viewer::myButtonMap[XGUI::STANDARD][XGUI::ROTATE] = Qt::RightButton;
+
+ XGUI_Viewer::myStateMap[XGUI::STANDARD][XGUI::FIT_AREA] = Qt::ControlModifier;
+ XGUI_Viewer::myButtonMap[XGUI::STANDARD][XGUI::FIT_AREA] = Qt::RightButton;
+
+ // "key free" interaction style
+ XGUI_Viewer::myStateMap[XGUI::KEY_FREE][XGUI::ZOOM] = Qt::NoModifier;
+ XGUI_Viewer::myButtonMap[XGUI::KEY_FREE][XGUI::ZOOM] = Qt::RightButton;
+
+ XGUI_Viewer::myStateMap[XGUI::KEY_FREE][XGUI::PAN] = Qt::NoModifier;
+ XGUI_Viewer::myButtonMap[XGUI::KEY_FREE][XGUI::PAN] = Qt::MidButton;
+
+ XGUI_Viewer::myStateMap[XGUI::KEY_FREE][XGUI::ROTATE] = Qt::NoModifier;
+ XGUI_Viewer::myButtonMap[XGUI::KEY_FREE][XGUI::ROTATE] = Qt::LeftButton;
+
+ XGUI_Viewer::myStateMap[XGUI::KEY_FREE][XGUI::FIT_AREA] = Qt::NoModifier; // unused
+ XGUI_Viewer::myButtonMap[XGUI::KEY_FREE][XGUI::FIT_AREA] = Qt::NoButton; // unused
+ }
+
// init CasCade viewers
myV3dViewer = CreateViewer(TCollection_ExtendedString("Viewer3d").ToExtString(),
"", "", 1000.0, V3d_XposYnegZpos, Standard_True, Standard_True );
// display isoline on planar faces (box for ex.)
myAISContext->IsoOnPlane( true );
+
+ if ( DisplayTrihedron ) {
+ Handle(Geom_Axis2Placement) anAxis = new Geom_Axis2Placement(gp::XOY());
+ myTrihedron = new AIS_Trihedron(anAxis);
+ myTrihedron->SetInfiniteState( Standard_True );
+
+ Quantity_Color Col(193/255., 205/255., 193/255., Quantity_TOC_RGB);
+ //myTrihedron->SetColor( Col );
+ myTrihedron->SetArrowColor( Col.Name() );
+ myTrihedron->SetSize(myTrihedronSize);
+ Handle(AIS_Drawer) drawer = myTrihedron->Attributes();
+ if (drawer->HasDatumAspect()) {
+ Handle(Prs3d_DatumAspect) daspect = drawer->DatumAspect();
+ daspect->FirstAxisAspect()->SetColor(Quantity_Color(1.0, 0.0, 0.0, Quantity_TOC_RGB));
+ daspect->SecondAxisAspect()->SetColor(Quantity_Color(0.0, 1.0, 0.0, Quantity_TOC_RGB));
+ daspect->ThirdAxisAspect()->SetColor(Quantity_Color(0.0, 0.0, 1.0, Quantity_TOC_RGB));
+ }
+ }
+ // set zooming style to standard
+ //myZoomingStyle = 0;
}
// set default background for view window
//vw->setBackground( background(0) ); // 0 means MAIN_VIEW (other views are not yet created here)
//// connect signal from viewport
- //connect(view->getViewPort(), SIGNAL(vpClosed()), this, SLOT(onViewClosed()));
- //connect(view->getViewPort(), SIGNAL(vpMapped()), this, SLOT(onViewMapped()));
+ connect(view->viewPort(), SIGNAL(vpClosed()), this, SLOT(onViewClosed()));
+ connect(view->viewPort(), SIGNAL(vpMapped()), this, SLOT(onViewMapped()));
QMdiArea* aMDI = myMainWindow->mdiArea();
QMdiSubWindow* aWnd = aMDI->addSubWindow(view, Qt::FramelessWindowHint);
aWnd->setGeometry(0,0, aMDI->width() / 2, aMDI->height() / 2);
aWnd->show();
return aWnd;
-}
\ No newline at end of file
+}
+
+/*! Sets hot button
+ *\param theOper - hot operation
+ *\param theState - adding state to state map operations.
+ *\param theButton - adding state to button map operations.
+ */
+void XGUI_Viewer::setHotButton( XGUI::InteractionStyle theInteractionStyle, XGUI::HotOperation theOper,
+ Qt::KeyboardModifiers theState, Qt::MouseButtons theButton )
+{
+ myStateMap[theInteractionStyle][theOper] = theState;
+ myButtonMap[theInteractionStyle][theOper] = theButton;
+}
+
+/*! Gets hot button for operation \a theOper.
+ *\param theOper - input hot operation
+ *\param theState - output state from state map operations.
+ *\param theButton - output state from button map operations.
+*/
+void XGUI_Viewer::getHotButton( XGUI::InteractionStyle theInteractionStyle, XGUI::HotOperation theOper,
+ Qt::KeyboardModifiers& theState, Qt::MouseButtons& theButton )
+{
+ theState = myStateMap[theInteractionStyle][theOper];
+ theButton = myButtonMap[theInteractionStyle][theOper];
+}
+
+/*!
+ Changes visibility of trihedron to opposite
+*/
+void XGUI_Viewer::toggleTrihedron()
+{
+ setTrihedronShown( !isTrihedronVisible() );
+}
+
+/*!
+ \return true if trihedron is visible
+*/
+bool XGUI_Viewer::isTrihedronVisible() const
+{
+ return !myTrihedron.IsNull() && !myAISContext.IsNull() && myAISContext->IsDisplayed( myTrihedron );
+}
+
+/*!
+ Sets visibility state of trihedron
+ \param on - new state
+*/
+
+void XGUI_Viewer::setTrihedronShown( const bool on )
+{
+ if ( myTrihedron.IsNull() )
+ return;
+
+ if ( on ) {
+ myAISContext->Display( myTrihedron );
+ myAISContext->Deactivate(myTrihedron);
+ } else {
+ myAISContext->Erase( myTrihedron );
+ }
+}
+
+/*!
+ \return trihedron size
+*/
+double XGUI_Viewer::trihedronSize() const
+{
+ double sz = 0;
+ if ( !myTrihedron.IsNull() )
+ sz = myTrihedron->Size();
+ return sz;
+}
+
+/*!
+ Changes trihedron size
+ \param sz - new size
+*/
+void XGUI_Viewer::setTrihedronSize( const double sz, bool isRelative )
+{
+ if ( myTrihedronSize != sz || isRelative != myIsRelative) {
+ myTrihedronSize = sz;
+ myIsRelative = isRelative;
+ updateTrihedron();
+ }
+}
+
+/*!
+ * Update the size of the trihedron
+ */
+void XGUI_Viewer::updateTrihedron()
+{
+ if ( myTrihedron.IsNull() )
+ return;
+
+ if(myIsRelative){
+ double newSz, oldSz;
+
+ if(computeTrihedronSize(newSz, oldSz))
+ myTrihedron->SetSize(newSz);
+
+ } else if(myTrihedron->Size() != myTrihedronSize) {
+ myTrihedron->SetSize(myTrihedronSize);
+ }
+}
+
+/*!
+ Get new and current trihedron size corresponding to the current model size
+*/
+bool XGUI_Viewer::computeTrihedronSize( double& theNewSize, double& theSize )
+{
+ theNewSize = 100;
+ theSize = 100;
+
+ //SRN: BUG IPAL8996, a usage of method ActiveView without an initialization
+ Handle(V3d_Viewer) viewer = v3dViewer();
+ viewer->InitActiveViews();
+ if(!viewer->MoreActiveViews()) return false;
+
+ Handle(V3d_View) view3d = viewer->ActiveView();
+ //SRN: END of fix
+
+ if ( view3d.IsNull() )
+ return false;
+
+ double Xmin = 0, Ymin = 0, Zmin = 0, Xmax = 0, Ymax = 0, Zmax = 0;
+ double aMaxSide;
+
+ view3d->View()->MinMaxValues( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax );
+
+ if ( Xmin == RealFirst() || Ymin == RealFirst() || Zmin == RealFirst() ||
+ Xmax == RealLast() || Ymax == RealLast() || Zmax == RealLast() )
+ return false;
+
+ aMaxSide = Xmax - Xmin;
+ if ( aMaxSide < Ymax -Ymin ) aMaxSide = Ymax -Ymin;
+ if ( aMaxSide < Zmax -Zmin ) aMaxSide = Zmax -Zmin;
+
+ // IPAL21687
+ // The boundary box of the view may be initialized but nullified
+ // (case of infinite objects)
+ if ( aMaxSide < Precision::Confusion() )
+ return false;
+
+ static float EPS = 5.0E-3;
+ theSize = trihedron()->Size();
+ //theNewSize = aMaxSide*aSizeInPercents / 100.0;
+
+ return fabs( theNewSize - theSize ) > theSize * EPS ||
+ fabs( theNewSize - theSize) > theNewSize * EPS;
+}
+
+
+void XGUI_Viewer::onViewClosed()
+{
+ Standard_Integer aViewsNb = 0;
+ for ( myV3dViewer->InitActiveViews(); myV3dViewer->MoreActiveViews(); myV3dViewer->NextActiveViews())
+ ++aViewsNb;
+ if ( aViewsNb < 2 ) {
+ //clean up presentations before last view is closed
+ myAISContext->RemoveAll(Standard_False);
+ }
+}
+
+void XGUI_Viewer::onViewMapped()
+{
+ setTrihedronShown( true );
+}
+
#ifndef XGUI_Viewer_H
#define XGUI_Viewer_H
+#include "XGUI_Constants.h"
+
#include <QObject>
+#include <QMap>
+
#include <V3d_Viewer.hxx>
#include <AIS_InteractiveContext.hxx>
#include <AIS_Trihedron.hxx>
{
Q_OBJECT
public:
- enum {
- HorizontalGradient, VerticalGradient,
- Diagonal1Gradient, Diagonal2Gradient,
- Corner1Gradient, Corner2Gradient,
- Corner3Gradient, Corner4Gradient,
- LastGradient = Corner4Gradient
- };
-
- XGUI_Viewer(XGUI_MainWindow* theParent);
+ XGUI_Viewer(XGUI_MainWindow* theParent, bool DisplayTrihedron = true);
~XGUI_Viewer();
QMdiSubWindow* createView(V3d_TypeOfView theType = V3d_ORTHOGRAPHIC);
Handle(V3d_Viewer) v3dViewer() const { return myV3dViewer; }
+ Handle(AIS_InteractiveContext) AISContext() const { return myAISContext; }
+
+ Handle(AIS_Trihedron) trihedron() const { return myTrihedron; }
+
+ void toggleTrihedron();
+ bool isTrihedronVisible() const;
+ void setTrihedronShown( const bool on );
+ double trihedronSize() const;
+ void setTrihedronSize( const double sz, bool isRelative );
+ bool trihedronRelative() const { return myIsRelative; }
+ void updateTrihedron();
+ bool computeTrihedronSize( double& theNewSize, double& theSize );
+
+
+
+ static void setHotButton( XGUI::InteractionStyle theInteractionStyle, XGUI::HotOperation theOper,
+ Qt::KeyboardModifiers theState, Qt::MouseButtons theButton );
+ static void getHotButton( XGUI::InteractionStyle theInteractionStyle, XGUI::HotOperation theOper,
+ Qt::KeyboardModifiers& theState, Qt::MouseButtons& theButton );
+
+ typedef QMap<XGUI::HotOperation, Qt::KeyboardModifiers> StatesMap;
+ typedef QMap<XGUI::HotOperation, Qt::MouseButtons> ButtonsMap;
+
+ typedef QMap<XGUI::InteractionStyle, StatesMap> InteractionStyle2StatesMap;
+ typedef QMap<XGUI::InteractionStyle, ButtonsMap> InteractionStyle2ButtonsMap;
+
+ static InteractionStyle2StatesMap myStateMap;
+ static InteractionStyle2ButtonsMap myButtonMap;
+
+private slots:
+ void onViewClosed();
+ void onViewMapped();
+
private:
XGUI_MainWindow* myMainWindow;
Handle(V3d_Viewer) myV3dViewer;
Handle(AIS_Trihedron) myTrihedron;
Handle(AIS_InteractiveContext) myAISContext;
+
+ XGUI::InteractionStyle myInteractionStyle;
+
+ bool myPreselectionEnabled;
+ bool mySelectionEnabled;
+ bool myMultiSelectionEnabled;
+ bool myIsRelative;
+
+ double myTrihedronSize;
};
#endif
\ No newline at end of file