Commit 74d29eab authored by Jan Hambrecht's avatar Jan Hambrecht

shapes can now support points and segments to the snap guide

to allow snapping to arbitrary internal shape data 
(as discussed with boemann an IRC)


svn path=/trunk/koffice/; revision=773049
parent cf84ff71
......@@ -64,6 +64,7 @@ set(flake_SRCS
KoConnectionShapeConfigWidget.cpp
KoSnapGuide.cpp
KoSnapStrategy.cpp
KoSnapData.cpp
SnapGuideConfigWidget.cpp
commands/KoShapeGroupCommand.cpp
commands/KoShapeAlignCommand.cpp
......
......@@ -286,27 +286,6 @@ void KoPathShape::debugPath()
}
#endif
QPointF KoPathShape::shapeToDocument( const QPointF &point ) const
{
return absoluteTransformation(0).map( point );
}
QRectF KoPathShape::shapeToDocument( const QRectF &rect ) const
{
return absoluteTransformation(0).mapRect( rect );
}
QPointF KoPathShape::documentToShape( const QPointF &point ) const
{
return absoluteTransformation(0).inverted().map( point );
}
QRectF KoPathShape::documentToShape( const QRectF &rect ) const
{
return absoluteTransformation(0).inverted().mapRect( rect );
}
void KoPathShape::paintPoints( QPainter &painter, const KoViewConverter &converter, int handleRadius )
{
applyConversion( painter, converter );
......
......@@ -387,42 +387,6 @@ public:
void debugPath();
#endif
/**
* @brief transform point from shape coordinates to document coordinates
*
* @param point in shape coordinates
*
* @return point in document coordinates
*/
QPointF shapeToDocument( const QPointF &point ) const;
/**
* @brief transform rect from shape coordinates to document coordinates
*
* @param rect in shape coordinates
*
* @return rect in document coordinates
*/
QRectF shapeToDocument( const QRectF &rect ) const;
/**
* @brief transform point from world coordinates to document coordinates
*
* @param point in document coordinates
*
* @return point in shape coordinates
*/
QPointF documentToShape( const QPointF &point ) const;
/**
* @brief transform rect from world coordinates to document coordinates
*
* @param rect in document coordinates
*
* @return rect in shape coordinates
*/
QRectF documentToShape( const QRectF &rect ) const;
/**
* Returns the specific path shape id.
*
......
......@@ -1002,6 +1002,27 @@ void KoShape::applyConversion(QPainter &painter, const KoViewConverter &converte
painter.scale(zoomX, zoomY);
}
QPointF KoShape::shapeToDocument( const QPointF &point ) const
{
return absoluteTransformation(0).map( point );
}
QRectF KoShape::shapeToDocument( const QRectF &rect ) const
{
return absoluteTransformation(0).mapRect( rect );
}
QPointF KoShape::documentToShape( const QPointF &point ) const
{
return absoluteTransformation(0).inverted().map( point );
}
QRectF KoShape::documentToShape( const QRectF &rect ) const
{
return absoluteTransformation(0).inverted().mapRect( rect );
}
void KoShape::addDependee( KoShape * shape )
{
if( ! d->dependees.contains( shape ) )
......@@ -1020,3 +1041,8 @@ void KoShape::notifyShapeChanged( KoShape * shape, ChangeType type )
Q_UNUSED( shape );
Q_UNUSED( type );
}
KoSnapData KoShape::snapData() const
{
return KoSnapData();
}
......@@ -32,6 +32,7 @@
#include <QBrush>
#include <KoXmlReaderForward.h>
#include <KoSnapData.h>
#include "flake_export.h"
......@@ -613,6 +614,34 @@ public:
*/
static void applyConversion(QPainter &painter, const KoViewConverter &converter);
/**
* @brief Transforms point from shape coordinates to document coordinates
* @param point in shape coordinates
* @return point in document coordinates
*/
QPointF shapeToDocument( const QPointF &point ) const;
/**
* @brief Transforms rect from shape coordinates to document coordinates
* @param rect in shape coordinates
* @return rect in document coordinates
*/
QRectF shapeToDocument( const QRectF &rect ) const;
/**
* @brief Transforms point from document coordinates to shape coordinates
* @param point in document coordinates
* @return point in shape coordinates
*/
QPointF documentToShape( const QPointF &point ) const;
/**
* @brief Transform rect from document coordinates to shape coordinates
* @param rect in document coordinates
* @return rect in shape coordinates
*/
QRectF documentToShape( const QRectF &rect ) const;
/**
* Return all the connections made to or from this shape.
*/
......@@ -676,6 +705,9 @@ public:
*/
KoShape * clone( KoShapeControllerBase * base ) const;
/// Returns additional snap data the shape wants to have snapping to
virtual KoSnapData snapData() const;
protected:
/* ** loading saving helper methods */
......
/* This file is part of the KDE project
* Copyright (C) 2008 Jan Hambrecht <jaham@gmx.net>
*
* 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 "KoSnapData.h"
KoSnapData::KoSnapData()
{
}
KoSnapData::~KoSnapData()
{
}
QList<QPointF> KoSnapData::snapPoints() const
{
return m_points;
}
void KoSnapData::setSnapPoints( const QList<QPointF> &snapPoints )
{
m_points = snapPoints;
}
QList<KoPathSegment> KoSnapData::snapSegments() const
{
return m_segments;
}
void KoSnapData::setSnapSegments( const QList<KoPathSegment> &snapSegments )
{
m_segments = snapSegments;
}
/* This file is part of the KDE project
* Copyright (C) 2008 Jan Hambrecht <jaham@gmx.net>
*
* 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.
*/
#ifndef KOSNAPDATA_H
#define KOSNAPDATA_H
#include <KoPathSegment.h>
/**
* This class is used to provide additional data to the snap guide.
*
* Some shapes might have internal data it wants snapping support for,
* i.e. the axis of a chart shape, the row of a table shape, etc.
* As the data is internal and special to that shape, the snap guide
* does not know about it and can therefore not provide any snapping
* to it.
* So the shape can put that data in form of points or segments into
* that class which the snap guide can retrieve and use accordingly.
*/
class KoSnapData
{
public:
KoSnapData();
~KoSnapData();
/// Returns list of points to snap to
QList<QPointF> snapPoints() const;
/// Sets list of points to snap to
void setSnapPoints( const QList<QPointF> &snapPoints );
/// Returns list of segments to snap to
QList<KoPathSegment> snapSegments() const;
/// Sets list of segments to snap to
void setSnapSegments( const QList<KoPathSegment> &snapSegments );
private:
QList<QPointF> m_points;
QList<KoPathSegment> m_segments;
};
#endif //KOSNAPDATA_H
......@@ -103,7 +103,7 @@ QPointF KoSnapGuide::snap( const QPointF &mousePosition, Qt::KeyboardModifiers m
{
if( m_usedStrategies & strategy->type() || strategy->type() == KoSnapStrategy::Grid )
{
if( ! strategy->snapToPoints( mousePosition, &proxy, maxSnapDistance ) )
if( ! strategy->snap( mousePosition, &proxy, maxSnapDistance ) )
continue;
QPointF snapCandidate = strategy->snappedPosition();
......@@ -135,7 +135,7 @@ QRectF KoSnapGuide::boundingRect()
void KoSnapGuide::paint( QPainter &painter, const KoViewConverter &converter )
{
Q_UNUSED(converter);
if( ! m_currentStrategy || ! m_active )
return;
......@@ -205,7 +205,10 @@ QList<QPointF> KoSnapProxy::pointsFromShape( KoShape * shape )
KoPathShape * path = dynamic_cast<KoPathShape*>( shape );
if( ! path )
return pathPoints;
{
// return the special snap points of the shape
return shape->snapData().snapPoints();
}
QMatrix m = path->absoluteTransformation(0);
......@@ -231,6 +234,44 @@ QList<QPointF> KoSnapProxy::pointsFromShape( KoShape * shape )
return pathPoints;
}
QList<KoPathSegment> KoSnapProxy::segmentsInRect( const QRectF &rect )
{
QList<KoShape*> shapes = shapesInRect( rect, true );
QList<KoPathSegment> segments;
foreach( KoShape * shape, shapes )
{
QList<KoPathSegment> shapeSegments;
QRectF rectOnShape = shape->documentToShape( rect );
KoPathShape * path = dynamic_cast<KoPathShape*>( shape );
if( path )
{
shapeSegments = path->segmentsAt( rectOnShape );
}
else
{
foreach( KoPathSegment s, shape->snapData().snapSegments() )
{
QRectF controlRect = s.controlPointRect();
if( ! rect.intersects( controlRect ) && ! controlRect.contains( rect ) )
continue;
QRectF bound = s.boundingRect();
if( ! rect.intersects( bound ) && ! bound.contains( rect ) )
continue;
shapeSegments.append( s );
}
}
QMatrix m = shape->absoluteTransformation(0);
// transform segments to document coordinates
foreach( KoPathSegment s, shapeSegments )
{
segments.append( s.mapped( m ) );
}
}
return segments;
}
QList<KoShape*> KoSnapProxy::shapes( bool omitEditedShape )
{
QList<KoShape*> shapes = m_snapGuide->canvas()->shapeManager()->shapes();
......
......@@ -20,6 +20,7 @@
#ifndef KOSNAPGUIDE_H
#define KOSNAPGUIDE_H
#include <KoPathSegment.h>
#include <QtCore/QPointF>
#include <QtCore/QList>
#include <QtCore/QRectF>
......@@ -112,6 +113,9 @@ public:
/// returns list of points from given shape
QList<QPointF> pointsFromShape( KoShape * shape );
/// returns list of points in given rectangle in document coordinates
QList<KoPathSegment> segmentsInRect( const QRectF &rect );
/// returns list of all shapes
QList<KoShape*> shapes( bool omitEditedShape = false );
......
......@@ -68,7 +68,7 @@ OrthogonalSnapStrategy::OrthogonalSnapStrategy()
{
}
bool OrthogonalSnapStrategy::snapToPoints( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance )
bool OrthogonalSnapStrategy::snap( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance )
{
QPointF horzSnap, vertSnap;
double minVertDist = HUGE_VAL;
......@@ -127,7 +127,7 @@ NodeSnapStrategy::NodeSnapStrategy()
{
}
bool NodeSnapStrategy::snapToPoints( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance )
bool NodeSnapStrategy::snap( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance )
{
double maxDistance = maxSnapDistance*maxSnapDistance;
double minDistance = HUGE_VAL;
......@@ -168,7 +168,7 @@ ExtensionSnapStrategy::ExtensionSnapStrategy()
{
}
bool ExtensionSnapStrategy::snapToPoints( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance )
bool ExtensionSnapStrategy::snap( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance )
{
double maxDistance = maxSnapDistance*maxSnapDistance;
double minDistance = HUGE_VAL;
......@@ -304,31 +304,16 @@ IntersectionSnapStrategy::IntersectionSnapStrategy()
{
}
bool IntersectionSnapStrategy::snapToPoints( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance )
bool IntersectionSnapStrategy::snap( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance )
{
double maxDistance = maxSnapDistance*maxSnapDistance;
double minDistance = HUGE_VAL;
QRectF rect( -maxSnapDistance, -maxSnapDistance, maxSnapDistance, maxSnapDistance );
rect.moveCenter( mousePosition );
QList<KoShape*> shapes = proxy->shapesInRect( rect, true );
QList<KoPathSegment> segments;
foreach( KoShape * shape, shapes )
{
KoPathShape * path = dynamic_cast<KoPathShape*>( shape );
if( ! path )
continue;
QMatrix m = shape->absoluteTransformation(0);
// transform segments to document coordinates
foreach( KoPathSegment s, path->segmentsAt( path->documentToShape( rect ) ) )
{
segments.append( s.mapped( m ) );
}
}
QPointF snappedPoint = mousePosition;
QList<KoPathSegment> segments = proxy->segmentsInRect( rect );
//kDebug() << "found" << segments.count() << "segments in roi";
int segmentCount = segments.count();
......@@ -375,7 +360,7 @@ GridSnapStrategy::GridSnapStrategy()
{
}
bool GridSnapStrategy::snapToPoints( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance )
bool GridSnapStrategy::snap( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance )
{
if( ! proxy->canvas()->snapToGrid() )
return false;
......
......@@ -42,7 +42,7 @@ public:
KoSnapStrategy( SnapType type );
virtual ~KoSnapStrategy() {};
virtual bool snapToPoints( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance ) = 0;
virtual bool snap( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance ) = 0;
/// returns the current snap strategy decoration
QPainterPath decoration() const;
......@@ -73,7 +73,7 @@ class OrthogonalSnapStrategy : public KoSnapStrategy
{
public:
OrthogonalSnapStrategy();
virtual bool snapToPoints( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance );
virtual bool snap( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance );
};
/// snaps to path points
......@@ -81,7 +81,7 @@ class NodeSnapStrategy : public KoSnapStrategy
{
public:
NodeSnapStrategy();
virtual bool snapToPoints( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance );
virtual bool snap( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance );
};
/// snaps extension lines of path shapes
......@@ -89,7 +89,7 @@ class ExtensionSnapStrategy : public KoSnapStrategy
{
public:
ExtensionSnapStrategy();
virtual bool snapToPoints( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance );
virtual bool snap( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance );
private:
double project( const QPointF &lineStart , const QPointF &lineEnd, const QPointF &point );
QPointF extensionDirection( KoPathPoint * point, const QMatrix &matrix );
......@@ -101,7 +101,7 @@ class IntersectionSnapStrategy : public KoSnapStrategy
{
public:
IntersectionSnapStrategy();
virtual bool snapToPoints( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance );
virtual bool snap( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance );
};
/// snaps to the canvas grid
......@@ -109,7 +109,7 @@ class GridSnapStrategy : public KoSnapStrategy
{
public:
GridSnapStrategy();
virtual bool snapToPoints( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance );
virtual bool snap( const QPointF &mousePosition, KoSnapProxy * proxy, double maxSnapDistance );
};
#endif // KOSNAPSTRATEGY_H
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