/* This file is part of the KDE project Copyright (C) 1998, 1999, 2000 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 "KoContainerHandler.h" #include #include #include #include KoEventHandler::KoEventHandler( TQObject* target ) { m_target = target; m_target->installEventFilter( this ); } KoEventHandler::~KoEventHandler() { } TQObject* KoEventHandler::target() { return m_target; } // ------------------------------------------------------ class KoPartResizeHandlerPrivate { public: KoPartResizeHandlerPrivate( const TQWMatrix& matrix, KoView *view, KoChild* child, KoChild::Gadget gadget, const TQPoint& point ) : m_gadget(gadget), m_view(view), m_child(child), m_parentMatrix(matrix) { m_geometryStart = child->geometry(); m_matrix = child->matrix() * matrix; m_invertParentMatrix = matrix.invert(); bool ok = true; m_invert = m_matrix.invert( &ok ); Q_ASSERT( ok ); m_mouseStart = m_invert.map( m_invertParentMatrix.map( point ) ); } ~KoPartResizeHandlerPrivate() {} KoChild::Gadget m_gadget; TQPoint m_mouseStart; TQRect m_geometryStart; KoView* m_view; KoChild* m_child; TQWMatrix m_invert; TQWMatrix m_matrix; TQWMatrix m_parentMatrix; TQWMatrix m_invertParentMatrix; }; KoPartResizeHandler::KoPartResizeHandler( TQWidget* widget, const TQWMatrix& matrix, KoView* view, KoChild* child, KoChild::Gadget gadget, const TQPoint& point ) : KoEventHandler( TQT_TQOBJECT(widget) ) { child->lock(); d=new KoPartResizeHandlerPrivate(matrix, view, child, gadget, point); } KoPartResizeHandler::~KoPartResizeHandler() { d->m_child->unlock(); delete d; d=0L; } void KoPartResizeHandler::repaint(TQRegion &rgn) { rgn = rgn.unite( d->m_child->frameRegion( d->m_parentMatrix, true ) ); // rgn.translate(- d->m_view->canvasXOffset(), - d->m_view->canvasYOffset()); ((TQWidget*)target())->repaint( rgn ); } bool KoPartResizeHandler::eventFilter( TQObject*, TQEvent* ev ) { if ( ev->type() == TQEvent::MouseButtonRelease ) { delete this; return true; } else if ( ev->type() == TQEvent::MouseMove ) { TQMouseEvent* e = (TQMouseEvent*)ev; TQPoint p = d->m_invert.map( d->m_invertParentMatrix.map( e->pos() /*+ TQPoint(d->m_view->canvasXOffset(), d->m_view->canvasYOffset()) */ ) ); TQRegion rgn( d->m_child->frameRegion( d->m_parentMatrix, true ) ); double x1_x, x1_y, x2_x, x2_y; d->m_matrix.map( double( p.x() ), 0.0, &x1_x, &x1_y ); d->m_matrix.map( double( d->m_mouseStart.x() ), 0.0, &x2_x, &x2_y ); double y1_x, y1_y, y2_x, y2_y; d->m_matrix.map( 0.0, double( p.y() ), &y1_x, &y1_y ); d->m_matrix.map( 0.0, double( d->m_mouseStart.y() ), &y2_x, &y2_y ); double dx = x2_x - x1_x; double dy = x2_y - x1_y; int x = int( sqrt( dx * dx + dy * dy ) * ( d->m_mouseStart.x() < p.x() ? 1.0 : -1.0 ) ); dx = y2_x - y1_x; dy = y2_y - y1_y; int y = int( sqrt( dx * dx + dy * dy ) * ( d->m_mouseStart.y() < p.y() ? 1.0 : -1.0 ) ); switch( d->m_gadget ) { case KoChild::TopLeft: { x = TQMIN( d->m_geometryStart.width() - 1, x ); y = TQMIN( d->m_geometryStart.height() - 1, y ); d->m_child->setGeometry( TQRect( d->m_geometryStart.x() + x, d->m_geometryStart.y() + y, d->m_geometryStart.width() - x, d->m_geometryStart.height() - y ) ); repaint(rgn); } break; case KoChild::TopMid: { y = TQMIN( d->m_geometryStart.height() - 1, y ); d->m_child->setGeometry( TQRect( d->m_geometryStart.x(), d->m_geometryStart.y() + y, d->m_geometryStart.width(), d->m_geometryStart.height() - y ) ); repaint(rgn); } break; case KoChild::TopRight: { x = TQMAX( -d->m_geometryStart.width() + 1, x ); y = TQMIN( d->m_geometryStart.height() - 1, y ); d->m_child->setGeometry( TQRect( d->m_geometryStart.x(), d->m_geometryStart.y() + y, d->m_geometryStart.width() + x, d->m_geometryStart.height() - y ) ); repaint(rgn); } break; case KoChild::MidLeft: { x = TQMIN( d->m_geometryStart.width() - 1, x ); d->m_child->setGeometry( TQRect( d->m_geometryStart.x() + x, d->m_geometryStart.y(), d->m_geometryStart.width() - x, d->m_geometryStart.height() ) ); repaint(rgn); } break; case KoChild::MidRight: { x = TQMAX( -d->m_geometryStart.width() + 1, x ); d->m_child->setGeometry( TQRect( d->m_geometryStart.x(), d->m_geometryStart.y(), d->m_geometryStart.width() + x, d->m_geometryStart.height() ) ); repaint(rgn); } break; case KoChild::BottomLeft: { x = TQMIN( d->m_geometryStart.width() - 1, x ); y = TQMAX( -d->m_geometryStart.height() + 1, y ); d->m_child->setGeometry( TQRect( d->m_geometryStart.x() + x, d->m_geometryStart.y(), d->m_geometryStart.width() - x, d->m_geometryStart.height() + y ) ); repaint(rgn); } break; case KoChild::BottomMid: { y = TQMAX( -d->m_geometryStart.height() + 1, y ); d->m_child->setGeometry( TQRect( d->m_geometryStart.x(), d->m_geometryStart.y(), d->m_geometryStart.width(), d->m_geometryStart.height() + y ) ); repaint(rgn); } break; case KoChild::BottomRight: { x = TQMAX( -d->m_geometryStart.width() + 1, x ); y = TQMAX( -d->m_geometryStart.height() + 1, y ); d->m_child->setGeometry( TQRect( d->m_geometryStart.x(), d->m_geometryStart.y(), d->m_geometryStart.width() + x, d->m_geometryStart.height() + y ) ); repaint(rgn); } break; default: Q_ASSERT( 0 ); } return true; } return false; } // -------------------------------------------------------------- class KoPartMoveHandlerPrivate { public: KoPartMoveHandlerPrivate( const TQWMatrix& matrix, KoView* view, KoChild* child, const TQPoint& point) : m_view(view), m_dragChild(child), m_parentMatrix(matrix) { m_invertParentMatrix = matrix.invert(); m_mouseDragStart = m_invertParentMatrix.map( point ); m_geometryDragStart = m_dragChild->geometry(); m_rotationDragStart = m_dragChild->rotationPoint(); } ~KoPartMoveHandlerPrivate() {} KoView* m_view; KoChild* m_dragChild; TQPoint m_mouseDragStart; TQRect m_geometryDragStart; TQPoint m_rotationDragStart; TQWMatrix m_invertParentMatrix; TQWMatrix m_parentMatrix; }; KoPartMoveHandler::KoPartMoveHandler( TQWidget* widget, const TQWMatrix& matrix, KoView* view, KoChild* child, const TQPoint& point ) : KoEventHandler( TQT_TQOBJECT(widget) ) { child->lock(); d=new KoPartMoveHandlerPrivate(matrix, view, child, point); } KoPartMoveHandler::~KoPartMoveHandler() { d->m_dragChild->unlock(); delete d; d=0L; } bool KoPartMoveHandler::eventFilter( TQObject*, TQEvent* ev ) { if ( ev->type() == TQEvent::MouseButtonRelease ) { delete this; return true; } else if ( ev->type() == TQEvent::MouseMove ) { TQMouseEvent* e = (TQMouseEvent*)ev; TQRegion bound = d->m_dragChild->frameRegion( d->m_parentMatrix, true ); TQPoint pos = d->m_invertParentMatrix.map( e->pos() /* + TQPoint(d->m_view->canvasXOffset(), d->m_view->canvasYOffset()) */ ); d->m_dragChild->setGeometry( TQRect( d->m_geometryDragStart.x() + pos.x() - d->m_mouseDragStart.x(), d->m_geometryDragStart.y() + pos.y() - d->m_mouseDragStart.y(), d->m_geometryDragStart.width(), d->m_geometryDragStart.height() ) ); d->m_dragChild->setRotationPoint( TQPoint( d->m_rotationDragStart.x() + pos.x() - d->m_mouseDragStart.x(), d->m_rotationDragStart.y() + pos.y() - d->m_mouseDragStart.y() ) ); bound = bound.unite( d->m_dragChild->frameRegion( d->m_parentMatrix, false ) ); // bound.translate(- d->m_view->canvasXOffset(), - d->m_view->canvasYOffset()); ((TQWidget*)target())->repaint( bound ); return true; } return false; } // ------------------------------------------------------- KoContainerHandler::KoContainerHandler( KoView* view, TQWidget* widget ) : KoEventHandler( TQT_TQOBJECT(widget) ) { m_view = view; } KoContainerHandler::~KoContainerHandler() { } bool KoContainerHandler::eventFilter( TQObject*, TQEvent* ev ) { if ( ev->type() == TQEvent::KeyPress ) { TQKeyEvent* keyEvent=(TQKeyEvent*)ev; KoChild* child=m_view->selectedChild(); if (child != 0) { if (keyEvent->key()==TQt::Key_Delete) emit deleteChild(child); } } if ( ev->type() == TQEvent::MouseButtonPress ) { KoChild::Gadget gadget; TQPoint pos; TQMouseEvent *e=TQT_TQMOUSEEVENT(ev); KoChild *ch=child(gadget, pos, e); if ( e->button() == TQt::RightButton && gadget != KoChild::NoGadget ) { emit popupMenu( ch, e->globalPos() ); return true; } else if ( e->button() == TQt::LeftButton && gadget == KoChild::Move ) { (void)new KoPartMoveHandler( TQT_TQWIDGET(target()), m_view->matrix(), m_view, ch, pos ); return true; } else if ( e->button() == TQt::LeftButton && gadget != KoChild::NoGadget ) { (void)new KoPartResizeHandler( TQT_TQWIDGET(target()), m_view->matrix(), m_view, ch, gadget, pos ); return true; } return false; } else if ( ev->type() == TQEvent::MouseMove ) { TQWidget *targetWidget = TQT_TQWIDGET( target() ); KoChild::Gadget gadget; TQPoint pos; TQMouseEvent *e=TQT_TQMOUSEEVENT(ev); child(gadget, pos, e); bool retval = true; if ( gadget == KoChild::NoGadget ) retval = false; if ( gadget == KoChild::TopLeft || gadget == KoChild::BottomRight ) targetWidget->setCursor( sizeFDiagCursor ); else if ( gadget == KoChild::TopRight || gadget == KoChild::BottomLeft ) targetWidget->setCursor( sizeBDiagCursor ); else if ( gadget == KoChild::TopMid || gadget == KoChild::BottomMid ) targetWidget->setCursor( sizeVerCursor ); else if ( gadget == KoChild::MidLeft || gadget == KoChild::MidRight ) targetWidget->setCursor( sizeHorCursor ); else if ( gadget == KoChild::Move ) targetWidget->setCursor( KCursor::handCursor() ); else { // targetWidget->setCursor( arrowCursor ); return false; } return retval; } return false; } KoChild *KoContainerHandler::child(KoChild::Gadget &gadget, TQPoint &pos, const TQMouseEvent *ev) { pos = ev->pos(); //+ TQPoint(m_view->canvasXOffset(), m_view->canvasYOffset()); pos = m_view->reverseViewTransformations( pos ); KoChild *child = 0; KoDocumentChild* docChild = m_view->selectedChild(); gadget = KoChild::NoGadget; if ( docChild ) { KoViewChild *viewChild = m_view->child( docChild->document() ); if ( viewChild ) child = viewChild; else child = docChild; gadget = child->gadgetHitTest( pos ); } if ( gadget == KoChild::NoGadget ) { docChild = m_view->activeChild(); if ( docChild ) { KoViewChild *viewChild = m_view->child( docChild->document() ); if ( viewChild ) child = viewChild; else child = docChild; gadget = child->gadgetHitTest( pos ); } } return child; } #include "KoContainerHandler.moc"