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 211ff4df authored by Jan Hambrecht's avatar Jan Hambrecht

implement snapping for shape movement


svn path=/trunk/koffice/; revision=773417
parent 97c83292
......@@ -161,11 +161,22 @@ QList<KoPathPoint*> KoSnapGuide::ignoredPathPoints() const
return m_ignoredPoints;
}
void KoSnapGuide::setIgnoredShapes( const QList<KoShape*> &ignoredShapes )
{
m_ignoredShapes = ignoredShapes;
}
QList<KoShape*> KoSnapGuide::ignoredShapes() const
{
return m_ignoredShapes;
}
void KoSnapGuide::reset()
{
m_currentStrategy = 0;
m_editedShape = 0;
m_ignoredPoints.clear();
m_ignoredShapes.clear();
}
/////////////////////////////////////////////////////////
......@@ -196,7 +207,12 @@ QList<QPointF> KoSnapProxy::pointsInRect( const QRectF &rect )
QList<KoShape*> KoSnapProxy::shapesInRect( const QRectF &rect, bool omitEditedShape )
{
QList<KoShape*> shapes = m_snapGuide->canvas()->shapeManager()->shapesAt( rect );
foreach( KoShape * shape, m_snapGuide->ignoredShapes() )
{
int index = shapes.indexOf( shape );
if( index >= 0 )
shapes.removeAt( index );
}
if( ! omitEditedShape && m_snapGuide->editedShape() )
{
QRectF bound = m_snapGuide->editedShape()->boundingRect();
......@@ -244,6 +260,7 @@ QList<QPointF> KoSnapProxy::pointsFromShape( KoShape * shape )
QList<KoPathSegment> KoSnapProxy::segmentsInRect( const QRectF &rect )
{
QList<KoShape*> shapes = shapesInRect( rect, true );
QList<KoPathPoint*> ignoredPoints = m_snapGuide->ignoredPathPoints();
QList<KoPathSegment> segments;
foreach( KoShape * shape, shapes )
......@@ -273,6 +290,8 @@ QList<KoPathSegment> KoSnapProxy::segmentsInRect( const QRectF &rect )
// transform segments to document coordinates
foreach( KoPathSegment s, shapeSegments )
{
if( ignoredPoints.contains( s.first() ) || ignoredPoints.contains( s.second() ) )
continue;
segments.append( s.mapped( m ) );
}
}
......@@ -282,6 +301,12 @@ QList<KoPathSegment> KoSnapProxy::segmentsInRect( const QRectF &rect )
QList<KoShape*> KoSnapProxy::shapes( bool omitEditedShape )
{
QList<KoShape*> shapes = m_snapGuide->canvas()->shapeManager()->shapes();
foreach( KoShape * shape, m_snapGuide->ignoredShapes() )
{
int index = shapes.indexOf( shape );
if( index >= 0 )
shapes.removeAt( index );
}
if( ! omitEditedShape && m_snapGuide->editedShape() )
shapes.append( m_snapGuide->editedShape() );
return shapes;
......
......@@ -20,6 +20,8 @@
#ifndef KOSNAPGUIDE_H
#define KOSNAPGUIDE_H
#include "flake_export.h"
#include <KoPathSegment.h>
#include <QtCore/QPointF>
#include <QtCore/QList>
......@@ -35,7 +37,7 @@ class KoCanvasBase;
class QPainter;
class KoCanvasBase;
class KoSnapGuide
class FLAKE_EXPORT KoSnapGuide
{
public:
......@@ -86,6 +88,12 @@ public:
/// Returns list of ignored points
QList<KoPathPoint*> ignoredPathPoints() const;
/// Sets list of ignored shapes
void setIgnoredShapes( const QList<KoShape*> &ignoredShapes );
/// Returns list of ignored shapes
QList<KoShape*> ignoredShapes() const;
/// Resets the snap guide
void reset();
......@@ -100,6 +108,7 @@ private:
bool m_active;
int m_snapDistance;
QList<KoPathPoint*> m_ignoredPoints;
QList<KoShape*> m_ignoredShapes;
};
class KoSnapProxy
......
......@@ -44,6 +44,7 @@
#include <KoShapeRubberSelectStrategy.h>
#include <commands/KoShapeMoveCommand.h>
#include <commands/KoShapeDeleteCommand.h>
#include <KoSnapGuide.h>
#include <QAction>
#include <QKeyEvent>
......@@ -388,6 +389,10 @@ void DefaultTool::paint( QPainter &painter, const KoViewConverter &converter) {
decorator.setHotPosition( m_hotPosition );
decorator.paint(painter, converter);
}
painter.save();
KoShape::applyConversion( painter, converter );
m_canvas->snapGuide()->paint( painter, converter );
painter.restore();
}
void DefaultTool::mousePressEvent( KoPointerEvent *event ) {
......
......@@ -28,10 +28,10 @@
#include <KoShapeContainerModel.h>
#include <KoCanvasResourceProvider.h>
#include <commands/KoShapeMoveCommand.h>
#include <KoSnapGuide.h>
ShapeMoveStrategy::ShapeMoveStrategy( KoTool *tool, KoCanvasBase *canvas, const QPointF &clicked)
: KoInteractionStrategy(tool, canvas)
, m_initialTopLeft(99999, 99999)
, m_start(clicked)
{
QList<KoShape*> selectedShapes = canvas->shapeManager()->selection()->selectedShapes(KoFlake::TopLevelSelection);
......@@ -44,18 +44,18 @@ ShapeMoveStrategy::ShapeMoveStrategy( KoTool *tool, KoCanvasBase *canvas, const
m_newPositions << shape->position();
boundingRect = boundingRect.unite( shape->boundingRect() );
}
m_initialTopLeft = boundingRect.topLeft();
m_initialSelectionPosition = canvas->shapeManager()->selection()->position();
KoSelection * selection = m_canvas->shapeManager()->selection();
m_initialOffset = selection->absolutePosition( SelectionDecorator::hotPosition() ) - m_start;
m_initialSelectionPosition = selection->position();
m_canvas->snapGuide()->setIgnoredShapes( selection->selectedShapes( KoFlake::FullSelection ) );
}
void ShapeMoveStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifiers modifiers) {
if(m_selectedShapes.isEmpty()) return;
void ShapeMoveStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifiers modifiers)
{
if(m_selectedShapes.isEmpty())
return;
QPointF diff = point - m_start;
if(m_canvas->snapToGrid() && (modifiers & Qt::ShiftModifier) == 0) {
QPointF newPos = m_initialTopLeft + diff;
applyGrid(newPos);
diff = newPos - m_initialTopLeft;
}
if(modifiers & (Qt::AltModifier | Qt::ControlModifier)) {
// keep x or y position unchanged
if(qAbs(diff.x()) < qAbs(diff.y()))
......@@ -63,6 +63,14 @@ void ShapeMoveStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifi
else
diff.setY(0);
}
else
{
QPointF positionToSnap = point + m_initialOffset;
m_canvas->updateCanvas( m_canvas->snapGuide()->boundingRect() );
QPointF snappedPosition = m_canvas->snapGuide()->snap( positionToSnap, modifiers );
m_canvas->updateCanvas( m_canvas->snapGuide()->boundingRect() );
diff = snappedPosition - m_initialOffset - m_start;
}
Q_ASSERT(m_newPositions.count());
......@@ -84,6 +92,7 @@ void ShapeMoveStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifi
}
QUndoCommand* ShapeMoveStrategy::createCommand() {
m_canvas->snapGuide()->reset();
if(m_diff.x() == 0 && m_diff.y() == 0)
return 0;
return new KoShapeMoveCommand(m_selectedShapes, m_previousPositions, m_newPositions);
......
......@@ -52,7 +52,7 @@ public:
private:
QList<QPointF> m_previousPositions;
QList<QPointF> m_newPositions;
QPointF m_initialTopLeft, m_start, m_diff, m_initialSelectionPosition;
QPointF m_start, m_diff, m_initialSelectionPosition, m_initialOffset;
};
#endif
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