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.3.5.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Nov 17 06:54:14 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003