Skip to content

Commit 9eddf69

Browse files
committed
[FEATURE] Shift-resizing composer items maintains their aspect ratio, ctrl-resizing resizes from item center
1 parent 579226d commit 9eddf69

File tree

2 files changed

+122
-16
lines changed

2 files changed

+122
-16
lines changed

src/core/composer/qgscomposermousehandles.cpp

Lines changed: 115 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -362,15 +362,28 @@ void QgsComposerMouseHandles::hoverMoveEvent( QGraphicsSceneHoverEvent * event )
362362

363363
void QgsComposerMouseHandles::mouseMoveEvent( QGraphicsSceneMouseEvent* event )
364364
{
365+
bool shiftModifier = false;
366+
bool controlModifier = false;
367+
if ( event->modifiers() & Qt::ShiftModifier )
368+
{
369+
//shift key depressed
370+
shiftModifier = true;
371+
}
372+
if ( event->modifiers() & Qt::ControlModifier )
373+
{
374+
//shift key depressed
375+
controlModifier = true;
376+
}
377+
365378
if ( mIsDragging )
366379
{
367380
//currently dragging a selection
368-
dragMouseMove( event->lastScenePos() );
381+
dragMouseMove( event->lastScenePos(), shiftModifier );
369382
}
370383
else if ( mIsResizing )
371384
{
372385
//currently resizing a selection
373-
resizeMouseMove( event->lastScenePos() );
386+
resizeMouseMove( event->lastScenePos(), shiftModifier, controlModifier );
374387
}
375388

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

487500
}
488501

