Skip to content

Commit

Permalink
Snap to arbitrary snap lines
Browse files Browse the repository at this point in the history
  • Loading branch information
mhugent committed Feb 19, 2013
1 parent cb1f5c3 commit 90461f2
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 10 deletions.
67 changes: 67 additions & 0 deletions src/core/composer/qgscomposition.cpp
Expand Up @@ -1064,6 +1064,57 @@ QPointF QgsComposition::alignPos( const QPointF& pos, const QgsComposerItem* exc
return result;
}

void QgsComposition::addSnapLine( QGraphicsLineItem* line )
{
addItem( line );
mSnapLines.push_back( line );
}

void QgsComposition::removeSnapLine( QGraphicsLineItem* line )
{
removeItem( line );
mSnapLines.removeAll( line );
}

QGraphicsLineItem* QgsComposition::nearestSnapLine( double x, double y, double tolerance )
{
bool xDirection = doubleNear( y, 0.0 );
double minSqrDist = DBL_MAX;
QGraphicsLineItem* item = 0;
double currentXCoord = 0;
double currentYCoord = 0;
double currentSqrDist = 0;
double sqrTolerance = tolerance * tolerance;

QList< QGraphicsLineItem* >::const_iterator it = mSnapLines.constBegin();
for ( ; it != mSnapLines.constEnd(); ++it )
{
currentXCoord = ( *it )->line().x1();
currentYCoord = ( *it )->line().y1();

if ( xDirection && !doubleNear( currentXCoord, 0.0 ) )
{
currentSqrDist = ( x - currentXCoord ) * ( x - currentXCoord );
}
else if ( !xDirection && !doubleNear( currentYCoord, 0.0 ) )
{
currentSqrDist = ( y - currentYCoord ) * ( y - currentYCoord );
}
else
{
continue;
}

if ( currentSqrDist < minSqrDist && currentSqrDist < sqrTolerance )
{
item = *it;
minSqrDist = currentSqrDist;
}
}

return item;
}

int QgsComposition::boundingRectOfSelectedItems( QRectF& bRect )
{
QList<QgsComposerItem*> selectedItems = selectedComposerItems();
Expand Down Expand Up @@ -1747,6 +1798,22 @@ void QgsComposition::collectAlignCoordinates( QMap< double, const QgsComposerIte
alignCoordsY.insert( currentItem->transform().dy() + currentItem->rect().bottom(), currentItem );
}
}

//arbitrary snap lines
QList< QGraphicsLineItem* >::const_iterator sIt = mSnapLines.constBegin();
for ( ; sIt != mSnapLines.constEnd(); ++sIt )
{
double x = ( *sIt )->line().x1();
double y = ( *sIt )->line().y1();
if ( doubleNear( y, 0.0 ) )
{
alignCoordsX.insert( x, 0 );
}
else
{
alignCoordsY.insert( y, 0 );
}
}
}

void QgsComposition::checkNearestItem( double checkCoord, const QMap< double, const QgsComposerItem* >& alignCoords, double& smallestDiff,
Expand Down
10 changes: 10 additions & 0 deletions src/core/composer/qgscomposition.h
Expand Up @@ -259,6 +259,13 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
@return snapped position or original position if no snap*/
QPointF alignPos( const QPointF& pos, const QgsComposerItem* excludeItem, double& alignX, double& alignY );

/**Add a custom snap line (can be horizontal or vertical)*/
void addSnapLine( QGraphicsLineItem* line );
/**Remove custom snap line*/
void removeSnapLine( QGraphicsLineItem* line );
/**Get nearest snap line*/
QGraphicsLineItem* nearestSnapLine( double x, double y, double tolerance );

/**Allocates new item command and saves initial state in it
@param item target item
@param commandText descriptive command text
Expand Down Expand Up @@ -369,6 +376,9 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
bool mAlignmentSnap;
double mAlignmentSnapTolerance;

/**Arbitraty snap lines (horizontal and vertical)*/
QList< QGraphicsLineItem* > mSnapLines;

QUndoStack mUndoStack;

QgsComposerItemCommand* mActiveItemCommand;
Expand Down
35 changes: 25 additions & 10 deletions src/gui/qgscomposerruler.cpp
Expand Up @@ -129,26 +129,41 @@ void QgsComposerRuler::setSceneTransform( const QTransform& transform )

void QgsComposerRuler::mouseMoveEvent( QMouseEvent* event )
{
qWarning( "QgsComposerRuler::mouseMoveEvent" );
//qWarning( "QgsComposerRuler::mouseMoveEvent" );
updateMarker( event->posF() );
setSnapLinePosition( event->posF() );
}

void QgsComposerRuler::mouseReleaseEvent( QMouseEvent* event )
{
Q_UNUSED( event );
delete mLineSnapItem;
mLineSnapItem = 0;
}

void QgsComposerRuler::mousePressEvent( QMouseEvent* event )
{
delete mLineSnapItem;
mLineSnapItem = 0;
mLineSnapItem = createLineSnapItem();
mComposition->addItem( mLineSnapItem );
setSnapLinePosition( event->posF() );
mLineSnapItem->show();
double x = 0;
double y = 0;
if ( mDirection == Horizontal )
{
x = mTransform.inverted().map( event->pos() ).x();
}
else //vertical
{
y = mTransform.inverted().map( event->pos() ).y();
}

QGraphicsLineItem* line = mComposition->nearestSnapLine( x, y, 2.0 );
if ( !line )
{
//create new snap line
mLineSnapItem = createLineSnapItem();
mComposition->addSnapLine( mLineSnapItem );
}
else
{
mLineSnapItem = line;
}
}

void QgsComposerRuler::setSnapLinePosition( const QPointF& pos )
Expand All @@ -161,11 +176,11 @@ void QgsComposerRuler::setSnapLinePosition( const QPointF& pos )
QPointF transformedPt = mTransform.inverted().map( pos );
if ( mDirection == Horizontal )
{
mLineSnapItem->setLine( QLineF( transformedPt.x(), 0, transformedPt.x(), mComposition->height() ) );
mLineSnapItem->setLine( QLineF( transformedPt.x(), 0, transformedPt.x(), mComposition->height() - 1 ) );
}
else //vertical
{
mLineSnapItem->setLine( QLineF( 0, transformedPt.y(), mComposition->width(), transformedPt.y() ) );
mLineSnapItem->setLine( QLineF( 0, transformedPt.y(), mComposition->width() - 1, transformedPt.y() ) );
}
}

Expand Down

0 comments on commit 90461f2

Please sign in to comment.