Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Alignment snap also for item resize in composer
  • Loading branch information
mhugent committed Jan 18, 2013
1 parent 4495925 commit 4105eac
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 27 deletions.
75 changes: 55 additions & 20 deletions src/core/composer/qgscomposeritem.cpp
Expand Up @@ -514,6 +514,35 @@ void QgsComposerItem::changeItemRectangle( const QPointF& currentPosition,
double mx = 0.0, my = 0.0, rx = 0.0, ry = 0.0;
QPointF snappedPosition = mComposition->snapPointToGrid( currentPosition );

//snap to grid and align to other items
if ( mCurrentMouseMoveAction != QgsComposerItem::MoveItem )
{
double alignX = 0;
double alignY = 0;
snappedPosition = mComposition->alignPos( snappedPosition, dynamic_cast<const QgsComposerItem*>( originalItem ), alignX, alignY );
if ( alignX != -1 )
{
QGraphicsLineItem* item = hAlignSnapItem();
item->setLine( QLineF( alignX, 0, alignX, mComposition->paperHeight() ) );
item->show();
}
else
{
deleteHAlignSnapItem();
}

if ( alignY != -1 )
{
QGraphicsLineItem* item = vAlignSnapItem();
item->setLine( QLineF( 0, alignY, mComposition->paperWidth(), alignY ) );
item->show();
}
else
{
deleteVAlignSnapItem();
}
}

double diffX = 0;
double diffY = 0;

Expand Down Expand Up @@ -575,29 +604,35 @@ void QgsComposerItem::changeItemRectangle( const QPointF& currentPosition,
QPointF upperLeftPoint( originalItem->transform().dx() + moveX, originalItem->transform().dy() + moveY );
QPointF snappedLeftPoint = mComposition->snapPointToGrid( upperLeftPoint );

//align item
double alignX = 0;
double alignY = 0;
snappedLeftPoint = mComposition->alignItem( dynamic_cast<const QgsComposerItem*>( originalItem ), alignX, alignY, moveX, moveY );
if ( alignX != -1 )
{
QGraphicsLineItem* item = hAlignSnapItem();
item->setLine( QLineF( alignX, 0, alignX, mComposition->paperHeight() ) );
item->show();
}
else
{
deleteHAlignSnapItem();
}
if ( alignY != -1 )
if ( snappedLeftPoint != upperLeftPoint ) //don't do align snap if grid snap has been done
{
QGraphicsLineItem* item = vAlignSnapItem();
item->setLine( QLineF( 0, alignY, mComposition->paperWidth(), alignY ) );
item->show();
deleteAlignItems();
}
else
else //align item
{
deleteVAlignSnapItem();
double alignX = 0;
double alignY = 0;
snappedLeftPoint = mComposition->alignItem( dynamic_cast<const QgsComposerItem*>( originalItem ), alignX, alignY, moveX, moveY );
if ( alignX != -1 )
{
QGraphicsLineItem* item = hAlignSnapItem();
item->setLine( QLineF( alignX, 0, alignX, mComposition->paperHeight() ) );
item->show();
}
else
{
deleteHAlignSnapItem();
}
if ( alignY != -1 )
{
QGraphicsLineItem* item = vAlignSnapItem();
item->setLine( QLineF( 0, alignY, mComposition->paperWidth(), alignY ) );
item->show();
}
else
{
deleteVAlignSnapItem();
}
}
double moveRectX = snappedLeftPoint.x() - originalItem->transform().dx();
double moveRectY = snappedLeftPoint.y() - originalItem->transform().dy();
Expand Down
65 changes: 59 additions & 6 deletions src/core/composer/qgscomposition.cpp
Expand Up @@ -1019,6 +1019,45 @@ QPointF QgsComposition::alignItem( const QgsComposerItem* item, double& alignX,
return QPointF( xCoord, yCoord );
}

QPointF QgsComposition::alignPos( const QPointF& pos, const QgsComposerItem* excludeItem, double& alignX, double& alignY )
{
QMap<double, const QgsComposerItem* > xAlignCoordinates;
QMap<double, const QgsComposerItem* > yAlignCoordinates;
collectAlignCoordinates( xAlignCoordinates, yAlignCoordinates, excludeItem );

double nearestX = pos.x();
double nearestY = pos.y();
if ( !nearestItem( xAlignCoordinates, pos.x(), nearestX )
|| !nearestItem( yAlignCoordinates, pos.y(), nearestY ) )
{
alignX = -1;
alignY = -1;
return pos;
}

QPointF result( pos.x(), pos.y() );
if ( abs( nearestX - pos.x() ) < 5 )
{
result.setX( nearestX );
alignX = nearestX;
}
else
{
alignX = -1;
}

if ( abs( nearestY - pos.y() ) < 5 )
{
result.setY( nearestY );
alignY = nearestY;
}
else
{
alignY = -1;
}
return result;
}

int QgsComposition::boundingRectOfSelectedItems( QRectF& bRect )
{
QList<QgsComposerItem*> selectedItems = selectedComposerItems();
Expand Down Expand Up @@ -1707,7 +1746,12 @@ void QgsComposition::collectAlignCoordinates( QMap< double, const QgsComposerIte
void QgsComposition::checkNearestItem( double checkCoord, const QMap< double, const QgsComposerItem* >& alignCoords, double& smallestDiff,
double itemCoordOffset, double& itemCoord, double& alignCoord )
{
double currentCoord = nearestItem( alignCoords, checkCoord );
double currentCoord = 0;
if ( !nearestItem( alignCoords, checkCoord, currentCoord ) )
{
return;
}

double currentDiff = abs( checkCoord - currentCoord );
if ( currentDiff < smallestDiff )
{
Expand All @@ -1717,17 +1761,24 @@ void QgsComposition::checkNearestItem( double checkCoord, const QMap< double, co
}
}

double QgsComposition::nearestItem( const QMap< double, const QgsComposerItem* >& coords, double value )
bool QgsComposition::nearestItem( const QMap< double, const QgsComposerItem* >& coords, double value, double& nearestValue )
{
if ( coords.size() < 1 )
{
return false;
}

QMap< double, const QgsComposerItem* >::const_iterator it = coords.lowerBound( value );
if ( it == coords.constBegin() ) //value smaller than first map value
{
return it.key();
nearestValue = it.key();
return true;
}
else if ( it == coords.constEnd() ) //value larger than last map value
{
--it;
return it.key();
nearestValue = it.key();
return true;
}
else
{
Expand All @@ -1740,11 +1791,13 @@ double QgsComposition::nearestItem( const QMap< double, const QgsComposerItem* >
double upperDiff = upperVal - value;
if ( lowerDiff < upperDiff )
{
return lowerVal;
nearestValue = lowerVal;
return true;
}
else
{
return upperVal;
nearestValue = upperVal;
return true;
}
}
}
Expand Down
11 changes: 10 additions & 1 deletion src/core/composer/qgscomposition.h
Expand Up @@ -245,6 +245,13 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
@return new upper left point after the align*/
QPointF alignItem( const QgsComposerItem* item, double& alignX, double& alignY, double dx = 0, double dy = 0 );

/**Snaps position to align with the boundaries of other items
@param pos position to snap
@param alignX snapped x coordinate or -1 if not snapped
@param alignY snapped y coordinate or -1 if not snapped
@return snapped position or original position if no snap*/
QPointF alignPos( const QPointF& pos, const QgsComposerItem* excludeItem, double& alignX, double& alignY );

/**Allocates new item command and saves initial state in it
@param item target item
@param commandText descriptive command text
Expand Down Expand Up @@ -387,7 +394,9 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
static void checkNearestItem( double checkCoord, const QMap< double, const QgsComposerItem* >& alignCoords, double& smallestDiff,
double itemCoordOffset, double& itemCoord, double& alignCoord );

static double nearestItem( const QMap< double, const QgsComposerItem* >& coords, double value );
/**Find nearest item in coordinate map to a double.
@return true if item found, false if coords is empty*/
static bool nearestItem( const QMap< double, const QgsComposerItem* >& coords, double value, double& nearestValue );

signals:
void paperSizeChanged();
Expand Down

0 comments on commit 4105eac

Please sign in to comment.