00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <KoChild.h>
00021
00022 #include <QPainter>
00023
00024 #include <QPolygon>
00025
00026 #include <kdebug.h>
00027
00028 class KoChild::KoChildPrivate
00029 {
00030 public:
00031 KoChildPrivate()
00032 {
00033 m_contentsX = m_contentsY = 0;
00034 }
00035 ~KoChildPrivate()
00036 {
00037 }
00038
00039 QRect m_geometry;
00040
00041 double m_rotation;
00042 double m_shearX;
00043 double m_shearY;
00044 QPoint m_rotationPoint;
00045 double m_scaleX;
00046 double m_scaleY;
00047 QMatrix m_matrix;
00048 bool m_lock;
00049 QPolygon m_old;
00050 bool m_transparent;
00051 int m_contentsX;
00052 int m_contentsY;
00053 };
00054
00055 KoChild::KoChild( QObject *parent, const char* )
00056 : QObject( parent )
00057 {
00058 d = new KoChildPrivate;
00059
00060 d->m_scaleX = d->m_scaleY = 1.0;
00061 d->m_shearX = d->m_shearY = 0.0;
00062 d->m_rotation = 0.0;
00063 d->m_lock = false;
00064 d->m_transparent = false;
00065
00066 updateMatrix();
00067 }
00068
00069 KoChild::~KoChild()
00070 {
00071 delete d;
00072 }
00073
00074 void KoChild::setGeometry( const QRect &rect, bool noEmit )
00075 {
00076 if ( !d->m_lock )
00077 d->m_old = framePointArray();
00078
00079 d->m_geometry = rect;
00080
00081
00082 if( d->m_geometry.width() < 3 )
00083 d->m_geometry.setWidth( 3 );
00084
00085 if( d->m_geometry.height() < 3 )
00086 d->m_geometry.setHeight( 3 );
00087
00088 updateMatrix();
00089
00090 if ( !d->m_lock && !noEmit )
00091 emit changed( this );
00092 }
00093
00094 QRect KoChild::geometry() const
00095 {
00096 return d->m_geometry;
00097 }
00098
00099 QRegion KoChild::region( const QMatrix &matrix ) const
00100 {
00101 return QRegion( pointArray( matrix ) );
00102 }
00103
00104 QPolygon KoChild::pointArray( const QMatrix &matrix ) const
00105 {
00106 return pointArray( QRect( 0, 0, d->m_geometry.width(), d->m_geometry.height() ), matrix );
00107 }
00108
00109
00110
00111
00112
00113
00114 QRect KoChild::boundingRect() const
00115 {
00116 return pointArray().boundingRect();
00117 }
00118
00119 bool KoChild::isRectangle() const
00120 {
00121 return !( d->m_shearX != 0.0 || d->m_shearY != 0.0 || d->m_rotation != 0.0 );
00122 }
00123
00124 void KoChild::setClipRegion( QPainter &painter, bool combine )
00125 {
00126 painter.setClipping( true );
00127 if ( combine && !painter.clipRegion().isEmpty() )
00128 painter.setClipRegion( region( painter.matrix() ).intersect( painter.clipRegion() ) );
00129 else
00130 painter.setClipRegion( region( painter.matrix() ) );
00131 }
00132
00133 void KoChild::setScaling( double x, double y )
00134 {
00135 if ( !d->m_lock )
00136 d->m_old = framePointArray();
00137
00138 d->m_scaleX = x;
00139 d->m_scaleY = y;
00140
00141
00142
00143
00144
00145
00146
00147 if ( !d->m_lock )
00148 emit changed( this );
00149 }
00150
00151 double KoChild::xScaling() const
00152 {
00153 return d->m_scaleX;
00154 }
00155
00156 double KoChild::yScaling() const
00157 {
00158 return d->m_scaleY;
00159 }
00160
00161 void KoChild::setShearing( double x, double y )
00162 {
00163 if ( !d->m_lock )
00164 d->m_old = framePointArray();
00165
00166 d->m_shearX = x;
00167 d->m_shearY = y;
00168
00169 updateMatrix();
00170
00171 if ( !d->m_lock )
00172 emit changed( this );
00173 }
00174
00175 double KoChild::xShearing() const
00176 {
00177 return d->m_shearX;
00178 }
00179
00180 double KoChild::yShearing() const
00181 {
00182 return d->m_shearY;
00183 }
00184
00185 void KoChild::setRotation( double rot )
00186 {
00187 if ( !d->m_lock )
00188 d->m_old = framePointArray();
00189
00190 d->m_rotation = rot;
00191 updateMatrix();
00192
00193 if ( !d->m_lock )
00194 emit changed( this );
00195 }
00196
00197 double KoChild::rotation() const
00198 {
00199 return d->m_rotation;
00200 }
00201
00202 void KoChild::setRotationPoint( const QPoint &pos )
00203 {
00204 if ( !d->m_lock )
00205 d->m_old = framePointArray();
00206
00207 d->m_rotationPoint = pos;
00208 updateMatrix();
00209
00210 if ( !d->m_lock )
00211 emit changed( this );
00212 }
00213
00214 QPoint KoChild::rotationPoint() const
00215 {
00216 return d->m_rotationPoint;
00217 }
00218
00219 void KoChild::transform( QPainter &painter )
00220 {
00221 setClipRegion( painter, true );
00222
00223 QMatrix m = painter.matrix();
00224 m = d->m_matrix * m;
00225 m.scale( d->m_scaleX, d->m_scaleY );
00226 painter.setMatrix( m );
00227 }
00228
00229 void KoChild::setContentsPos( int x, int y )
00230 {
00231 d->m_contentsX = x;
00232 d->m_contentsY = y;
00233 }
00234
00235 QRect KoChild::contentRect() const
00236 {
00237 return QRect( d->m_contentsX, d->m_contentsY, int(d->m_geometry.width() / d->m_scaleX),
00238 int(d->m_geometry.height() / d->m_scaleY) );
00239 }
00240
00241 QPolygon KoChild::framePointArray( const QMatrix &matrix ) const
00242 {
00243 return pointArray( QRect( -6, -6, d->m_geometry.width() + 12, d->m_geometry.height() + 12 ), matrix );
00244 }
00245
00246 QRegion KoChild::frameRegion( const QMatrix &matrix, bool solid ) const
00247 {
00248 const QPolygon arr = framePointArray( matrix );
00249 const QRegion frameReg( arr );
00250
00251 if ( solid )
00252 return frameReg;
00253
00254 const QRegion reg = region( matrix );
00255 return frameReg.subtract( reg );
00256 }
00257
00258 QPolygon KoChild::pointArray( const QRect &r, const QMatrix &matrix ) const
00259 {
00260 QPoint topleft = d->m_matrix.map( QPoint( r.left(), r.top() ) );
00261 QPoint topright = d->m_matrix.map( QPoint( r.right(), r.top() ) );
00262 QPoint bottomleft = d->m_matrix.map( QPoint( r.left(), r.bottom() ) );
00263 QPoint bottomright = d->m_matrix.map( QPoint( r.right(), r.bottom() ) );
00264
00265 QPolygon arr( 4 );
00266 arr.setPoint( 0, topleft );
00267 arr.setPoint( 1, topright );
00268 arr.setPoint( 2, bottomright );
00269 arr.setPoint( 3, bottomleft );
00270
00271 for( int i = 0; i < 4; ++i )
00272 arr.setPoint( i, matrix.map( arr.point( i ) ) );
00273
00274 return arr;
00275 }
00276
00277 void KoChild::updateMatrix()
00278 {
00279 QMatrix r;
00280 r.rotate( - d->m_rotation );
00281 QPoint p = r.map( QPoint( d->m_rotationPoint.x(),
00282 d->m_rotationPoint.y() ) );
00283
00284 QMatrix m;
00285 m.rotate( d->m_rotation );
00286 m.translate( -d->m_rotationPoint.x() + d->m_geometry.x(), -d->m_rotationPoint.y() + d->m_geometry.y() );
00287 m.translate( p.x(), p.y() );
00288 m.shear( d->m_shearX, d->m_shearY );
00289
00290 d->m_matrix = m;
00291 }
00292
00293 QMatrix KoChild::matrix() const
00294 {
00295 return d->m_matrix;
00296 }
00297
00298 void KoChild::lock()
00299 {
00300 if ( d->m_lock )
00301 return;
00302
00303 d->m_old = framePointArray();
00304 d->m_lock = true;
00305 }
00306
00307 void KoChild::unlock()
00308 {
00309 if ( !d->m_lock )
00310 return;
00311
00312 d->m_lock = false;
00313 emit changed( this );
00314 }
00315
00316 bool KoChild::locked() const
00317 {
00318 return d->m_lock;
00319 }
00320
00321 QPolygon KoChild::oldPointArray( const QMatrix &matrix )
00322 {
00323 QPolygon arr = d->m_old;
00324
00325 for( int i = 0; i < 4; ++i )
00326 arr.setPoint( i, matrix.map( arr.point( i ) ) );
00327
00328 return arr;
00329 }
00330
00331 void KoChild::setTransparent( bool transparent )
00332 {
00333 d->m_transparent = transparent;
00334 }
00335
00336 bool KoChild::isTransparent() const
00337 {
00338 return d->m_transparent;
00339 }
00340
00341 KoChild::Gadget KoChild::gadgetHitTest( const QPoint &p )
00342 {
00343 if ( !frameRegion().contains( p ) )
00344 return NoGadget;
00345
00346 if ( QRegion( pointArray( QRect( -5, -5, 5, 5 ) ) ).contains( p ) )
00347 return TopLeft;
00348 if ( QRegion( pointArray( QRect( d->m_geometry.width() / 2 - 3, -5, 5, 5 ) ) ).contains( p ) )
00349 return TopMid;
00350 if ( QRegion( pointArray( QRect( d->m_geometry.width(), -5, 5, 5 ) ) ).contains( p ) )
00351 return TopRight;
00352 if ( QRegion( pointArray( QRect( -5, d->m_geometry.height() / 2 - 3, 5, 5 ) ) ).contains( p ) )
00353 return MidLeft;
00354 if ( QRegion( pointArray( QRect( -5, d->m_geometry.height(), 5, 5 ) ) ).contains( p ) )
00355 return BottomLeft;
00356 if ( QRegion( pointArray( QRect( d->m_geometry.width() / 2 - 3,
00357 d->m_geometry.height(), 5, 5 ) ) ).contains( p ) )
00358 return BottomMid;
00359 if ( QRegion( pointArray( QRect( d->m_geometry.width(), d->m_geometry.height(), 5, 5 ) ) ).contains( p ) )
00360 return BottomRight;
00361 if ( QRegion( pointArray( QRect( d->m_geometry.width(),
00362 d->m_geometry.height() / 2 - 3, 5, 5 ) ) ).contains( p ) )
00363 return MidRight;
00364
00365 return Move;
00366 }
00367
00368 #include <KoChild.moc>