1 #include "XGUI_RubberBand.h"
9 #include <QVectorIterator>
12 \class QtxAbstractRubberBand
13 \brief Analog of class QRubberBand with possibility of creation non-rectangular contour for selection.
15 Currently this class does not support Style functionality in full.
20 \param theParent parent widget
23 XGUI_AbstractRubberBand::XGUI_AbstractRubberBand( QWidget* theParent)
24 : QWidget( theParent ),
28 setAttribute(Qt::WA_TransparentForMouseEvents);
30 setAttribute(Qt::WA_NoSystemBackground);
32 setAttribute(Qt::WA_WState_ExplicitShowHide);
34 theParent->installEventFilter(this);
35 setGeometry( QRect(QPoint(0,0), theParent->size() ) );
41 XGUI_AbstractRubberBand::~XGUI_AbstractRubberBand()
45 void XGUI_AbstractRubberBand::clearGeometry()
50 bool XGUI_AbstractRubberBand::isClosed()
55 void XGUI_AbstractRubberBand::paintEvent( QPaintEvent* theEvent )
57 if ( !myPoints.empty() ) {
58 QPixmap tiledPixmap(16, 16);
60 QPainter pixmapPainter(&tiledPixmap);
61 pixmapPainter.setPen(Qt::NoPen);
62 pixmapPainter.setBrush(QBrush( Qt::black, Qt::Dense4Pattern ));
63 pixmapPainter.setBackground(QBrush( Qt::white ));
64 pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
65 pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
67 // ### workaround for borked XRENDER
68 tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
70 QPainter aPainter( this );
71 aPainter.setRenderHint( QPainter::Antialiasing );
72 QRect r = myPoints.boundingRect();
73 aPainter.setClipRegion( r.normalized().adjusted( -1, -1, 2, 2 ) );
74 aPainter.drawTiledPixmap( 0, 0, width(), height(), tiledPixmap);
80 void XGUI_AbstractRubberBand::showEvent( QShowEvent* theEvent )
86 void XGUI_AbstractRubberBand::moveEvent( QMoveEvent* )
90 void XGUI_AbstractRubberBand::resizeEvent( QResizeEvent* )
94 bool XGUI_AbstractRubberBand::eventFilter( QObject* obj, QEvent* e )
96 if ( obj && obj == parent() && e->type() == QEvent::Resize ) {
97 QWidget* p = (QWidget*)parent();
98 setGeometry( QRect(QPoint(0,0), p->size() ) );
100 return QWidget::eventFilter( obj, e );
103 QRegion createRegion( const QPointF& p1, const QPointF& p2 )
108 QLineF n = QLineF( p1, p2 ).normalVector();//.unitVector();
110 n.translate( p1 * -1 );
111 QPointF nPoint = n.p2();
114 p << p1 + nPoint << p2 + nPoint << p2 - nPoint << p1 - nPoint << p1 + nPoint;
116 return QRegion( p.toPolygon() );
119 void XGUI_AbstractRubberBand::updateMask()
123 QVectorIterator<QPoint> it(myPoints);
124 while( it.hasNext() ) {
125 QPoint p = it.next();
129 QPoint np = it.peekNext();
131 if ( p == np ) continue;
133 r += createRegion( p, np );
137 r += createRegion( myPoints.last(), myPoints.first() );
143 //**********************************************************
144 XGUI_RectRubberBand::XGUI_RectRubberBand(QWidget* parent)
145 :XGUI_AbstractRubberBand( parent )
147 myPoints.resize( 4 );
151 XGUI_RectRubberBand::~XGUI_RectRubberBand()
155 void XGUI_RectRubberBand::initGeometry( const QRect& theRect )
158 myPoints << theRect.topLeft() << theRect.topRight() << theRect.bottomRight() << theRect.bottomLeft();
159 //setMask( QRegion( myPoints ) );
163 void XGUI_RectRubberBand::setStartPoint( const QPoint& thePoint )
165 myPoints[0] = thePoint;
166 myPoints[1].setY( thePoint.y() );
167 myPoints[3].setX( thePoint.x() );
171 void XGUI_RectRubberBand::setEndPoint( const QPoint& thePoint)
173 myPoints[2] = thePoint;
174 myPoints[1].setX( thePoint.x() );
175 myPoints[3].setY( thePoint.y() );
179 void XGUI_RectRubberBand::clearGeometry()
181 QMutableVectorIterator<QPoint> i(myPoints);
182 while (i.hasNext()) {
184 i.setValue( QPoint( -1, -1 ) );
188 //**********************************************************
189 XGUI_PolyRubberBand::XGUI_PolyRubberBand(QWidget* parent)
190 :XGUI_AbstractRubberBand( parent )
194 XGUI_PolyRubberBand::~XGUI_PolyRubberBand()
198 void XGUI_PolyRubberBand::initGeometry( const QPolygon& thePoints )
200 myPoints = thePoints;
204 void XGUI_PolyRubberBand::initGeometry( const QPoint& thePoint )
207 myPoints << thePoint;
211 void XGUI_PolyRubberBand::addNode( const QPoint& thePoint )
213 myPoints << thePoint;
217 void XGUI_PolyRubberBand::replaceLastNode( const QPoint& thePoint )
219 if ( !myPoints.empty() ) {
221 myPoints << thePoint;
226 void XGUI_PolyRubberBand::removeLastNode()
228 if ( !myPoints.empty() ) {
234 void XGUI_PolyRubberBand::setClosed( bool theFlag )
236 if (myIsClosed != theFlag ) {
237 myIsClosed = theFlag;