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