Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit 2b05ab34 authored by Jan Hambrecht's avatar Jan Hambrecht

implemented moving, rotating and resizing of shapes

with the space navigator device when the default tool
is activated


svn path=/trunk/koffice/; revision=798838
parent 8ab6a425
......@@ -80,3 +80,7 @@ QPointF KoInteractionStrategy::snapToGrid( const QPointF &point, Qt::KeyboardMod
return p;
}
void KoInteractionStrategy::handleCustomEvent( KoPointerEvent * event )
{
}
......@@ -64,6 +64,14 @@ public:
* @param modifiers OR-ed set of keys pressed.
*/
virtual void handleMouseMove(const QPointF &mouseLocation, Qt::KeyboardModifiers modifiers) = 0;
/**
* Extending classes should implement this method to update the selectedShapes
* based on the new pointer event. The default implementations does nothing.
* @param event the new pointer event
*/
virtual void handleCustomEvent( KoPointerEvent * event );
/**
* For interactions that are undo-able this method should be implemented to return such
* a command. Implementations should return 0 otherwise.
......
......@@ -80,7 +80,8 @@ DefaultTool::DefaultTool( KoCanvasBase *canvas )
m_hotPosition( KoFlake::TopLeftCorner ),
m_mouseWasInsideHandles( false ),
m_moveCommand(0),
m_selectionHandler(new SelectionHandler(this))
m_selectionHandler(new SelectionHandler(this)),
m_customEventStrategy(0)
{
setupActions();
......@@ -552,6 +553,63 @@ void DefaultTool::keyPressEvent(QKeyEvent *event) {
}
}
void DefaultTool::customMoveEvent( KoPointerEvent * event )
{
if( ! koSelection()->count() )
{
event->ignore();
return;
}
int move = qMax( qAbs(event->x()), qAbs(event->y() ) );
int zoom = qAbs(event->z());
int rotate = qAbs(event->rotationZ());
const int threshold = 2;
if( move < threshold && zoom < threshold && rotate < threshold )
{
if( m_customEventStrategy )
{
m_customEventStrategy->finishInteraction( event->modifiers() );
QUndoCommand *command = m_customEventStrategy->createCommand();
if(command)
m_canvas->addCommand(command);
delete m_customEventStrategy;
m_customEventStrategy = 0;
repaintDecorations();
}
event->accept();
return;
}
// check if the z-movement is dominant
if( zoom > move && zoom > rotate )
{
// zoom
if( ! m_customEventStrategy )
m_customEventStrategy = new ShapeResizeStrategy( this, m_canvas, event->point, KoFlake::TopLeftHandle );
}
// check if x-/y-movement is dominant
else if( move > zoom && move > rotate )
{
// move
if( ! m_customEventStrategy )
m_customEventStrategy = new ShapeMoveStrategy( this, m_canvas, event->point );
}
// rotation is dominant
else if( rotate > zoom && rotate > move )
{
// rotate
if( ! m_customEventStrategy )
m_customEventStrategy = new ShapeRotateStrategy( this, m_canvas, event->point, event->buttons() );
}
if( m_customEventStrategy )
m_customEventStrategy->handleCustomEvent( event );
event->accept();
}
void DefaultTool::repaintDecorations() {
Q_ASSERT(koSelection());
if ( koSelection()->count() > 0 )
......
......@@ -112,6 +112,8 @@ public: // Events
virtual void keyPressEvent(QKeyEvent *event);
virtual void customMoveEvent( KoPointerEvent * event );
protected:
QWidget* createOptionWidget();
......@@ -152,6 +154,7 @@ private:
double m_angle;
KoToolSelection *m_selectionHandler;
friend class SelectionHandler;
KoInteractionStrategy * m_customEventStrategy;
};
#endif
......@@ -29,6 +29,7 @@
#include <KoCanvasResourceProvider.h>
#include <commands/KoShapeMoveCommand.h>
#include <KoSnapGuide.h>
#include <KoPointerEvent.h>
ShapeMoveStrategy::ShapeMoveStrategy( KoTool *tool, KoCanvasBase *canvas, const QPointF &clicked)
: KoInteractionStrategy(tool, canvas)
......@@ -72,16 +73,39 @@ void ShapeMoveStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifi
diff = snappedPosition - m_initialOffset - m_start;
}
m_diff = diff;
moveBy( diff );
}
void ShapeMoveStrategy::handleCustomEvent( KoPointerEvent * event )
{
QPointF diff = m_canvas->viewConverter()->viewToDocument( event->pos() );
if( event->modifiers() & (Qt::AltModifier | Qt::ControlModifier)) {
// keep x or y position unchanged
if(qAbs(diff.x()) < qAbs(diff.y()))
diff.setX(0);
else
diff.setY(0);
}
m_diff += 0.1 * diff ;
moveBy( diff );
}
void ShapeMoveStrategy::moveBy( const QPointF &diff )
{
Q_ASSERT(m_newPositions.count());
m_diff = diff;
int i=0;
foreach(KoShape *shape, m_selectedShapes) {
diff = m_previousPositions.at(i) + m_diff - shape->position();
QPointF delta = m_previousPositions.at(i) + m_diff - shape->position();
if(shape->parent())
shape->parent()->model()->proposeMove(shape, diff);
m_canvas->clipToDocument(shape, diff);
QPointF newPos (shape->position() + diff);
shape->parent()->model()->proposeMove(shape, delta);
m_canvas->clipToDocument(shape, delta);
QPointF newPos (shape->position() + delta);
m_newPositions[i] = newPos;
shape->update();
shape->setPosition(newPos);
......
......@@ -48,8 +48,9 @@ public:
QUndoCommand* createCommand();
void finishInteraction( Qt::KeyboardModifiers modifiers ) { Q_UNUSED( modifiers ); }
virtual void paint( QPainter &painter, const KoViewConverter &converter);
virtual void handleCustomEvent( KoPointerEvent * event );
private:
void moveBy( const QPointF &diff );
QList<QPointF> m_previousPositions;
QList<QPointF> m_newPositions;
QPointF m_start, m_diff, m_initialSelectionPosition, m_initialOffset;
......
......@@ -33,7 +33,7 @@
ShapeResizeStrategy::ShapeResizeStrategy( KoTool *tool, KoCanvasBase *canvas,
const QPointF &clicked, KoFlake::SelectionHandle direction )
: KoInteractionStrategy(tool, canvas)
: KoInteractionStrategy(tool, canvas), m_lastScale(1.0,1.0)
{
Q_ASSERT( canvas->shapeManager()->selection()->count() > 0);
QList<KoShape*> selectedShapes = canvas->shapeManager()->selection()->selectedShapes(KoFlake::StrippedSelection);
......@@ -92,7 +92,7 @@ ShapeResizeStrategy::ShapeResizeStrategy( KoTool *tool, KoCanvasBase *canvas,
}
}
void ShapeResizeStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifiers modifiers)
void ShapeResizeStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifiers modifiers)
{
QPointF newPos = m_canvas->snapGuide()->snap( point, modifiers );
......@@ -124,31 +124,44 @@ void ShapeResizeStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModi
bool scaleFromCenter = modifiers & Qt::ControlModifier;
QPointF move;
QMatrix matrix;
if(scaleFromCenter)
move = QPointF(startWidth / 2.0, startHeight / 2.0);
else
move = QPointF(m_left?startWidth:0, m_top?startHeight:0);
matrix.translate(move.x(), move.y()); // translate to
resizeBy( move, zoomX, zoomY );
}
void ShapeResizeStrategy::handleCustomEvent( KoPointerEvent * event )
{
QPointF center = 0.5 * QPointF( m_initialSize.width(), m_initialSize.height() );
qreal zoom = pow(1.01, -0.1 * event->z() );
m_lastScale *= zoom;
resizeBy( center, m_lastScale.x(), m_lastScale.y() );
}
void ShapeResizeStrategy::resizeBy( const QPointF &center, qreal zoomX, qreal zoomY )
{
QMatrix matrix;
matrix.translate(center.x(), center.y()); // translate to
matrix.scale(zoomX, zoomY);
matrix.translate(-move.x(), -move.y()); // and back
matrix.translate(-center.x(), -center.y()); // and back
// that is the transformation we want to apply to the shapes
matrix = m_unwindMatrix * matrix * m_windMatrix;
// the resizing transformation without the mirroring part
QMatrix resizeMatrix;
resizeMatrix.translate(move.x(), move.y()); // translate to
resizeMatrix.translate(center.x(), center.y()); // translate to
resizeMatrix.scale( qAbs(zoomX), qAbs(zoomY) );
resizeMatrix.translate(-move.x(), -move.y()); // and back
resizeMatrix.translate(-center.x(), -center.y()); // and back
// the mirroring part of the resizing transformation
QMatrix mirrorMatrix;
mirrorMatrix.translate(move.x(), move.y()); // translate to
mirrorMatrix.translate(center.x(), center.y()); // translate to
mirrorMatrix.scale( zoomX < 0 ? -1 : 1, zoomY < 0 ? -1 : 1 );
mirrorMatrix.translate(-move.x(), -move.y()); // and back
mirrorMatrix.translate(-center.x(), -center.y()); // and back
int i = 0;
foreach(KoShape *shape, m_selectedShapes)
......
......@@ -45,8 +45,10 @@ public:
QUndoCommand* createCommand();
void finishInteraction( Qt::KeyboardModifiers modifiers ) { Q_UNUSED(modifiers); }
virtual void paint( QPainter &painter, const KoViewConverter &converter);
virtual void handleCustomEvent( KoPointerEvent * event );
private:
void resizeBy( const QPointF &center, qreal zoomX, qreal zoomY );
QPointF m_start;
QList<QPointF> m_startPositions;
QList<QSizeF> m_startSizes;
......@@ -57,6 +59,7 @@ private:
QMatrix m_scaleMatrix;
QList<QMatrix> m_oldTransforms;
QList<QMatrix> m_transformations;
QPointF m_lastScale;
};
#endif
......
......@@ -49,10 +49,10 @@ ShapeRotateStrategy::ShapeRotateStrategy( KoTool *tool, KoCanvasBase *canvas, co
m_oldTransforms << shape->transformation();
}
if( buttons & Qt::LeftButton )
m_rotationCenter = m_initialBoundingRect.center();
else
if( buttons & Qt::RightButton )
m_rotationCenter = canvas->shapeManager()->selection()->absolutePosition( SelectionDecorator::hotPosition() );
else
m_rotationCenter = m_initialBoundingRect.center();
}
void ShapeRotateStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifiers modifiers) {
......@@ -84,6 +84,39 @@ void ShapeRotateStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModi
m_canvas->shapeManager()->selection()->applyAbsoluteTransformation( applyMatrix );
}
void ShapeRotateStrategy::handleCustomEvent( KoPointerEvent * event )
{
QMatrix matrix;
matrix.translate(m_rotationCenter.x(), m_rotationCenter.y());
matrix.rotate( 0.1 * event->rotationZ() );
matrix.translate(-m_rotationCenter.x(), -m_rotationCenter.y());
m_rotationMatrix *= matrix;
foreach( KoShape * shape, m_selectedShapes ) {
shape->update();
shape->applyAbsoluteTransformation( matrix );
shape->update();
}
m_canvas->shapeManager()->selection()->applyAbsoluteTransformation( matrix );
}
void ShapeRotateStrategy::rotateBy( qreal angle )
{
QMatrix matrix;
matrix.translate(m_rotationCenter.x(), m_rotationCenter.y());
matrix.rotate(angle);
matrix.translate(-m_rotationCenter.x(), -m_rotationCenter.y());
QMatrix applyMatrix = matrix * m_rotationMatrix.inverted();
m_rotationMatrix = matrix;
foreach( KoShape * shape, m_selectedShapes ) {
shape->update();
shape->applyAbsoluteTransformation( applyMatrix );
shape->update();
}
m_canvas->shapeManager()->selection()->applyAbsoluteTransformation( applyMatrix );
}
void ShapeRotateStrategy::paint( QPainter &painter, const KoViewConverter &converter) {
SelectionDecorator decorator(KoFlake::NoHandle, true, false);
decorator.setSelection(m_canvas->shapeManager()->selection());
......
......@@ -48,8 +48,10 @@ public:
QUndoCommand* createCommand();
void finishInteraction( Qt::KeyboardModifiers modifiers ) { Q_UNUSED( modifiers ); }
virtual void paint( QPainter &painter, const KoViewConverter &converter);
virtual void handleCustomEvent( KoPointerEvent * event );
private:
void rotateBy( qreal angle );
QRectF m_initialBoundingRect;
QPointF m_start;
QMatrix m_rotationMatrix;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment