Implementation of QtxRubberBand for customization of selection interface in OCC Viewer
#include "OCCViewer_ViewWindow.h"
#include "OCCViewer_ViewPort3d.h"
+#include "QtxRubberBand.h"
+
#include <QApplication>
#include <QPainter>
#include <QPolygon>
*****************************************************************/
OCCViewer_RectSketcher::OCCViewer_RectSketcher( OCCViewer_ViewWindow* vw, int typ )
-: OCCViewer_ViewSketcher( vw, typ )
+ : OCCViewer_ViewSketcher( vw, typ )
{
+ if ( vw )
+ {
+ OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort();
+ mypRectRB = new QtxRectRubberBand( avp );
+ }
}
OCCViewer_RectSketcher::~OCCViewer_RectSketcher()
{
delete (QRect*)mypData;
mypData = 0;
+ mypRectRB->clearGeometry();
}
bool OCCViewer_RectSketcher::onKey( QKeyEvent* e )
void OCCViewer_RectSketcher::onSketch( SketchState state )
{
- OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort();
-
- QRect* sketchRect = (QRect*)data();
- if ( myButtonState & sketchButton() )
- {
- QRect rect( qMin( myStart.x(), myCurr.x() ), qMin( myStart.y(), myCurr.y() ),
- qAbs( myStart.x() - myCurr.x() ), qAbs( myStart.y() - myCurr.y() ) );
- QPainter p( avp );
- p.setPen( Qt::white );
- p.setCompositionMode( QPainter::CompositionMode_Xor );
- if ( state != Debut && !sketchRect->isEmpty() )
- p.drawRect( *sketchRect );
- *sketchRect = rect;
- if ( !rect.isEmpty() && state != Fin )
- p.drawRect( *sketchRect );
- }
+ //OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort();
+
+ if ( mypRectRB )
+ {
+ QRect* sketchRect = (QRect*)data();
+ if ( myButtonState & sketchButton() )
+ {
+ QRect rect = QRect( myStart, myCurr ).normalized();
+ /*QRect rect( qMin( myStart.x(), myCurr.x() ), qMin( myStart.y(), myCurr.y() ),
+ qAbs( myStart.x() - myCurr.x() ), qAbs( myStart.y() - myCurr.y() ) );
+ QPainter p( avp );
+ p.setPen( Qt::white );
+ p.setCompositionMode( QPainter::CompositionMode_Xor );
+ */
+
+ //if ( state != Debut && !sketchRect->isEmpty() )
+ // p.drawRect( *sketchRect );
+
+ *sketchRect = rect;
+ if ( !rect.isEmpty() && state != Fin )
+ {
+ //p.drawRect( *sketchRect );
+ mypRectRB->initGeometry( rect );
+ mypRectRB->show();
+ }
+ else
+ mypRectRB->hide();
+ }
+ }
if ( state == Fin )
{
: OCCViewer_ViewSketcher( vw, typ ),
myDbl ( false ),
myToler ( 5, 5 ),
- mypPoints ( 0L ),
+ //mypPoints ( 0L ),
myAddButton ( 0 ),
myDelButton ( 0 )
{
mySketchButton = Qt::RightButton;
+ if ( vw )
+ {
+ OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort();
+ mypPolyRB = new QtxPolyRubberBand( avp );
+ }
}
OCCViewer_PolygonSketcher::~OCCViewer_PolygonSketcher()
{
- delete mypPoints;
+ //delete mypPoints;
delete (QPolygon*)mypData;
}
{
myDbl = false;
mypData = new QPolygon( 0 );
- mypPoints = new QPolygon( 0 );
+ //mypPoints = new QPolygon( 0 );
switch ( sketchButton() )
{
void OCCViewer_PolygonSketcher::onDeactivate()
{
- delete mypPoints;
- mypPoints = 0;
+ //delete mypPoints;
+ //mypPoints = 0;
delete (QPolygon*)mypData;
mypData = 0;
+
+ if ( mypPolyRB )
+ mypPolyRB->clearGeometry();
}
bool OCCViewer_PolygonSketcher::onKey( QKeyEvent* e )
void OCCViewer_PolygonSketcher::onSketch( SketchState state )
{
- OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort();
+ //OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort();
QPolygon* points = (QPolygon*)data();
- QPainter p( avp );
+ /*QPainter p( avp );
p.setPen( Qt::white );
p.setCompositionMode( QPainter::CompositionMode_Xor );
if ( state != Debut )
mypPoints->setPoint( points->count(), myCurr );
if ( state != Fin )
p.drawPolyline( *mypPoints );
- }
-
+ }*/
+ if ( mypPolyRB )
+ {
+ mypPolyRB->setUpdatesEnabled ( false );
+ if ( !mypPolyRB->isVisible() )
+ mypPolyRB->show();
+ //if ( state != Debut )
+ // mypPolyRB->repaint();
+
+ if ( state != Fin && points->count() )
+ mypPolyRB->initGeometry( QPolygon(*points) << myCurr );
+ //mypPolyRB->addNode( myCurr );
+
+ //if ( state != Fin )
+ // mypPolyRB->repaint();
+ mypPolyRB->setUpdatesEnabled ( true );
+ //mypPolyRB->repaint();
+ }
+
if ( state == Fin )
{
+ if ( mypPolyRB )
+ {
+ mypPolyRB->clearGeometry();
+ mypPolyRB->hide();
+ }
QApplication::syncX();
mypViewWindow->activateSketching( OCCViewer_ViewWindow::NoSketching );
}
class QMouseEvent;
class QPolygon;
+class QtxRectRubberBand;
+class QtxPolyRubberBand;
+
#ifdef WNT
#pragma warning ( disable:4251 )
#endif
virtual void onSketch( SketchState );
virtual void onActivate();
virtual void onDeactivate();
+ private:
+ QtxRectRubberBand* mypRectRB;
};
/*!
QPolygon* mypPoints;
int myAddButton;
int myDelButton;
+
+ QtxPolyRubberBand* mypPolyRB;
};
#ifdef WNT
#include <QtxActionToolMgr.h>
#include <QtxMultiAction.h>
+#include <QtxRubberBand.h>
#include <QPainter>
#include <QTime>
#include <QImage>
#include <QMouseEvent>
-#include <QRubberBand>
#include <QApplication>
#include <V3d_Plane.hxx>
void OCCViewer_ViewWindow::drawRect()
{
if ( !myRectBand ) {
- myRectBand = new QRubberBand( QRubberBand::Rectangle, myViewPort );
-#ifdef WIN32
- myRectBand->setStyle(new QWindowsStyle);
-#endif
- QPalette palette;
- palette.setColor(myRectBand->foregroundRole(), Qt::white);
- myRectBand->setPalette(palette);
+ myRectBand = new QtxRectRubberBand( myViewPort );
+ //QPalette palette;
+ //palette.setColor(myRectBand->foregroundRole(), Qt::white);
+ //myRectBand->setPalette(palette);
}
- myRectBand->hide();
-
+ //myRectBand->hide();
+
+ myRectBand->setUpdatesEnabled ( false );
QRect aRect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
- myRectBand->setGeometry( aRect );
- myRectBand->setVisible( aRect.isValid() );
+ myRectBand->initGeometry( aRect );
+
+ if ( !myRectBand->isVisible() )
+ myRectBand->show();
+
+ myRectBand->setUpdatesEnabled ( true );
+ //myRectBand->repaint();
+
+ //myRectBand->setVisible( aRect.isValid() );
+ //if ( myRectBand->isVisible() )
+ // myRectBand->repaint();
+ //else
+ // myRectBand->show();
+ //myRectBand->repaint();
}
/*!
*/
void OCCViewer_ViewWindow::endDrawRect()
{
- delete myRectBand;
- myRectBand = 0;
+ //delete myRectBand;
+ //myRectBand = 0;
+ if ( myRectBand )
+ {
+ myRectBand->clearGeometry();
+ myRectBand->hide();
+ }
}
/*!
#include "SUIT_ViewWindow.h"
#include <gp_Pnt.hxx>
-class QRubberBand;
+class QtxRectRubberBand;
class SUIT_Desktop;
class OCCViewer_ViewPort3d;
class OCCViewer_ViewSketcher;
OCCViewer_SetRotationPointDlg* mySetRotationPointDlg;
QtxAction* mySetRotationPointAction;
- QRubberBand* myRectBand; //!< selection rectangle rubber band
+ QtxRectRubberBand* myRectBand; //!< selection rectangle rubber band
};
#ifdef WIN32
QtxPopupMgr.h \
QtxPreferenceMgr.h \
QtxResourceMgr.h \
+ QtxRubberBand.h \
QtxSearchTool.h \
QtxSplash.h \
QtxToolBar.h \
QtxPopupMgr.cxx \
QtxPreferenceMgr.cxx \
QtxResourceMgr.cxx \
+ QtxRubberBand.cxx \
QtxSearchTool.cxx \
QtxSplash.cxx \
QtxToolBar.cxx \
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxRubberBand.cxx
+// Author: Alexander A. BORODIN
+//
+
+#include "QtxRubberBand.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
+ */
+
+QtxAbstractRubberBand::QtxAbstractRubberBand( QWidget* theParent)
+ : QWidget( theParent/*,Qt::ToolTip*/ ),
+ 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
+ */
+QtxAbstractRubberBand::~QtxAbstractRubberBand()
+{
+}
+
+void QtxAbstractRubberBand::clearGeometry()
+{
+ myPoints.clear();
+}
+
+bool QtxAbstractRubberBand::isClosed()
+{
+ return myIsClosed;
+}
+
+void QtxAbstractRubberBand::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();
+
+ /*
+
+
+
+#ifdef WIN32
+ QPixmap anImage( size() );
+#else
+ QImage anImage( size(), QImage::Format_ARGB32_Premultiplied );
+#endif
+
+ anImage.fill( Qt::transparent );
+ QPainter aImgPainter( &anImage );
+ aImgPainter.setRenderHint( QPainter::Antialiasing );
+ aImgPainter.setCompositionMode(QPainter::CompositionMode_Source);
+
+ QPen aPen( Qt::black );
+ aPen.setWidth( 2 );
+ aImgPainter.setPen( aPen );
+
+ aImgPainter.drawPolyline( myPoints );
+ if ( myIsClosed && myPoints.last() != myPoints.first() )
+ aImgPainter.drawLine( myPoints.last(), myPoints.first() );
+
+ //aImgPainter.setPen(Qt::NoPen);
+ //aImgPainter.setBrush(QBrush( Qt::white, Qt::Dense4Pattern));
+ //aImgPainter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
+ //aImgPainter.drawRect(0, 0, width(), height());
+ aImgPainter.end();
+
+ QPainter aPainter( this );
+ aPainter.drawPolyline( myPoints );
+ if ( myIsClosed && myPoints.last() != myPoints.first() )
+ aPainter.drawLine( myPoints.last(), myPoints.first() );
+
+#ifdef WIN32
+ aPainter.drawPixmap( 0, 0, anImage );
+#else
+ aPainter.drawImage( 0, 0, anImage );
+ #endif
+ aPainter.end();*/
+
+ }
+}
+
+void QtxAbstractRubberBand::showEvent( QShowEvent* theEvent )
+{
+ raise();
+ theEvent->ignore();
+}
+
+void QtxAbstractRubberBand::moveEvent( QMoveEvent* )
+{
+}
+
+void QtxAbstractRubberBand::resizeEvent( QResizeEvent* )
+{
+}
+
+bool QtxAbstractRubberBand::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 QtxAbstractRubberBand::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 );
+
+}
+
+
+QtxRectRubberBand::QtxRectRubberBand(QWidget* parent)
+ :QtxAbstractRubberBand( parent )
+{
+ myPoints.resize( 4 );
+ myIsClosed = true;
+}
+
+QtxRectRubberBand::~QtxRectRubberBand()
+{
+}
+
+void QtxRectRubberBand::initGeometry( const QRect& theRect )
+{
+ myPoints.clear();
+ myPoints << theRect.topLeft() << theRect.topRight() << theRect.bottomRight() << theRect.bottomLeft();
+ //setMask( QRegion( myPoints ) );
+ updateMask();
+}
+
+void QtxRectRubberBand::setStartPoint( const QPoint& thePoint )
+{
+ myPoints[0] = thePoint;
+ myPoints[1].setY( thePoint.y() );
+ myPoints[3].setX( thePoint.x() );
+ updateMask();
+}
+
+void QtxRectRubberBand::setEndPoint( const QPoint& thePoint)
+{
+ myPoints[2] = thePoint;
+ myPoints[1].setX( thePoint.x() );
+ myPoints[3].setY( thePoint.y() );
+ updateMask();
+}
+
+void QtxRectRubberBand::clearGeometry()
+{
+ QMutableVectorIterator<QPoint> i(myPoints);
+ while (i.hasNext())
+ {
+ i.next();
+ i.setValue( QPoint( -1, -1 ) );
+ }
+}
+
+
+QtxPolyRubberBand::QtxPolyRubberBand(QWidget* parent)
+ :QtxAbstractRubberBand( parent )
+{
+}
+
+QtxPolyRubberBand::~QtxPolyRubberBand()
+{
+}
+
+void QtxPolyRubberBand::initGeometry( const QPolygon& thePoints )
+{
+ myPoints = thePoints;
+ updateMask();
+}
+
+void QtxPolyRubberBand::initGeometry( const QPoint& thePoint )
+{
+ myPoints.clear();
+ myPoints << thePoint;
+ updateMask();
+}
+
+void QtxPolyRubberBand::addNode( const QPoint& thePoint )
+{
+ myPoints << thePoint;
+ updateMask();
+}
+
+void QtxPolyRubberBand::replaceLastNode( const QPoint& thePoint )
+{
+ if ( !myPoints.empty() )
+ {
+ myPoints.pop_back();
+ myPoints << thePoint;
+ updateMask();
+ }
+}
+
+void QtxPolyRubberBand::removeLastNode()
+{
+ if ( !myPoints.empty() )
+ {
+ myPoints.pop_back();
+ updateMask();
+ }
+}
+
+void QtxPolyRubberBand::setClosed( bool theFlag )
+{
+ if (myIsClosed != theFlag )
+ {
+ myIsClosed = theFlag;
+ updateMask();
+ }
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File: QtxRubberBand.h
+// Author: Alexander A. BORODIN
+//
+
+#ifndef QTXRUBBERBAND_H
+#define QTXRUBBERBAND_H
+
+#include "Qtx.h"
+
+#include <QWidget>
+
+class QTX_EXPORT QtxAbstractRubberBand: public QWidget
+{
+protected:
+ QtxAbstractRubberBand( QWidget* );
+
+public:
+ virtual ~QtxAbstractRubberBand();
+
+ 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 QTX_EXPORT QtxRectRubberBand: public QtxAbstractRubberBand
+{
+public:
+
+ QtxRectRubberBand( QWidget* );
+ virtual ~QtxRectRubberBand();
+
+ void initGeometry( const QRect& );
+ void setStartPoint( const QPoint& );
+ void setEndPoint( const QPoint& );
+
+ virtual void clearGeometry();
+};
+
+class QTX_EXPORT QtxPolyRubberBand: public QtxAbstractRubberBand
+{
+public:
+
+ QtxPolyRubberBand( QWidget* );
+ virtual ~QtxPolyRubberBand();
+
+ void initGeometry( const QPolygon& );
+ void initGeometry( const QPoint& );
+
+ void addNode( const QPoint& );
+ void replaceLastNode( const QPoint& );
+ void removeLastNode();
+
+ void setClosed( bool );
+};
+
+#endif //QTXRUBBERBAND_H