Back to index

salome-gui  6.5.0
QtxRubberBand.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 // File:      QtxRubberBand.cxx
00021 // Author:    Alexander A. BORODIN
00022 //
00023 #include "QtxRubberBand.h"
00024 
00025 #include <QBitmap>
00026 #include <QImage>
00027 #include <QPaintEvent>
00028 #include <QPainter>
00029 #include <QPalette>
00030 #include <QShowEvent>
00031 #include <QVectorIterator>
00032 
00045 QtxAbstractRubberBand::QtxAbstractRubberBand( QWidget* theParent)
00046   : QWidget( theParent/*,Qt::ToolTip*/ ),
00047     myPoints(),
00048     myIsClosed( false )
00049 {
00050   setAttribute(Qt::WA_TransparentForMouseEvents);
00051 #ifndef WIN32
00052   setAttribute(Qt::WA_NoSystemBackground);
00053 #endif //WIN32
00054   setAttribute(Qt::WA_WState_ExplicitShowHide);
00055   setVisible(false);
00056   theParent->installEventFilter(this);
00057   setGeometry( QRect(QPoint(0,0), theParent->size() ) );
00058 }
00059 
00063 QtxAbstractRubberBand::~QtxAbstractRubberBand()
00064 {
00065 }
00066 
00067 void QtxAbstractRubberBand::clearGeometry()
00068 {
00069   myPoints.clear();
00070 }
00071 
00072 bool QtxAbstractRubberBand::isClosed()
00073 {
00074   return myIsClosed;
00075 }
00076 
00077 void QtxAbstractRubberBand::paintEvent( QPaintEvent* theEvent )
00078 {
00079   if ( !myPoints.empty() )
00080     {
00081       QPixmap tiledPixmap(16, 16);
00082      
00083       QPainter pixmapPainter(&tiledPixmap);
00084       pixmapPainter.setPen(Qt::NoPen);
00085       pixmapPainter.setBrush(QBrush( Qt::black, Qt::Dense4Pattern ));
00086       pixmapPainter.setBackground(QBrush( Qt::white ));
00087       pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
00088       pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
00089       pixmapPainter.end();
00090       // ### workaround for borked XRENDER
00091       tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
00092 
00093 
00094       
00095       QPainter aPainter( this );
00096       aPainter.setRenderHint( QPainter::Antialiasing );
00097       QRect r = myPoints.boundingRect();
00098       aPainter.setClipRegion( r.normalized().adjusted( -1, -1, 2, 2 ) );
00099       aPainter.drawTiledPixmap( 0, 0, width(), height(), tiledPixmap);
00100 
00101       aPainter.end();
00102 
00103     /*
00104 
00105 
00106 
00107 #ifdef WIN32
00108       QPixmap anImage( size() );
00109 #else
00110       QImage anImage( size(), QImage::Format_ARGB32_Premultiplied );
00111 #endif
00112 
00113       anImage.fill( Qt::transparent );
00114       QPainter aImgPainter( &anImage );
00115       aImgPainter.setRenderHint( QPainter::Antialiasing );
00116       aImgPainter.setCompositionMode(QPainter::CompositionMode_Source);
00117 
00118       QPen aPen( Qt::black );
00119       aPen.setWidth( 2 );
00120       aImgPainter.setPen( aPen );
00121     
00122       aImgPainter.drawPolyline( myPoints );
00123       if ( myIsClosed && myPoints.last() != myPoints.first() )
00124         aImgPainter.drawLine( myPoints.last(), myPoints.first() );
00125 
00126       //aImgPainter.setPen(Qt::NoPen);
00127       //aImgPainter.setBrush(QBrush( Qt::white, Qt::Dense4Pattern));
00128       //aImgPainter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
00129       //aImgPainter.drawRect(0, 0, width(), height());
00130       aImgPainter.end();
00131 
00132       QPainter aPainter( this );
00133       aPainter.drawPolyline( myPoints );
00134       if ( myIsClosed && myPoints.last() != myPoints.first() )
00135         aPainter.drawLine( myPoints.last(), myPoints.first() );
00136       
00137 #ifdef WIN32
00138       aPainter.drawPixmap( 0, 0, anImage );
00139 #else
00140       aPainter.drawImage( 0, 0, anImage );
00141       #endif
00142       aPainter.end();*/
00143       
00144     }
00145 }
00146 
00147 void QtxAbstractRubberBand::showEvent( QShowEvent* theEvent )
00148 {
00149   raise();
00150   theEvent->ignore();
00151 }
00152 
00153 void QtxAbstractRubberBand::moveEvent( QMoveEvent* )
00154 {
00155 }
00156 
00157 void QtxAbstractRubberBand::resizeEvent( QResizeEvent* )
00158 {
00159 }
00160 
00161 bool QtxAbstractRubberBand::eventFilter( QObject* obj, QEvent* e )
00162 {
00163   if ( obj && obj == parent() && e->type() == QEvent::Resize )
00164     {
00165       QWidget* p = (QWidget*)parent();
00166       setGeometry( QRect(QPoint(0,0), p->size() ) );
00167     }
00168   return QWidget::eventFilter( obj, e );
00169 }
00170 
00171 QRegion createRegion( const QPointF& p1, const QPointF& p2 )
00172 {
00173   if ( p1 == p2 )
00174     return QRegion();
00175 
00176   QLineF n = QLineF( p1, p2 ).normalVector();//.unitVector();
00177   n.setLength( 1 );
00178   n.translate( p1 * -1 );
00179   QPointF nPoint = n.p2();
00180 
00181   QPolygonF p;
00182   p << p1 + nPoint << p2 + nPoint << p2 - nPoint << p1 - nPoint << p1 + nPoint;
00183 
00184   return QRegion( p.toPolygon() );
00185 }
00186 
00187 void QtxAbstractRubberBand::updateMask()
00188 {
00189   QRegion r;
00190 
00191   QVectorIterator<QPoint> it(myPoints);
00192   while( it.hasNext() )
00193     {
00194       QPoint p = it.next();
00195       if( !it.hasNext() )
00196         break;
00197 
00198       QPoint np = it.peekNext();
00199       
00200       if ( p == np ) continue;
00201 
00202       r += createRegion( p, np );
00203     }
00204 
00205   if ( isClosed() )
00206     r += createRegion( myPoints.last(), myPoints.first() );
00207 
00208   setMask( r );
00209 
00210 }
00211 
00212 
00213 QtxRectRubberBand::QtxRectRubberBand(QWidget* parent)
00214   :QtxAbstractRubberBand( parent )      
00215 {
00216   myPoints.resize( 4 );
00217   myIsClosed = true;
00218 }
00219 
00220 QtxRectRubberBand::~QtxRectRubberBand()
00221 {
00222 }
00223 
00224 void QtxRectRubberBand::initGeometry( const QRect& theRect )
00225 {
00226   myPoints.clear();
00227   myPoints << theRect.topLeft() << theRect.topRight() << theRect.bottomRight() << theRect.bottomLeft();
00228   //setMask( QRegion( myPoints ) );
00229   updateMask();
00230 }
00231 
00232 void QtxRectRubberBand::setStartPoint( const QPoint& thePoint )
00233 {
00234   myPoints[0] = thePoint;
00235   myPoints[1].setY( thePoint.y() );
00236   myPoints[3].setX( thePoint.x() );
00237   updateMask();
00238 }
00239 
00240 void QtxRectRubberBand::setEndPoint( const QPoint& thePoint)
00241 {
00242   myPoints[2] = thePoint;       
00243   myPoints[1].setX( thePoint.x() );
00244   myPoints[3].setY( thePoint.y() );
00245   updateMask();
00246 }
00247 
00248 void QtxRectRubberBand::clearGeometry()
00249 {
00250   QMutableVectorIterator<QPoint> i(myPoints);
00251   while (i.hasNext())
00252     {
00253       i.next();
00254       i.setValue( QPoint( -1, -1 ) );
00255     }
00256 }
00257 
00258 
00259 QtxPolyRubberBand::QtxPolyRubberBand(QWidget* parent)
00260   :QtxAbstractRubberBand( parent )
00261 {
00262 }
00263 
00264 QtxPolyRubberBand::~QtxPolyRubberBand()
00265 {
00266 }
00267 
00268 void QtxPolyRubberBand::initGeometry( const QPolygon& thePoints )
00269 {
00270   myPoints = thePoints;
00271   updateMask();
00272 }
00273 
00274 void QtxPolyRubberBand::initGeometry( const QPoint& thePoint )
00275 {
00276   myPoints.clear();  
00277   myPoints << thePoint;
00278   updateMask();
00279 }
00280 
00281 void QtxPolyRubberBand::addNode( const QPoint& thePoint )
00282 {
00283   myPoints << thePoint;
00284   updateMask();
00285 }
00286 
00287 void QtxPolyRubberBand::replaceLastNode( const QPoint& thePoint )
00288 {
00289   if ( !myPoints.empty() )
00290     {
00291       myPoints.pop_back();
00292       myPoints << thePoint;
00293       updateMask();
00294     }
00295 }
00296 
00297 void QtxPolyRubberBand::removeLastNode()
00298 {
00299   if ( !myPoints.empty() )
00300     {
00301       myPoints.pop_back();
00302       updateMask();
00303     }
00304 }
00305 
00306 void QtxPolyRubberBand::setClosed( bool theFlag )
00307 {
00308   if (myIsClosed != theFlag )
00309     {
00310       myIsClosed = theFlag;
00311       updateMask();
00312     }
00313 }