00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "KoShapeShearStrategy.h"
00022 #include "KoInteractionTool.h"
00023 #include "KoCanvasBase.h"
00024 #include "KoPointerEvent.h"
00025 #include "KoShapeManager.h"
00026 #include "KoCommand.h"
00027
00028 #include <QPointF>
00029
00030 #include <math.h>
00031 #include <kdebug.h>
00032
00033 KoShapeShearStrategy::KoShapeShearStrategy( KoTool *tool, KoCanvasBase *canvas, const QPointF &clicked, KoFlake::SelectionHandle direction )
00034 : KoInteractionStrategy(tool, canvas)
00035 , m_initialBoundingRect()
00036 , m_start(clicked)
00037 {
00038 KoSelectionSet selectedShapes = canvas->shapeManager()->selection()->selectedShapes(KoFlake::StrippedSelection);
00039 foreach(KoShape *shape, selectedShapes) {
00040 if(shape->isLocked())
00041 continue;
00042 m_selectedShapes << shape;
00043 m_startPositions << shape->position();
00044 m_startMatrices << shape->transformationMatrix(0);
00045 m_startRotationMatrices << QMatrix().rotate(shape->rotation());
00046 m_startShearXs << shape->shearX();
00047 m_startShearYs << shape->shearY();
00048 m_initialBoundingRect = m_initialBoundingRect.unite( shape->boundingRect() );
00049 }
00050 m_initialSelectionAngle = canvas->shapeManager()->selection()->rotation();
00051
00052
00053 switch(direction) {
00054 case KoFlake::TopMiddleHandle:
00055 m_top = true; m_bottom = false; m_left = false; m_right = false; break;
00056 case KoFlake::TopRightHandle:
00057 m_top = true; m_bottom = false; m_left = false; m_right = true; break;
00058 case KoFlake::RightMiddleHandle:
00059 m_top = false; m_bottom = false; m_left = false; m_right = true; break;
00060 case KoFlake::BottomRightHandle:
00061 m_top = false; m_bottom = true; m_left = false; m_right = true; break;
00062 case KoFlake::BottomMiddleHandle:
00063 m_top = false; m_bottom = true; m_left = false; m_right = false; break;
00064 case KoFlake::BottomLeftHandle:
00065 m_top = false; m_bottom = true; m_left = true; m_right = false; break;
00066 case KoFlake::LeftMiddleHandle:
00067 m_top = false; m_bottom = false; m_left = true; m_right = false; break;
00068 case KoFlake::TopLeftHandle:
00069 m_top = true; m_bottom = false; m_left = true; m_right = false; break;
00070 default:
00071 ;
00072 }
00073 m_initialSize = canvas->shapeManager()->selection()->size();
00074 m_solidPoint = QPointF( m_initialSize.width() / 2, m_initialSize.height() / 2);
00075
00076 if(m_top)
00077 m_solidPoint += QPointF(0, m_initialSize.height() / 2);
00078 else if(m_bottom)
00079 m_solidPoint -= QPointF(0, m_initialSize.height() / 2);
00080 if(m_left)
00081 m_solidPoint += QPointF(m_initialSize.width() / 2, 0);
00082 else if(m_right)
00083 m_solidPoint -= QPointF(m_initialSize.width() / 2, 0);
00084
00085 kDebug() << " PREsol.x=" << m_solidPoint.x() << " sol.y=" << m_solidPoint.y() <<endl;
00086 QMatrix matrix = canvas->shapeManager()->selection()->transformationMatrix(0);
00087 m_solidPoint = matrix.map(m_solidPoint);
00088 }
00089
00090 void KoShapeShearStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifiers modifiers)
00091 {
00092 Q_UNUSED(modifiers);
00093 QPointF shearVector = point - m_solidPoint;
00094
00095 QMatrix matrix;
00096 matrix.rotate(-m_initialSelectionAngle);
00097 shearVector = matrix.map(shearVector);
00098
00099 double shearX=0, shearY=0;
00100
00101 if(m_top || m_left)
00102 shearVector = - shearVector;
00103 if(m_top || m_bottom)
00104 shearX = shearVector.x() / m_initialSize.height();
00105 if(m_left || m_right)
00106 shearY = shearVector.y() / m_initialSize.width();
00107
00108 QMatrix applyMatrix;
00109 applyMatrix.translate(m_solidPoint.x(), m_solidPoint.y());
00110 applyMatrix.rotate(m_initialSelectionAngle);
00111 applyMatrix.shear(shearX, shearY);
00112 applyMatrix.rotate(-m_initialSelectionAngle);
00113 applyMatrix.translate(-m_solidPoint.x(), -m_solidPoint.y());
00114
00115 kDebug() << "Begin retransform" <<endl;
00116 int counter=0;
00117 foreach(KoShape *shape, m_selectedShapes) {
00118 shape->repaint();
00119 QMatrix m = m_startMatrices[counter] * applyMatrix;
00120 QMatrix orm = m_startRotationMatrices[counter];
00121 shape->shear((m.m21() - orm.m21()) / orm.m11(), (m.m12() - orm.m12()) / orm.m22());
00122 QPointF p = applyMatrix.map(m_startPositions[counter]);
00123 kDebug() << " px=" << p.x() << " py=" << p.y() <<endl;
00124 shape->setPosition(p);
00125 shape->repaint();
00126 counter++;
00127 }
00128 m_canvas->shapeManager()->selection()->shear(shearX, shearY);
00129
00130 }
00131
00132 void KoShapeShearStrategy::paint( QPainter &painter, KoViewConverter &converter) {
00133 SelectionDecorator decorator(KoFlake::NoHandle, true, false);
00134 decorator.setSelection(m_canvas->shapeManager()->selection());
00135 decorator.paint(painter, converter);
00136 }
00137
00138 KCommand* KoShapeShearStrategy::createCommand() {
00139 KMacroCommand *cmd = new KMacroCommand("Shear");
00140 QList<QPointF> newPositions;
00141 QList<double> newShearX;
00142 QList<double> newShearY;
00143 foreach(KoShape *shape, m_selectedShapes) {
00144 newPositions << shape->position();
00145 newShearX << shape->shearX();
00146 newShearY << shape->shearY();
00147 }
00148 cmd->addCommand(new KoShapeMoveCommand(m_selectedShapes, m_startPositions, newPositions));
00149 cmd->addCommand(new KoShapeShearCommand(m_selectedShapes, m_startShearXs, m_startShearYs, newShearX, newShearY));
00150 return cmd;
00151 }