F:/KPlato/koffice/libs/flake/KoShapeResizeStrategy.cpp

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002  * Copyright (C) 2006 Thomas Zander <zander@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 "KoShapeResizeStrategy.h"
00021 #include "KoShapeManager.h"
00022 #include "KoPointerEvent.h"
00023 #include "KoCanvasBase.h"
00024 #include "KoCommand.h"
00025 
00026 #include <kdebug.h>
00027 
00028 KoShapeResizeStrategy::KoShapeResizeStrategy( KoTool *tool, KoCanvasBase *canvas,
00029         const QPointF &clicked, KoFlake::SelectionHandle direction )
00030 : KoInteractionStrategy(tool, canvas)
00031 {
00032     Q_ASSERT( canvas->shapeManager()->selection()->count() > 0);
00033     KoSelectionSet selectedShapes = canvas->shapeManager()->selection()->selectedShapes(KoFlake::StrippedSelection);
00034     foreach(KoShape *shape, selectedShapes) {
00035         m_selectedShapes << shape;
00036         m_startPositions << shape->position();
00037         m_startAbsolutePositions << shape->absolutePosition();
00038         m_startSizes << shape->size();
00039         m_startShearXs << shape->shearX();
00040         m_startShearYs << shape->shearY();
00041     }
00042     m_start = clicked;
00043 
00044     KoShape *shp = 0;
00045     if(canvas->shapeManager()->selection()->count()>1)
00046        shp = canvas->shapeManager()->selection();
00047     if(canvas->shapeManager()->selection()->count()==1)
00048         shp = canvas->shapeManager()->selection()->firstSelectedShape();
00049 
00050     m_unwindMatrix = QMatrix();
00051     if (shp)
00052         m_unwindMatrix.rotate( - shp->rotation());
00053     m_windMatrix = QMatrix();
00054     if (shp)
00055         m_windMatrix.rotate(shp->rotation());
00056     if (shp)
00057         m_initialSize = shp->size();
00058     if (shp)
00059         m_initialPosition = shp->transformationMatrix(0).map(QPointF());
00060 
00061     switch(direction) {
00062         case KoFlake::TopMiddleHandle:
00063             m_top = true; m_bottom = false; m_left = false; m_right = false; break;
00064         case KoFlake::TopRightHandle:
00065             m_top = true; m_bottom = false; m_left = false; m_right = true; break;
00066         case KoFlake::RightMiddleHandle:
00067             m_top = false; m_bottom = false; m_left = false; m_right = true; break;
00068         case KoFlake::BottomRightHandle:
00069             m_top = false; m_bottom = true; m_left = false; m_right = true; break;
00070         case KoFlake::BottomMiddleHandle:
00071             m_top = false; m_bottom = true; m_left = false; m_right = false; break;
00072         case KoFlake::BottomLeftHandle:
00073             m_top = false; m_bottom = true; m_left = true; m_right = false; break;
00074         case KoFlake::LeftMiddleHandle:
00075             m_top = false; m_bottom = false; m_left = true; m_right = false; break;
00076         case KoFlake::TopLeftHandle:
00077             m_top = true; m_bottom = false; m_left = true; m_right = false; break;
00078         default:
00079             ;// throw exception ?  TODO
00080     }
00081 }
00082 
00083 void KoShapeResizeStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifiers modifiers) {
00084     QPointF newPos = point;
00085     if(m_canvas->snapToGrid() && (modifiers & Qt::ShiftModifier) == 0)
00086         applyGrid(newPos);
00087     QPointF distance = newPos - m_start;
00088 
00089     bool keepAspect = modifiers & Qt::AltModifier;
00090     foreach(KoShape *shape, m_selectedShapes)
00091         keepAspect = keepAspect || shape->keepAspectRatio();
00092 
00093     double startWidth = m_initialSize.width();
00094     double startHeight = m_initialSize.height();
00095     distance = m_unwindMatrix.map(distance);
00096 
00097     double zoomX=1, zoomY=1;
00098     if(keepAspect) {
00099         double ratio = startWidth / startHeight;
00100         double width = startWidth - distance.x();
00101         double height = startHeight - distance.y();
00102         int toLargestEdge = (m_bottom?1:0) + (m_top?1:0) + // should be false when only one
00103             (m_left?1:0) + (m_right?1:0);                  // of the direction bools is set
00104         bool horizontal = m_left || m_right;
00105 
00106         if(toLargestEdge != 1) { // one of the corners.
00107             if (width < height) // the biggest border is the one in control
00108                 width = height * ratio;
00109             else
00110                 height = width / ratio;
00111         } else {
00112             if (horizontal)
00113                 height = width / ratio;
00114             else
00115                 width = height * ratio;
00116         }
00117         zoomX = startWidth / width;
00118         zoomY = startHeight / height;
00119     }
00120     else {
00121         if(m_left)
00122             zoomX = (startWidth - distance.x()) / startWidth;
00123         else if(m_right)
00124             zoomX = (startWidth + distance.x()) / startWidth;
00125         if(m_top)
00126             zoomY = (startHeight - distance.y()) / startHeight;
00127         else if(m_bottom)
00128             zoomY = (startHeight + distance.y()) / startHeight;
00129     }
00130 
00131     bool scaleFromCenter = modifiers & Qt::ControlModifier;
00132     QPointF move;
00133     QMatrix matrix;
00134 
00135     if(scaleFromCenter)
00136     {
00137         move = QPointF(startWidth / 2.0, startHeight / 2.0);
00138     }
00139     else
00140     {
00141         move = QPointF(m_left?startWidth:0, m_top?startHeight:0);
00142     }
00143     matrix.translate(move.x(), move.y()); // translate to 
00144     matrix.scale(qMax(0.0, zoomX), qMax(0.0, zoomY));
00145     matrix.translate(-move.x(), -move.y()); // and back
00146 
00147     matrix = m_unwindMatrix * matrix * m_windMatrix;
00148     int i=0;
00149     foreach(KoShape *shape, m_selectedShapes) {
00150         QPointF pos(m_startAbsolutePositions[i] - m_initialPosition);
00151         pos = matrix.map(pos);
00152 
00153         // construct the matrix tranformation we apply to the shape
00154         QMatrix m = (QMatrix().rotate(shape->rotation())) * matrix  * (QMatrix().rotate(-shape->rotation()));
00155         QSizeF size(m.m11() * m_startSizes[i].width(), m.m22() * m_startSizes[i].height());
00156         size.setWidth(qMax(4.0, size.width()));
00157         size.setHeight(qMax(4.0, size.height()));
00158 
00159         shape->repaint();
00160         // the position has to be set after the size as we set the center of the shape
00161         shape->resize( size );
00162         shape->shear(m_startShearXs[i] + m.m12() / m.m22(), m_startShearYs[i] + m.m21() / m.m11());
00163         shape->setAbsolutePosition( pos + m_initialPosition );
00164         shape->repaint();
00165         i++;
00166     }
00167 }
00168 
00169 KCommand* KoShapeResizeStrategy::createCommand() {
00170     KMacroCommand *cmd = new KMacroCommand("Resize");
00171     QList<QPointF> newPositions;
00172     QList<QSizeF> newSizes;
00173     foreach(KoShape *shape, m_selectedShapes) {
00174         newPositions << shape->position();
00175         newSizes << shape->size();
00176     }
00177     cmd->addCommand(new KoShapeMoveCommand(m_selectedShapes, m_startPositions, newPositions));
00178     cmd->addCommand(new KoShapeSizeCommand(m_selectedShapes, m_startSizes, newSizes));
00179     return cmd;
00180 }
00181 
00182 void KoShapeResizeStrategy::paint( QPainter &painter, KoViewConverter &converter) {
00183     SelectionDecorator decorator (KoFlake::NoHandle, false, false);
00184     decorator.setSelection(m_canvas->shapeManager()->selection());
00185     decorator.paint(painter, converter);
00186 }

Généré le Wed Nov 22 23:41:00 2006 pour KPlato par  doxygen 1.5.1-p1