489-
void QgsComposerMouseHandles::dragMouseMove( const QPointF& currentPosition )
502+
void QgsComposerMouseHandles::dragMouseMove( const QPointF& currentPosition, bool lockMovement )
490503
{
491504
if ( !mComposition )
492505
{
@@ -515,7 +528,7 @@ void QgsComposerMouseHandles::dragMouseMove( const QPointF& currentPosition )
515528
setTransform( moveTransform );
516529
}
517530

518-
void QgsComposerMouseHandles::resizeMouseMove( const QPointF& currentPosition )
531+
void QgsComposerMouseHandles::resizeMouseMove( const QPointF& currentPosition, bool lockRatio, bool fromCenter )
519532
{
520533

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

532-
//TODO: shift-resizing should lock aspect ratio
545+
double ratio = 0;
546+
if ( lockRatio && mBeginHandleHeight != 0 )
547+
{
548+
ratio = mBeginHandleWidth / mBeginHandleHeight;
549+
}
533550

534551
//TODO: resizing eg from top handle to below bottom handle
535552
switch ( mCurrentMouseMoveAction )
536553
{
537554
//vertical resize
538555
case QgsComposerMouseHandles::ResizeUp:
539556
diffY = snappedPosition.y() - mBeginHandlePos.y();
540-
mx = 0; my = diffY; rx = 0; ry = -diffY;
557+
if ( ratio )
558+
{
559+
diffX = (( mBeginHandleHeight - diffY ) * ratio ) - mBeginHandleWidth;
560+
mx = -diffX / 2; my = diffY; rx = diffX; ry = -diffY;
561+
}
562+
else
563+
{
564+
mx = 0; my = diffY; rx = 0; ry = -diffY;
565+
}
541566
break;
542567

543568
case QgsComposerMouseHandles::ResizeDown:
544569
diffY = snappedPosition.y() - ( mBeginHandlePos.y() + mBeginHandleHeight );
545-
mx = 0; my = 0; rx = 0; ry = diffY;
570+
if ( ratio )
571+
{
572+
diffX = (( mBeginHandleHeight + diffY ) * ratio ) - mBeginHandleWidth;
573+
mx = -diffX / 2; my = 0; rx = diffX; ry = diffY;
574+
}
575+
else
576+
{
577+
mx = 0; my = 0; rx = 0; ry = diffY;
578+
}
546579
break;
547580

548581
//horizontal resize
549582
case QgsComposerMouseHandles::ResizeLeft:
550583
diffX = snappedPosition.x() - mBeginHandlePos.x();
551-
mx = diffX, my = 0; rx = -diffX; ry = 0;
584+
if ( ratio )
585+
{
586+
diffY = (( mBeginHandleWidth - diffX ) / ratio ) - mBeginHandleHeight;
587+
mx = diffX; my = -diffY / 2; rx = -diffX; ry = diffY;
588+
}
589+
else
590+
{
591+
mx = diffX, my = 0; rx = -diffX; ry = 0;
592+
}
552593
break;
553594

554595
case QgsComposerMouseHandles::ResizeRight:
555596
diffX = snappedPosition.x() - ( mBeginHandlePos.x() + mBeginHandleWidth );
556-
mx = 0; my = 0; rx = diffX, ry = 0;
597+
if ( ratio )
598+
{
599+
diffY = (( mBeginHandleWidth + diffX ) / ratio ) - mBeginHandleHeight;
600+
mx = 0; my = -diffY / 2; rx = diffX; ry = diffY;
601+
}
602+
else
603+
{
604+
mx = 0; my = 0; rx = diffX, ry = 0;
605+
}
557606
break;
558607

559608
//diagonal resize
560609
case QgsComposerMouseHandles::ResizeLeftUp:
561610
diffX = snappedPosition.x() - mBeginHandlePos.x();
562611
diffY = snappedPosition.y() - mBeginHandlePos.y();
612+
if ( ratio )
613+
{
614+
//ratio locked resize
615+
if (( mBeginHandleWidth - diffX ) / ( mBeginHandleHeight - diffY ) > ratio )
616+
{
617+
diffX = mBeginHandleWidth - (( mBeginHandleHeight - diffY ) * ratio );
618+
}
619+
else
620+
{
621+
diffY = mBeginHandleHeight - (( mBeginHandleWidth - diffX ) / ratio );
622+
}
623+
}
563624
mx = diffX, my = diffY; rx = -diffX; ry = -diffY;
564625
break;
565626

566627
case QgsComposerMouseHandles::ResizeRightDown:
567628
diffX = snappedPosition.x() - ( mBeginHandlePos.x() + mBeginHandleWidth );
568629
diffY = snappedPosition.y() - ( mBeginHandlePos.y() + mBeginHandleHeight );
630+
if ( ratio )
631+
{
632+
//ratio locked resize
633+
if (( mBeginHandleWidth + diffX ) / ( mBeginHandleHeight + diffY ) > ratio )
634+
{
635+
diffX = (( mBeginHandleHeight + diffY ) * ratio ) - mBeginHandleWidth;
636+
}
637+
else
638+
{
639+
diffY = (( mBeginHandleWidth + diffX ) / ratio ) - mBeginHandleHeight;
640+
}
641+
}
569642
mx = 0; my = 0; rx = diffX, ry = diffY;
570643
break;
571644

572645
case QgsComposerMouseHandles::ResizeRightUp:
573646
diffX = snappedPosition.x() - ( mBeginHandlePos.x() + mBeginHandleWidth );
574647
diffY = snappedPosition.y() - mBeginHandlePos.y();
648+
if ( ratio )
649+
{
650+
//ratio locked resize
651+
if (( mBeginHandleWidth + diffX ) / ( mBeginHandleHeight - diffY ) > ratio )
652+
{
653+
diffX = (( mBeginHandleHeight - diffY ) * ratio ) - mBeginHandleWidth;
654+
}
655+
else
656+
{
657+
diffY = mBeginHandleHeight - (( mBeginHandleWidth + diffX ) / ratio );
658+
}
659+
}
575660
mx = 0; my = diffY, rx = diffX, ry = -diffY;
576661
break;
577662

578663
case QgsComposerMouseHandles::ResizeLeftDown:
579664
diffX = snappedPosition.x() - mBeginHandlePos.x();
580665
diffY = snappedPosition.y() - ( mBeginHandlePos.y() + mBeginHandleHeight );
666+
if ( ratio )
667+
{
668+
//ratio locked resize
669+
if (( mBeginHandleWidth - diffX ) / ( mBeginHandleHeight + diffY ) > ratio )
670+
{
671+
diffX = mBeginHandleWidth - (( mBeginHandleHeight + diffY ) * ratio );
672+
}
673+
else
674+
{
675+
diffY = (( mBeginHandleWidth - diffX ) / ratio ) - mBeginHandleHeight;
676+
}
677+
}
581678
mx = diffX, my = 0; rx = -diffX; ry = diffY;
582679
break;
583680

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

687+
//resizing from center of objects?
688+
if ( fromCenter )
689+
{
690+
my = -ry;
691+
mx = -rx;
692+
ry = 2 * ry;
693+
rx = 2 * rx;
694+
}
695+
590696
//update selection handle rectangle
591697
QTransform itemTransform;
592698
itemTransform.translate( mx, my );

src/core/composer/qgscomposermousehandles.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class QgsComposerItem;
2525

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

8181
protected:
82-
82+
8383
void mouseMoveEvent( QGraphicsSceneMouseEvent* event );
8484
void mouseReleaseEvent( QGraphicsSceneMouseEvent* event );
8585
void mousePressEvent( QGraphicsSceneMouseEvent* event );
8686
void hoverMoveEvent( QGraphicsSceneHoverEvent * event );
8787

8888
public slots:
89-
89+
9090
/**Sets up listeners to sizeChanged signal for all selected items*/
9191
void selectionChanged();
9292

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

9696
private:
97-
97+
9898
QgsComposition* mComposition; //reference to composition
9999

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

142142
/**Handles dragging of items during mouse move*/
143-
void dragMouseMove( const QPointF& currentPosition );
143+
void dragMouseMove( const QPointF& currentPosition, bool lockMovement );
144144
/**Handles resizing of items during mouse move*/
145-
void resizeMouseMove( const QPointF& currentPosition );
145+
void resizeMouseMove( const QPointF& currentPosition, bool lockAspect, bool fromCenter );
146146

147147
/**Resizes a QRectF relative to the change from boundsBefore to boundsAfter*/
148148
void relativeResizeRect( QRectF& rectToResize, const QRectF& boundsBefore, const QRectF& boundsAfter );
@@ -163,7 +163,7 @@ class CORE_EXPORT QgsComposerMouseHandles: public QObject, public QGraphicsRectI
163163
QPointF alignItem( double& alignX, double& alignY, double unalignedX, double unalignedY );
164164
/**Snaps a point to to the grid or align rulers*/
165165
QPointF alignPos( const QPointF& pos, double& alignX, double& alignY );
166-
166+
167167
//helper functions for item align
168168
void collectAlignCoordinates( QMap< double, const QgsComposerItem* >& alignCoordsX, QMap< double, const QgsComposerItem* >& alignCoordsY );
169169
bool nearestItem( const QMap< double, const QgsComposerItem* >& coords, double value, double& nearestValue ) const;

0 commit comments

Comments
 (0)