/* This file is part of the KDE project Copyright (C) 1998, 1999 Torben Weis This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include class KoChild::KoChildPrivate { public: KoChildPrivate() { m_contentsX = m_contentsY = 0; } ~KoChildPrivate() { } TQRect m_tqgeometry; double m_rotation; double m_shearX; double m_shearY; TQPoint m_rotationPoint; double m_scaleX; double m_scaleY; TQWMatrix m_matrix; bool m_lock; TQPointArray m_old; bool m_transparent; int m_contentsX; int m_contentsY; }; KoChild::KoChild( TQObject *parent, const char *name ) : TQObject( parent, name ) { d = new KoChildPrivate; d->m_scaleX = d->m_scaleY = 1.0; d->m_shearX = d->m_shearY = 0.0; d->m_rotation = 0.0; d->m_lock = false; d->m_transparent = false; updateMatrix(); } KoChild::~KoChild() { delete d; } void KoChild::setGeometry( const TQRect &rect, bool noEmit ) { if ( !d->m_lock ) d->m_old = framePointArray(); d->m_tqgeometry = rect; // Embedded objects should have a minimum size of 3, so they can be selected if( d->m_tqgeometry.width() < 3 ) d->m_tqgeometry.setWidth( 3 ); if( d->m_tqgeometry.height() < 3 ) d->m_tqgeometry.setHeight( 3 ); updateMatrix(); if ( !d->m_lock && !noEmit ) emit changed( this ); } TQRect KoChild::tqgeometry() const { return d->m_tqgeometry; } TQRegion KoChild::region( const TQWMatrix &matrix ) const { return TQRegion( pointArray( matrix ) ); } TQPointArray KoChild::pointArray( const TQWMatrix &matrix ) const { return pointArray( TQRect( 0, 0, d->m_tqgeometry.width(), d->m_tqgeometry.height() ), matrix ); } //bool KoChild::contains( const TQPoint &point ) const //{ // return region().contains( point ); //} TQRect KoChild::boundingRect() const { return pointArray().boundingRect(); } bool KoChild::isRectangle() const { return !( d->m_shearX != 0.0 || d->m_shearY != 0.0 || d->m_rotation != 0.0 ); } void KoChild::setClipRegion( TQPainter &painter, bool combine ) { painter.setClipping( true ); if ( combine && !painter.clipRegion().isEmpty() ) painter.setClipRegion( region( painter.worldMatrix() ).intersect( painter.clipRegion() ) ); else painter.setClipRegion( region( painter.worldMatrix() ) ); } void KoChild::setScaling( double x, double y ) { if ( !d->m_lock ) d->m_old = framePointArray(); d->m_scaleX = x; d->m_scaleY = y; // why is that commented out? (Simon) // This is commented out, because KoChild::transform() scales // the world matrix explicitly and updateMatrix() doesn't even // handle scaling (Werner) //updateMatrix() if ( !d->m_lock ) emit changed( this ); } double KoChild::xScaling() const { return d->m_scaleX; } double KoChild::yScaling() const { return d->m_scaleY; } void KoChild::setShearing( double x, double y ) { if ( !d->m_lock ) d->m_old = framePointArray(); d->m_shearX = x; d->m_shearY = y; updateMatrix(); if ( !d->m_lock ) emit changed( this ); } double KoChild::xShearing() const { return d->m_shearX; } double KoChild::yShearing() const { return d->m_shearY; } void KoChild::setRotation( double rot ) { if ( !d->m_lock ) d->m_old = framePointArray(); d->m_rotation = rot; updateMatrix(); if ( !d->m_lock ) emit changed( this ); } double KoChild::rotation() const { return d->m_rotation; } void KoChild::setRotationPoint( const TQPoint &pos ) { if ( !d->m_lock ) d->m_old = framePointArray(); d->m_rotationPoint = pos; updateMatrix(); if ( !d->m_lock ) emit changed( this ); } TQPoint KoChild::rotationPoint() const { return d->m_rotationPoint; } void KoChild::transform( TQPainter &painter ) { setClipRegion( painter, true ); TQWMatrix m = painter.worldMatrix(); m = d->m_matrix * m; m.scale( d->m_scaleX, d->m_scaleY ); painter.setWorldMatrix( m ); } void KoChild::setContentsPos( int x, int y ) { d->m_contentsX = x; d->m_contentsY = y; } TQRect KoChild::contentRect() const { return TQRect( d->m_contentsX, d->m_contentsY, int(d->m_tqgeometry.width() / d->m_scaleX), int(d->m_tqgeometry.height() / d->m_scaleY) ); } TQPointArray KoChild::framePointArray( const TQWMatrix &matrix ) const { return pointArray( TQRect( -6, -6, d->m_tqgeometry.width() + 12, d->m_tqgeometry.height() + 12 ), matrix ); } TQRegion KoChild::frameRegion( const TQWMatrix &matrix, bool solid ) const { const TQPointArray arr = framePointArray( matrix ); const TQRegion frameReg( arr ); if ( solid ) return frameReg; const TQRegion reg = region( matrix ); return frameReg.subtract( reg ); } TQPointArray KoChild::pointArray( const TQRect &r, const TQWMatrix &matrix ) const { TQPoint topleft = d->m_matrix.map( TQPoint( r.left(), r.top() ) ); TQPoint topright = d->m_matrix.map( TQPoint( r.right(), r.top() ) ); TQPoint bottomleft = d->m_matrix.map( TQPoint( r.left(), r.bottom() ) ); TQPoint bottomright = d->m_matrix.map( TQPoint( r.right(), r.bottom() ) ); TQPointArray arr( 4 ); arr.setPoint( 0, topleft ); arr.setPoint( 1, topright ); arr.setPoint( 2, bottomright ); arr.setPoint( 3, bottomleft ); for( int i = 0; i < 4; ++i ) arr.setPoint( i, matrix.map( arr.point( i ) ) ); return arr; } void KoChild::updateMatrix() { TQWMatrix r; r.rotate( - d->m_rotation ); TQPoint p = r.map( TQPoint( d->m_rotationPoint.x(), d->m_rotationPoint.y() ) ); TQWMatrix m; m.rotate( d->m_rotation ); m.translate( -d->m_rotationPoint.x() + d->m_tqgeometry.x(), -d->m_rotationPoint.y() + d->m_tqgeometry.y() ); m.translate( p.x(), p.y() ); m.shear( d->m_shearX, d->m_shearY ); d->m_matrix = m; } TQWMatrix KoChild::matrix() const { return d->m_matrix; } void KoChild::lock() { if ( d->m_lock ) return; d->m_old = framePointArray(); d->m_lock = true; } void KoChild::unlock() { if ( !d->m_lock ) return; d->m_lock = false; emit changed( this ); } bool KoChild::locked() const { return d->m_lock; } TQPointArray KoChild::oldPointArray( const TQWMatrix &matrix ) { TQPointArray arr = d->m_old; for( int i = 0; i < 4; ++i ) arr.setPoint( i, matrix.map( arr.point( i ) ) ); return arr; } void KoChild::setTransparent( bool transparent ) { d->m_transparent = transparent; } bool KoChild::isTransparent() const { return d->m_transparent; } KoChild::Gadget KoChild::gadgetHitTest( const TQPoint &p ) { if ( !frameRegion().contains( p ) ) return NoGadget; if ( TQRegion( pointArray( TQRect( -5, -5, 5, 5 ) ) ).contains( p ) ) return TopLeft; if ( TQRegion( pointArray( TQRect( d->m_tqgeometry.width() / 2 - 3, -5, 5, 5 ) ) ).contains( p ) ) return TopMid; if ( TQRegion( pointArray( TQRect( d->m_tqgeometry.width(), -5, 5, 5 ) ) ).contains( p ) ) return TopRight; if ( TQRegion( pointArray( TQRect( -5, d->m_tqgeometry.height() / 2 - 3, 5, 5 ) ) ).contains( p ) ) return MidLeft; if ( TQRegion( pointArray( TQRect( -5, d->m_tqgeometry.height(), 5, 5 ) ) ).contains( p ) ) return BottomLeft; if ( TQRegion( pointArray( TQRect( d->m_tqgeometry.width() / 2 - 3, d->m_tqgeometry.height(), 5, 5 ) ) ).contains( p ) ) return BottomMid; if ( TQRegion( pointArray( TQRect( d->m_tqgeometry.width(), d->m_tqgeometry.height(), 5, 5 ) ) ).contains( p ) ) return BottomRight; if ( TQRegion( pointArray( TQRect( d->m_tqgeometry.width(), d->m_tqgeometry.height() / 2 - 3, 5, 5 ) ) ).contains( p ) ) return MidRight; return Move; } #include