lib Library API Documentation

handler.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999, 2000 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., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include <handler.h>
00021 #include <koView.h>
00022 #include <math.h>
00023 #include <kcursor.h>
00024 #include <kdebug.h>
00025 
00026 EventHandler::EventHandler( QObject* target )
00027 {
00028     m_target = target;
00029 
00030     m_target->installEventFilter( this );
00031 }
00032 
00033 EventHandler::~EventHandler()
00034 {
00035 }
00036 
00037 QObject* EventHandler::target()
00038 {
00039     return m_target;
00040 }
00041 
00042 // ------------------------------------------------------
00043 
00044 class PartResizeHandlerPrivate {
00045 public:
00046     PartResizeHandlerPrivate( const QWMatrix& matrix, KoView *view, KoChild* child,
00047                               KoChild::Gadget gadget, const QPoint& point ) :
00048         m_gadget(gadget), m_view(view), m_child(child), m_parentMatrix(matrix) {
00049 
00050         m_geometryStart = child->geometry();
00051         m_matrix = child->matrix() * matrix;
00052         m_invertParentMatrix = matrix.invert();
00053 
00054         bool ok = true;
00055         m_invert = m_matrix.invert( &ok );
00056         Q_ASSERT( ok );
00057         m_mouseStart = m_invert.map( m_invertParentMatrix.map( point ) );
00058     }
00059     ~PartResizeHandlerPrivate() {}
00060 
00061     KoChild::Gadget m_gadget;
00062     QPoint m_mouseStart;
00063     QRect m_geometryStart;
00064     KoView* m_view;
00065     KoChild* m_child;
00066     QWMatrix m_invert;
00067     QWMatrix m_matrix;
00068     QWMatrix m_parentMatrix;
00069     QWMatrix m_invertParentMatrix;
00070 };
00071 
00072 PartResizeHandler::PartResizeHandler( QWidget* widget, const QWMatrix& matrix, KoView* view, KoChild* child,
00073                                       KoChild::Gadget gadget, const QPoint& point )
00074     : EventHandler( widget )
00075 {
00076     child->lock();
00077     d=new PartResizeHandlerPrivate(matrix, view, child, gadget, point);
00078 }
00079 
00080 PartResizeHandler::~PartResizeHandler()
00081 {
00082     d->m_child->unlock();
00083     delete d;
00084     d=0L;
00085 }
00086 
00087 void PartResizeHandler::repaint(QRegion &rgn)
00088 {
00089   rgn = rgn.unite( d->m_child->frameRegion( d->m_parentMatrix, true ) );
00090   rgn.translate(- d->m_view->canvasXOffset(), - d->m_view->canvasYOffset());
00091   ((QWidget*)target())->repaint( rgn );
00092 }
00093 
00094 bool PartResizeHandler::eventFilter( QObject*, QEvent* ev )
00095 {
00096     if ( ev->type() == QEvent::MouseButtonRelease )
00097     {
00098         delete this;
00099         return true;
00100     }
00101     else if ( ev->type() == QEvent::MouseMove )
00102     {
00103         QMouseEvent* e = (QMouseEvent*)ev;
00104         QPoint p = d->m_invert.map( d->m_invertParentMatrix.map( e->pos() + QPoint(d->m_view->canvasXOffset(), d->m_view->canvasYOffset()) ) );
00105         QRegion rgn( d->m_child->frameRegion( d->m_parentMatrix, true ) );
00106 
00107         double x1_x, x1_y, x2_x, x2_y;
00108         d->m_matrix.map( double( p.x() ), 0.0, &x1_x, &x1_y );
00109         d->m_matrix.map( double( d->m_mouseStart.x() ), 0.0, &x2_x, &x2_y );
00110         double y1_x, y1_y, y2_x, y2_y;
00111         d->m_matrix.map( 0.0, double( p.y() ), &y1_x, &y1_y );
00112         d->m_matrix.map( 0.0, double( d->m_mouseStart.y() ), &y2_x, &y2_y );
00113 
00114         double dx = x2_x - x1_x;
00115         double dy = x2_y - x1_y;
00116         int x = int( sqrt( dx * dx + dy * dy ) * ( d->m_mouseStart.x() < p.x() ? 1.0 : -1.0 ) );
00117 
00118         dx = y2_x - y1_x;
00119         dy = y2_y - y1_y;
00120         int y = int( sqrt( dx * dx + dy * dy ) * ( d->m_mouseStart.y() < p.y() ? 1.0 : -1.0 ) );
00121 
00122         switch( d->m_gadget )
00123         {
00124         case KoChild::TopLeft:
00125             {
00126                 x = QMIN( d->m_geometryStart.width() - 1, x );
00127                 y = QMIN( d->m_geometryStart.height() - 1, y );
00128 
00129                 d->m_child->setGeometry( QRect( d->m_geometryStart.x() + x, d->m_geometryStart.y() + y,
00130                                              d->m_geometryStart.width() - x, d->m_geometryStart.height() - y ) );
00131                 repaint(rgn);
00132             }
00133             break;
00134         case KoChild::TopMid:
00135             {
00136                 y = QMIN( d->m_geometryStart.height() - 1, y );
00137 
00138                 d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y() + y,
00139                                              d->m_geometryStart.width(), d->m_geometryStart.height() - y ) );
00140                 repaint(rgn);
00141             }
00142             break;
00143         case KoChild::TopRight:
00144             {
00145                 x = QMAX( -d->m_geometryStart.width() + 1, x );
00146                 y = QMIN( d->m_geometryStart.height() - 1, y );
00147 
00148                 d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y() + y,
00149                                              d->m_geometryStart.width() + x, d->m_geometryStart.height() - y ) );
00150                 repaint(rgn);
00151             }
00152             break;
00153         case KoChild::MidLeft:
00154             {
00155                 x = QMIN( d->m_geometryStart.width() - 1, x );
00156 
00157                 d->m_child->setGeometry( QRect( d->m_geometryStart.x() + x, d->m_geometryStart.y(),
00158                                              d->m_geometryStart.width() - x, d->m_geometryStart.height() ) );
00159                 repaint(rgn);
00160             }
00161             break;
00162         case KoChild::MidRight:
00163             {
00164                 x = QMAX( -d->m_geometryStart.width() + 1, x );
00165 
00166                 d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y(),
00167                                              d->m_geometryStart.width() + x, d->m_geometryStart.height() ) );
00168                 repaint(rgn);
00169             }
00170             break;
00171         case KoChild::BottomLeft:
00172             {
00173                 x = QMIN( d->m_geometryStart.width() - 1, x );
00174                 y = QMAX( -d->m_geometryStart.height() + 1, y );
00175 
00176                 d->m_child->setGeometry( QRect( d->m_geometryStart.x() + x, d->m_geometryStart.y(),
00177                                              d->m_geometryStart.width() - x, d->m_geometryStart.height() + y ) );
00178                 repaint(rgn);
00179             }
00180             break;
00181         case KoChild::BottomMid:
00182             {
00183                 y = QMAX( -d->m_geometryStart.height() + 1, y );
00184 
00185                 d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y(),
00186                                              d->m_geometryStart.width(), d->m_geometryStart.height() + y ) );
00187                 repaint(rgn);
00188             }
00189             break;
00190         case KoChild::BottomRight:
00191             {
00192                 x = QMAX( -d->m_geometryStart.width() + 1, x );
00193                 y = QMAX( -d->m_geometryStart.height() + 1, y );
00194 
00195                 d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y(),
00196                                              d->m_geometryStart.width() + x, d->m_geometryStart.height() + y ) );
00197                 repaint(rgn);
00198             }
00199             break;
00200         default:
00201             Q_ASSERT( 0 );
00202         }
00203         return true;
00204     }
00205     return false;
00206 }
00207 
00208 // --------------------------------------------------------------
00209 
00210 class PartMoveHandlerPrivate {
00211 public:
00212     PartMoveHandlerPrivate( const QWMatrix& matrix, KoView* view, KoChild* child,
00213                             const QPoint& point) : m_view(view), m_dragChild(child),
00214                                                    m_parentMatrix(matrix) {
00215         m_invertParentMatrix = matrix.invert();
00216         m_mouseDragStart = m_invertParentMatrix.map( point );
00217         m_geometryDragStart = m_dragChild->geometry();
00218         m_rotationDragStart = m_dragChild->rotationPoint();
00219     }
00220     ~PartMoveHandlerPrivate() {}
00221 
00222     KoView* m_view;
00223     KoChild* m_dragChild;
00224     QPoint m_mouseDragStart;
00225     QRect m_geometryDragStart;
00226     QPoint m_rotationDragStart;
00227     QWMatrix m_invertParentMatrix;
00228     QWMatrix m_parentMatrix;
00229 };
00230 
00231 PartMoveHandler::PartMoveHandler( QWidget* widget, const QWMatrix& matrix, KoView* view, KoChild* child,
00232                                   const QPoint& point )
00233     : EventHandler( widget )
00234 {
00235     child->lock();
00236     d=new PartMoveHandlerPrivate(matrix, view, child, point);
00237 }
00238 
00239 PartMoveHandler::~PartMoveHandler()
00240 {
00241     d->m_dragChild->unlock();
00242     delete d;
00243     d=0L;
00244 }
00245 
00246 bool PartMoveHandler::eventFilter( QObject*, QEvent* ev )
00247 {
00248     if ( ev->type() == QEvent::MouseButtonRelease )
00249     {
00250         delete this;
00251         return true;
00252     }
00253     else if ( ev->type() == QEvent::MouseMove )
00254     {
00255         QMouseEvent* e = (QMouseEvent*)ev;
00256 
00257         QRegion bound = d->m_dragChild->frameRegion( d->m_parentMatrix, true );
00258         QPoint pos = d->m_invertParentMatrix.map( e->pos()  + QPoint(d->m_view->canvasXOffset(), d->m_view->canvasYOffset()) );
00259         d->m_dragChild->setGeometry( QRect( d->m_geometryDragStart.x() + pos.x() - d->m_mouseDragStart.x(),
00260                                              d->m_geometryDragStart.y() + pos.y() - d->m_mouseDragStart.y(),
00261                                              d->m_geometryDragStart.width(), d->m_geometryDragStart.height() ) );
00262         d->m_dragChild->setRotationPoint( QPoint( d->m_rotationDragStart.x() + pos.x() - d->m_mouseDragStart.x(),
00263                                                d->m_rotationDragStart.y() + pos.y() - d->m_mouseDragStart.y() ) );
00264         bound = bound.unite( d->m_dragChild->frameRegion( d->m_parentMatrix, false ) );
00265         bound.translate(- d->m_view->canvasXOffset(), - d->m_view->canvasYOffset());
00266         ((QWidget*)target())->repaint( bound );
00267 
00268         return true;
00269     }
00270 
00271     return false;
00272 }
00273 
00274 // -------------------------------------------------------
00275 
00276 ContainerHandler::ContainerHandler( KoView* view, QWidget* widget )
00277     : EventHandler( widget )
00278 {
00279     m_view = view;
00280 }
00281 
00282 ContainerHandler::~ContainerHandler()
00283 {
00284 }
00285 
00286 bool ContainerHandler::eventFilter( QObject*, QEvent* ev )
00287 {
00288     if ( ev->type() == QEvent::MouseButtonPress )
00289     {
00290         KoChild::Gadget gadget;
00291         QPoint pos;
00292         QMouseEvent *e=static_cast<QMouseEvent*>(ev);
00293         KoChild *ch=child(gadget, pos, e);
00294 
00295     if ( e->button() == RightButton && gadget != KoChild::NoGadget )
00296         {
00297         emit popupMenu( ch, e->globalPos() );
00298             return true;
00299         }
00300         else if ( e->button() == LeftButton && gadget == KoChild::Move )
00301         {
00302             (void)new PartMoveHandler( static_cast<QWidget*>(target()), m_view->matrix(), m_view, ch, pos );
00303             return true;
00304         }
00305         else if ( e->button() == LeftButton && gadget != KoChild::NoGadget )
00306         {
00307             (void)new PartResizeHandler( static_cast<QWidget*>(target()), m_view->matrix(), m_view, ch, gadget, pos );
00308             return true;
00309         }
00310         return false;
00311     }
00312     else if ( ev->type() == QEvent::MouseMove )
00313     {
00314         QWidget *targetWidget = static_cast<QWidget *>( target() );
00315         KoChild::Gadget gadget;
00316         QPoint pos;
00317         QMouseEvent *e=static_cast<QMouseEvent*>(ev);
00318         child(gadget, pos, e);
00319 
00320         bool retval = true;
00321         if ( gadget == KoChild::NoGadget )
00322             retval = false;
00323 
00324         if ( gadget == KoChild::TopLeft || gadget == KoChild::BottomRight )
00325             targetWidget->setCursor( sizeFDiagCursor );
00326         else if ( gadget == KoChild::TopRight || gadget == KoChild::BottomLeft )
00327             targetWidget->setCursor( sizeBDiagCursor );
00328         else if ( gadget == KoChild::TopMid || gadget == KoChild::BottomMid )
00329             targetWidget->setCursor( sizeVerCursor );
00330         else if ( gadget == KoChild::MidLeft || gadget == KoChild::MidRight )
00331             targetWidget->setCursor( sizeHorCursor );
00332         else if ( gadget == KoChild::Move )
00333             targetWidget->setCursor( KCursor::handCursor() );
00334         else
00335         {
00336             targetWidget->setCursor( arrowCursor );
00337             return false;
00338         }
00339         return retval;
00340     }
00341     return false;
00342 }
00343 
00344 KoChild *ContainerHandler::child(KoChild::Gadget &gadget, QPoint &pos, const QMouseEvent *ev) {
00345 
00346     pos = ev->pos() + QPoint(m_view->canvasXOffset(), m_view->canvasYOffset());
00347 
00348     KoChild *child = 0;
00349     KoDocumentChild* docChild = m_view->selectedChild();
00350     gadget = KoChild::NoGadget;
00351     if ( docChild )
00352     {
00353         KoViewChild *viewChild = m_view->child( docChild->document() );
00354 
00355         if ( viewChild )
00356             child = viewChild;
00357         else
00358             child = docChild;
00359 
00360         gadget = child->gadgetHitTest( pos, m_view->matrix() );
00361     }
00362     if ( gadget == KoChild::NoGadget )
00363     {
00364         docChild = m_view->activeChild();
00365         if ( docChild )
00366         {
00367             KoViewChild *viewChild = m_view->child( docChild->document() );
00368 
00369             if ( viewChild )
00370                 child = viewChild;
00371             else
00372                 child = docChild;
00373 
00374             gadget = child->gadgetHitTest( pos, m_view->matrix() );
00375         }
00376     }
00377     return child;
00378 }
00379 
00380 #include <handler.moc>
KDE Logo
This file is part of the documentation for lib Library Version 1.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Feb 13 09:39:56 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003