Skip to content
Permalink
Browse files

[FEATURE] Shift-resizing composer items maintains their aspect ratio,…

… ctrl-resizing resizes from item center
  • Loading branch information
nyalldawson committed Oct 3, 2013
1 parent 579226d commit 9eddf69379d3d43ea27fd0dc82d13d6207246c7d
Showing with 122 additions and 16 deletions.
  1. +115 −9 src/core/composer/qgscomposermousehandles.cpp
  2. +7 −7 src/core/composer/qgscomposermousehandles.h
@@ -362,15 +362,28 @@ void QgsComposerMouseHandles::hoverMoveEvent( QGraphicsSceneHoverEvent * event )

void QgsComposerMouseHandles::mouseMoveEvent( QGraphicsSceneMouseEvent* event )
{
bool shiftModifier = false;
bool controlModifier = false;
if ( event->modifiers() & Qt::ShiftModifier )
{
//shift key depressed
shiftModifier = true;
}
if ( event->modifiers() & Qt::ControlModifier )
{
//shift key depressed
controlModifier = true;
}

if ( mIsDragging )
{
//currently dragging a selection
dragMouseMove( event->lastScenePos() );
dragMouseMove( event->lastScenePos(), shiftModifier );
}
else if ( mIsResizing )
{
//currently resizing a selection
resizeMouseMove( event->lastScenePos() );
resizeMouseMove( event->lastScenePos(), shiftModifier, controlModifier );
}

mLastMouseEventPos = event->lastScenePos();
@@ -486,7 +499,7 @@ void QgsComposerMouseHandles::mousePressEvent( QGraphicsSceneMouseEvent* event )

}

