lib

KoChild.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
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   // Embedded objects should have a minimum size of 3, so they can be selected
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
00113 {
00114   return pointArray().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   // why is that commented out? (Simon)
00140   // This is commented out, because KoChild::transform() scales
00141   // the world matrix explicitly and updateMatrix() doesn't even
00142   // handle scaling (Werner)
00143   //updateMatrix()
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   const QPointArray arr = framePointArray( matrix );
00247   const QRegion frameReg( arr );
00248 
00249   if ( solid )
00250     return frameReg;
00251 
00252   const QRegion reg = region( matrix );
00253   return frameReg.subtract( reg );
00254 }
00255 
00256 QPointArray KoChild::pointArray( const QRect &r, const QWMatrix &matrix ) const
00257 {
00258   QPoint topleft = d->m_matrix.map( QPoint( r.left(), r.top() ) );
00259   QPoint topright = d->m_matrix.map( QPoint( r.right(), r.top() ) );
00260   QPoint bottomleft = d->m_matrix.map( QPoint( r.left(), r.bottom() ) );
00261   QPoint bottomright = d->m_matrix.map( QPoint( r.right(), r.bottom() ) );
00262 
00263   QPointArray arr( 4 );
00264   arr.setPoint( 0, topleft );
00265   arr.setPoint( 1, topright );
00266   arr.setPoint( 2, bottomright );
00267   arr.setPoint( 3, bottomleft );
00268 
00269   for( int i = 0; i < 4; ++i )
00270       arr.setPoint( i, matrix.map( arr.point( i ) ) );
00271 
00272   return arr;
00273 }
00274 
00275 void KoChild::updateMatrix()
00276 {
00277   QWMatrix r;
00278   r.rotate( - d->m_rotation );
00279   QPoint p = r.map( QPoint( d->m_rotationPoint.x(),
00280                 d->m_rotationPoint.y() ) );
00281 
00282   QWMatrix m;
00283   m.rotate( d->m_rotation );
00284   m.translate( -d->m_rotationPoint.x() + d->m_geometry.x(), -d->m_rotationPoint.y() + d->m_geometry.y() );
00285   m.translate( p.x(), p.y() );
00286   m.shear( d->m_shearX, d->m_shearY );
00287 
00288   d->m_matrix = m;
00289 }
00290 
00291 QWMatrix KoChild::matrix() const
00292 {
00293   return d->m_matrix;
00294 }
00295 
00296 void KoChild::lock()
00297 {
00298   if ( d->m_lock )
00299     return;
00300 
00301   d->m_old = framePointArray();
00302   d->m_lock = true;
00303 }
00304 
00305 void KoChild::unlock()
00306 {
00307   if ( !d->m_lock )
00308     return;
00309 
00310   d->m_lock = false;
00311   emit changed( this );
00312 }
00313 
00314 bool KoChild::locked() const
00315 {
00316   return d->m_lock;
00317 }
00318 
00319 QPointArray KoChild::oldPointArray( const QWMatrix &matrix )
00320 {
00321   QPointArray arr = d->m_old;
00322 
00323   for( int i = 0; i < 4; ++i )
00324       arr.setPoint( i, matrix.map( arr.point( i ) ) );
00325 
00326   return arr;
00327 }
00328 
00329 void KoChild::setTransparent( bool transparent )
00330 {
00331   d->m_transparent = transparent;
00332 }
00333 
00334 bool KoChild::isTransparent() const
00335 {
00336   return d->m_transparent;
00337 }
00338 
00339 KoChild::Gadget KoChild::gadgetHitTest( const QPoint &p )
00340 {
00341   if ( !frameRegion().contains( p ) )
00342     return NoGadget;
00343 
00344   if ( QRegion( pointArray( QRect( -5, -5, 5, 5 ) ) ).contains( p ) )
00345       return TopLeft;
00346   if ( QRegion( pointArray( QRect( d->m_geometry.width() / 2 - 3, -5, 5, 5 ) ) ).contains( p ) )
00347       return TopMid;
00348   if ( QRegion( pointArray( QRect( d->m_geometry.width(), -5, 5, 5 ) ) ).contains( p ) )
00349       return TopRight;
00350   if ( QRegion( pointArray( QRect( -5, d->m_geometry.height() / 2 - 3, 5, 5 ) ) ).contains( p ) )
00351       return MidLeft;
00352   if ( QRegion( pointArray( QRect( -5, d->m_geometry.height(), 5, 5 ) ) ).contains( p ) )
00353       return BottomLeft;
00354   if ( QRegion( pointArray( QRect( d->m_geometry.width() / 2 - 3,
00355                    d->m_geometry.height(), 5, 5 ) ) ).contains( p ) )
00356     return BottomMid;
00357   if ( QRegion( pointArray( QRect( d->m_geometry.width(), d->m_geometry.height(), 5, 5 ) ) ).contains( p ) )
00358       return BottomRight;
00359   if ( QRegion( pointArray( QRect( d->m_geometry.width(),
00360                    d->m_geometry.height() / 2 - 3, 5, 5 ) ) ).contains( p ) )
00361     return MidRight;
00362 
00363   return Move;
00364 }
00365 
00366 #include <KoChild.moc>
KDE Home | KDE Accessibility Home | Description of Access Keys