void QgsComposerMouseHandles::dragMouseMove( const QPointF& currentPosition )
void QgsComposerMouseHandles::dragMouseMove( const QPointF& currentPosition, bool lockMovement )
{
if ( !mComposition )
{
@@ -515,7 +528,7 @@ void QgsComposerMouseHandles::dragMouseMove( const QPointF& currentPosition )
setTransform( moveTransform );
}

void QgsComposerMouseHandles::resizeMouseMove( const QPointF& currentPosition )
void QgsComposerMouseHandles::resizeMouseMove( const QPointF& currentPosition, bool lockRatio, bool fromCenter )
{

if ( !mComposition )
@@ -529,55 +542,139 @@ void QgsComposerMouseHandles::resizeMouseMove( const QPointF& currentPosition )
double diffX = 0;
double diffY = 0;

//TODO: shift-resizing should lock aspect ratio
double ratio = 0;
if ( lockRatio && mBeginHandleHeight != 0 )
{
ratio = mBeginHandleWidth / mBeginHandleHeight;
}

//TODO: resizing eg from top handle to below bottom handle
switch ( mCurrentMouseMoveAction )
{
//vertical resize
case QgsComposerMouseHandles::ResizeUp:
diffY = snappedPosition.y() - mBeginHandlePos.y();
mx = 0; my = diffY; rx = 0; ry = -diffY;
if ( ratio )
{
diffX = (( mBeginHandleHeight - diffY ) * ratio ) - mBeginHandleWidth;
mx = -diffX / 2; my = diffY; rx = diffX; ry = -diffY;
}
else
{
mx = 0; my = diffY; rx = 0; ry = -diffY;
}
break;

case QgsComposerMouseHandles::ResizeDown:
diffY = snappedPosition.y() - ( mBeginHandlePos.y() + mBeginHandleHeight );
mx = 0; my = 0; rx = 0; ry = diffY;
if ( ratio )
{
diffX = (( mBeginHandleHeight + diffY ) * ratio ) - mBeginHandleWidth;
mx = -diffX / 2; my = 0; rx = diffX; ry = diffY;
}
else
{
mx = 0; my = 0; rx = 0; ry = diffY;
}
break;

//horizontal resize
case QgsComposerMouseHandles::ResizeLeft:
diffX = snappedPosition.x() - mBeginHandlePos.x();
mx = diffX, my = 0; rx = -diffX; ry = 0;
if ( ratio )
{
diffY = (( mBeginHandleWidth - diffX ) / ratio ) - mBeginHandleHeight;
mx = diffX; my = -diffY / 2; rx = -diffX; ry = diffY;
}
else
{
mx = diffX, my = 0; rx = -diffX; ry = 0;
}
break;

case QgsComposerMouseHandles::ResizeRight:
diffX = snappedPosition.x() - ( mBeginHandlePos.x() + mBeginHandleWidth );
mx = 0; my = 0; rx = diffX, ry = 0;
if ( ratio )
{
diffY = (( mBeginHandleWidth + diffX ) / ratio ) - mBeginHandleHeight;
mx = 0; my = -diffY / 2; rx = diffX; ry = diffY;
}
else
{
mx = 0; my = 0; rx = diffX, ry = 0;
}
break;

//diagonal resize
case QgsComposerMouseHandles::ResizeLeftUp:
diffX = snappedPosition.x() - mBeginHandlePos.x();
diffY = snappedPosition.y() - mBeginHandlePos.y();
if ( ratio )
{
//ratio locked resize
if (( mBeginHandleWidth - diffX ) / ( mBeginHandleHeight - diffY ) > ratio )
{
diffX = mBeginHandleWidth - (( mBeginHandleHeight - diffY ) * ratio );
}
else
{
diffY = mBeginHandleHeight - (( mBeginHandleWidth - diffX ) / ratio );
}
}
mx = diffX, my = diffY; rx = -diffX; ry = -diffY;
break;

case QgsComposerMouseHandles::ResizeRightDown:
diffX = snappedPosition.x() - ( mBeginHandlePos.x() + mBeginHandleWidth );
diffY = snappedPosition.y() - ( mBeginHandlePos.y() + mBeginHandleHeight );
if ( ratio )
{
//ratio locked resize
if (( mBeginHandleWidth + diffX ) / ( mBeginHandleHeight + diffY ) > ratio )
{
diffX = (( mBeginHandleHeight + diffY ) * ratio ) - mBeginHandleWidth;
}
else
{
diffY = (( mBeginHandleWidth + diffX ) / ratio ) - mBeginHandleHeight;
}
}
mx = 0; my = 0; rx = diffX, ry = diffY;
break;

case QgsComposerMouseHandles::ResizeRightUp:
diffX = snappedPosition.x() - ( mBeginHandlePos.x() + mBeginHandleWidth );
diffY = snappedPosition.y() - mBeginHandlePos.y();
if ( ratio )
{
//ratio locked resize
if (( mBeginHandleWidth + diffX ) / ( mBeginHandleHeight - diffY ) > ratio )
{
diffX = (( mBeginHandleHeight - diffY ) * ratio ) - mBeginHandleWidth;
}
else
{
diffY = mBeginHandleHeight - (( mBeginHandleWidth + diffX ) / ratio );
}
}
mx = 0; my = diffY, rx = diffX, ry = -diffY;
break;

case QgsComposerMouseHandles::ResizeLeftDown:
diffX = snappedPosition.x() - mBeginHandlePos.x();
diffY = snappedPosition.y() - ( mBeginHandlePos.y() + mBeginHandleHeight );
if ( ratio )
{
//ratio locked resize
if (( mBeginHandleWidth - diffX ) / ( mBeginHandleHeight + diffY ) > ratio )
{
diffX = mBeginHandleWidth - (( mBeginHandleHeight + diffY ) * ratio );
}
else
{
diffY = (( mBeginHandleWidth - diffX ) / ratio ) - mBeginHandleHeight;
}
}
mx = diffX, my = 0; rx = -diffX; ry = diffY;
break;

@@ -587,6 +684,15 @@ void QgsComposerMouseHandles::resizeMouseMove( const QPointF& currentPosition )
break;
}

//resizing from center of objects?
if ( fromCenter )
{
my = -ry;
mx = -rx;
ry = 2 * ry;
rx = 2 * rx;
}

//update selection handle rectangle
QTransform itemTransform;
itemTransform.translate( mx, my );
@@ -25,7 +25,7 @@ class QgsComposerItem;

/** \ingroup MapComposer
* Handles drawing of selection outlines and mouse handles. Responsible for mouse
* interactions such as resizing and moving selected items.
* interactions such as resizing and moving selected items.
* */
class CORE_EXPORT QgsComposerMouseHandles: public QObject, public QGraphicsRectItem
{
@@ -79,22 +79,22 @@ class CORE_EXPORT QgsComposerMouseHandles: public QObject, public QGraphicsRectI
QgsComposerMouseHandles::MouseAction mouseActionForScenePos( const QPointF& sceneCoordPos );

protected:

void mouseMoveEvent( QGraphicsSceneMouseEvent* event );
void mouseReleaseEvent( QGraphicsSceneMouseEvent* event );
void mousePressEvent( QGraphicsSceneMouseEvent* event );
void hoverMoveEvent( QGraphicsSceneHoverEvent * event );

public slots:

/**Sets up listeners to sizeChanged signal for all selected items*/
void selectionChanged();

/**Redraws handles when selected item size changes*/
void selectedItemSizeChanged();

private:

QgsComposition* mComposition; //reference to composition

QgsComposerMouseHandles::MouseAction mCurrentMouseMoveAction;
@@ -140,9 +140,9 @@ class CORE_EXPORT QgsComposerMouseHandles: public QObject, public QGraphicsRectI
QgsComposerMouseHandles::MouseAction mouseActionForPosition( const QPointF& itemCoordPos );

/**Handles dragging of items during mouse move*/
void dragMouseMove( const QPointF& currentPosition );
void dragMouseMove( const QPointF& currentPosition, bool lockMovement );
/**Handles resizing of items during mouse move*/
void resizeMouseMove( const QPointF& currentPosition );
void resizeMouseMove( const QPointF& currentPosition, bool lockAspect, bool fromCenter );

/**Resizes a QRectF relative to the change from boundsBefore to boundsAfter*/
void relativeResizeRect( QRectF& rectToResize, const QRectF& boundsBefore, const QRectF& boundsAfter );
@@ -163,7 +163,7 @@ class CORE_EXPORT QgsComposerMouseHandles: public QObject, public QGraphicsRectI
QPointF alignItem( double& alignX, double& alignY, double unalignedX, double unalignedY );
/**Snaps a point to to the grid or align rulers*/
QPointF alignPos( const QPointF& pos, double& alignX, double& alignY );

//helper functions for item align
void collectAlignCoordinates( QMap< double, const QgsComposerItem* >& alignCoordsX, QMap< double, const QgsComposerItem* >& alignCoordsY );
bool nearestItem( const QMap< double, const QgsComposerItem* >& coords, double value, double& nearestValue ) const;

0 comments on commit 9eddf69

Please sign in to comment.
You can’t perform that action at this time.