mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Prevent snapping to selected items when resizing
This commit is contained in:
parent
d8ffab1523
commit
051ed1e156
@ -83,7 +83,8 @@ class QgsLayoutSnapper: QgsLayoutSerializableObject
|
|||||||
%End
|
%End
|
||||||
|
|
||||||
QPointF snapPoint( QPointF point, double scaleFactor, bool &snapped /Out/, QGraphicsLineItem *horizontalSnapLine = 0,
|
QPointF snapPoint( QPointF point, double scaleFactor, bool &snapped /Out/, QGraphicsLineItem *horizontalSnapLine = 0,
|
||||||
QGraphicsLineItem *verticalSnapLine = 0 ) const;
|
QGraphicsLineItem *verticalSnapLine = 0,
|
||||||
|
const QList< QgsLayoutItem * > *ignoreItems = 0 ) const;
|
||||||
%Docstring
|
%Docstring
|
||||||
Snaps a layout coordinate ``point``. If ``point`` was snapped, ``snapped`` will be set to true.
|
Snaps a layout coordinate ``point``. If ``point`` was snapped, ``snapped`` will be set to true.
|
||||||
|
|
||||||
@ -95,6 +96,8 @@ class QgsLayoutSnapper: QgsLayoutSerializableObject
|
|||||||
|
|
||||||
If the ``horizontalSnapLine`` and ``verticalSnapLine`` arguments are specified, then the snapper
|
If the ``horizontalSnapLine`` and ``verticalSnapLine`` arguments are specified, then the snapper
|
||||||
will automatically display and position these lines to indicate snapping positions to item bounds.
|
will automatically display and position these lines to indicate snapping positions to item bounds.
|
||||||
|
|
||||||
|
A list of items to ignore during the snapping can be specified via the ``ignoreItems`` list.
|
||||||
:rtype: QPointF
|
:rtype: QPointF
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
@ -49,7 +49,8 @@ void QgsLayoutSnapper::setSnapToItems( bool enabled )
|
|||||||
mSnapToItems = enabled;
|
mSnapToItems = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF QgsLayoutSnapper::snapPoint( QPointF point, double scaleFactor, bool &snapped, QGraphicsLineItem *horizontalSnapLine, QGraphicsLineItem *verticalSnapLine ) const
|
QPointF QgsLayoutSnapper::snapPoint( QPointF point, double scaleFactor, bool &snapped, QGraphicsLineItem *horizontalSnapLine, QGraphicsLineItem *verticalSnapLine,
|
||||||
|
const QList< QgsLayoutItem * > *ignoreItems ) const
|
||||||
{
|
{
|
||||||
snapped = false;
|
snapped = false;
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ QPointF QgsLayoutSnapper::snapPoint( QPointF point, double scaleFactor, bool &sn
|
|||||||
bool snappedYToItems = false;
|
bool snappedYToItems = false;
|
||||||
if ( !snappedXToGuides )
|
if ( !snappedXToGuides )
|
||||||
{
|
{
|
||||||
newX = snapPointToItems( point.x(), Qt::Horizontal, scaleFactor, QList< QgsLayoutItem * >(), snappedXToItems, verticalSnapLine );
|
newX = snapPointToItems( point.x(), Qt::Horizontal, scaleFactor, ignoreItems ? *ignoreItems : QList< QgsLayoutItem * >(), snappedXToItems, verticalSnapLine );
|
||||||
if ( snappedXToItems )
|
if ( snappedXToItems )
|
||||||
{
|
{
|
||||||
snapped = true;
|
snapped = true;
|
||||||
@ -86,7 +87,7 @@ QPointF QgsLayoutSnapper::snapPoint( QPointF point, double scaleFactor, bool &sn
|
|||||||
}
|
}
|
||||||
if ( !snappedYToGuides )
|
if ( !snappedYToGuides )
|
||||||
{
|
{
|
||||||
newY = snapPointToItems( point.y(), Qt::Vertical, scaleFactor, QList< QgsLayoutItem * >(), snappedYToItems, horizontalSnapLine );
|
newY = snapPointToItems( point.y(), Qt::Vertical, scaleFactor, ignoreItems ? *ignoreItems : QList< QgsLayoutItem * >(), snappedYToItems, horizontalSnapLine );
|
||||||
if ( snappedYToItems )
|
if ( snappedYToItems )
|
||||||
{
|
{
|
||||||
snapped = true;
|
snapped = true;
|
||||||
|
@ -105,9 +105,12 @@ class CORE_EXPORT QgsLayoutSnapper: public QgsLayoutSerializableObject
|
|||||||
*
|
*
|
||||||
* If the \a horizontalSnapLine and \a verticalSnapLine arguments are specified, then the snapper
|
* If the \a horizontalSnapLine and \a verticalSnapLine arguments are specified, then the snapper
|
||||||
* will automatically display and position these lines to indicate snapping positions to item bounds.
|
* will automatically display and position these lines to indicate snapping positions to item bounds.
|
||||||
|
*
|
||||||
|
* A list of items to ignore during the snapping can be specified via the \a ignoreItems list.
|
||||||
*/
|
*/
|
||||||
QPointF snapPoint( QPointF point, double scaleFactor, bool &snapped SIP_OUT, QGraphicsLineItem *horizontalSnapLine = nullptr,
|
QPointF snapPoint( QPointF point, double scaleFactor, bool &snapped SIP_OUT, QGraphicsLineItem *horizontalSnapLine = nullptr,
|
||||||
QGraphicsLineItem *verticalSnapLine = nullptr ) const;
|
QGraphicsLineItem *verticalSnapLine = nullptr,
|
||||||
|
const QList< QgsLayoutItem * > *ignoreItems = nullptr ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Snaps a layout coordinate \a point to the grid. If \a point
|
* Snaps a layout coordinate \a point to the grid. If \a point
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "qgslayoututils.h"
|
#include "qgslayoututils.h"
|
||||||
#include "qgslayoutview.h"
|
#include "qgslayoutview.h"
|
||||||
#include "qgslayoutviewtoolselect.h"
|
#include "qgslayoutviewtoolselect.h"
|
||||||
|
#include "qgslayoutsnapper.h"
|
||||||
#include <QGraphicsView>
|
#include <QGraphicsView>
|
||||||
#include <QGraphicsSceneHoverEvent>
|
#include <QGraphicsSceneHoverEvent>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
@ -41,6 +42,13 @@ QgsLayoutMouseHandles::QgsLayoutMouseHandles( QgsLayout *layout, QgsLayoutView *
|
|||||||
|
|
||||||
//accept hover events, required for changing cursor to resize cursors
|
//accept hover events, required for changing cursor to resize cursors
|
||||||
setAcceptHoverEvents( true );
|
setAcceptHoverEvents( true );
|
||||||
|
|
||||||
|
mHorizontalSnapLine.reset( mView->createSnapLine() );
|
||||||
|
mHorizontalSnapLine->hide();
|
||||||
|
layout->addItem( mHorizontalSnapLine.get() );
|
||||||
|
mVerticalSnapLine.reset( mView->createSnapLine() );
|
||||||
|
mVerticalSnapLine->hide();
|
||||||
|
layout->addItem( mVerticalSnapLine.get() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsLayoutMouseHandles::paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget )
|
void QgsLayoutMouseHandles::paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget )
|
||||||
@ -697,6 +705,58 @@ void QgsLayoutMouseHandles::resetStatusBar()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPointF QgsLayoutMouseHandles::snapPoint( QPointF originalPoint, QgsLayoutMouseHandles::SnapGuideMode mode )
|
||||||
|
{
|
||||||
|
//align item
|
||||||
|
double alignX = 0;
|
||||||
|
double alignY = 0;
|
||||||
|
|
||||||
|
bool snapped = false;
|
||||||
|
|
||||||
|
const QList< QgsLayoutItem * > selectedItems = mLayout->selectedLayoutItems();
|
||||||
|
|
||||||
|
//depending on the mode, we either snap just the single point, or all the bounds of the selection
|
||||||
|
QPointF snappedPoint;
|
||||||
|
switch ( mode )
|
||||||
|
{
|
||||||
|
case Item:
|
||||||
|
//snappedPoint = alignItem( alignX, alignY, point.x(), point.y() );
|
||||||
|
break;
|
||||||
|
case Point:
|
||||||
|
snappedPoint = mLayout->snapper().snapPoint( originalPoint, mView->transform().m11(), snapped, mHorizontalSnapLine.get(), mVerticalSnapLine.get(), &selectedItems );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
if ( !qgsDoubleNear( alignX, -1.0 ) )
|
||||||
|
{
|
||||||
|
QGraphicsLineItem *item = hAlignSnapItem();
|
||||||
|
int numPages = mComposition->numPages();
|
||||||
|
double yLineCoord = 300; //default in case there is no single page
|
||||||
|
if ( numPages > 0 )
|
||||||
|
{
|
||||||
|
yLineCoord = mComposition->paperHeight() * numPages + mComposition->spaceBetweenPages() * ( numPages - 1 );
|
||||||
|
}
|
||||||
|
item->setLine( QLineF( alignX, 0, alignX, yLineCoord ) );
|
||||||
|
item->show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
deleteHAlignSnapItem();
|
||||||
|
}
|
||||||
|
if ( !qgsDoubleNear( alignY, -1.0 ) )
|
||||||
|
{
|
||||||
|
QGraphicsLineItem *item = vAlignSnapItem();
|
||||||
|
item->setLine( QLineF( 0, alignY, mComposition->paperWidth(), alignY ) );
|
||||||
|
item->show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
deleteVAlignSnapItem();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return snappedPoint;
|
||||||
|
}
|
||||||
|
|
||||||
void QgsLayoutMouseHandles::mousePressEvent( QGraphicsSceneMouseEvent *event )
|
void QgsLayoutMouseHandles::mousePressEvent( QGraphicsSceneMouseEvent *event )
|
||||||
{
|
{
|
||||||
//save current cursor position
|
//save current cursor position
|
||||||
@ -797,9 +857,6 @@ void QgsLayoutMouseHandles::dragMouseMove( QPointF currentPosition, bool lockMov
|
|||||||
|
|
||||||
QPointF snappedLeftPoint;
|
QPointF snappedLeftPoint;
|
||||||
|
|
||||||
//TODO
|
|
||||||
snappedLeftPoint = upperLeftPoint;
|
|
||||||
#if 0
|
|
||||||
//no snapping for rotated items for now
|
//no snapping for rotated items for now
|
||||||
if ( !preventSnap && qgsDoubleNear( rotation(), 0.0 ) )
|
if ( !preventSnap && qgsDoubleNear( rotation(), 0.0 ) )
|
||||||
{
|
{
|
||||||
@ -810,9 +867,11 @@ void QgsLayoutMouseHandles::dragMouseMove( QPointF currentPosition, bool lockMov
|
|||||||
{
|
{
|
||||||
//no snapping
|
//no snapping
|
||||||
snappedLeftPoint = upperLeftPoint;
|
snappedLeftPoint = upperLeftPoint;
|
||||||
|
#if 0
|
||||||
deleteAlignItems();
|
deleteAlignItems();
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//calculate total shift for item from beginning of drag operation to current position
|
//calculate total shift for item from beginning of drag operation to current position
|
||||||
double moveRectX = snappedLeftPoint.x() - mBeginHandlePos.x();
|
double moveRectX = snappedLeftPoint.x() - mBeginHandlePos.x();
|
||||||
double moveRectY = snappedLeftPoint.y() - mBeginHandlePos.y();
|
double moveRectY = snappedLeftPoint.y() - mBeginHandlePos.y();
|
||||||
@ -859,11 +918,8 @@ void QgsLayoutMouseHandles::resizeMouseMove( QPointF currentPosition, bool lockR
|
|||||||
//subtract cursor edge offset from begin mouse event and current cursor position, so that snapping occurs to edge of mouse handles
|
//subtract cursor edge offset from begin mouse event and current cursor position, so that snapping occurs to edge of mouse handles
|
||||||
//rather then cursor position
|
//rather then cursor position
|
||||||
beginMousePos = mapFromScene( QPointF( mBeginMouseEventPos.x() - mCursorOffset.width(), mBeginMouseEventPos.y() - mCursorOffset.height() ) );
|
beginMousePos = mapFromScene( QPointF( mBeginMouseEventPos.x() - mCursorOffset.width(), mBeginMouseEventPos.y() - mCursorOffset.height() ) );
|
||||||
#if 0
|
|
||||||
QPointF snappedPosition = snapPoint( QPointF( currentPosition.x() - mCursorOffset.width(), currentPosition.y() - mCursorOffset.height() ), QgsLayoutMouseHandles::Point );
|
QPointF snappedPosition = snapPoint( QPointF( currentPosition.x() - mCursorOffset.width(), currentPosition.y() - mCursorOffset.height() ), QgsLayoutMouseHandles::Point );
|
||||||
finalPosition = mapFromScene( snappedPosition );
|
finalPosition = mapFromScene( snappedPosition );
|
||||||
#endif
|
|
||||||
finalPosition = mapFromScene( currentPosition );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <QGraphicsRectItem>
|
#include <QGraphicsRectItem>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "qgis_gui.h"
|
#include "qgis_gui.h"
|
||||||
|
|
||||||
@ -157,8 +158,8 @@ class GUI_EXPORT QgsLayoutMouseHandles: public QObject, public QGraphicsRectItem
|
|||||||
bool mIsResizing = false;
|
bool mIsResizing = false;
|
||||||
|
|
||||||
//! Align snap lines
|
//! Align snap lines
|
||||||
QGraphicsLineItem *mHAlignSnapItem = nullptr;
|
std::unique_ptr< QGraphicsLineItem > mHorizontalSnapLine;
|
||||||
QGraphicsLineItem *mVAlignSnapItem = nullptr;
|
std::unique_ptr< QGraphicsLineItem > mVerticalSnapLine;
|
||||||
|
|
||||||
QSizeF mCursorOffset;
|
QSizeF mCursorOffset;
|
||||||
|
|
||||||
@ -199,6 +200,10 @@ class GUI_EXPORT QgsLayoutMouseHandles: public QObject, public QGraphicsRectItem
|
|||||||
|
|
||||||
//resets the composer window status bar to the default message
|
//resets the composer window status bar to the default message
|
||||||
void resetStatusBar();
|
void resetStatusBar();
|
||||||
|
|
||||||
|
//! Snaps an item or point (depending on mode) originating at originalPoint to the grid or align rulers
|
||||||
|
QPointF snapPoint( QPointF originalPoint, SnapGuideMode mode );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
///@endcond PRIVATE
|
///@endcond PRIVATE
|
||||||
|
@ -306,6 +306,7 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
|
|||||||
int mCurrentPage = 0;
|
int mCurrentPage = 0;
|
||||||
|
|
||||||
friend class TestQgsLayoutView;
|
friend class TestQgsLayoutView;
|
||||||
|
friend class QgsLayoutMouseHandles;
|
||||||
|
|
||||||
QGraphicsLineItem *createSnapLine() const;
|
QGraphicsLineItem *createSnapLine() const;
|
||||||
};
|
};
|
||||||
|
@ -314,6 +314,11 @@ class TestQgsLayoutSnapper(unittest.TestCase):
|
|||||||
self.assertTrue(snapped)
|
self.assertTrue(snapped)
|
||||||
self.assertEqual(point, QPointF(0, 1.1))
|
self.assertEqual(point, QPointF(0, 1.1))
|
||||||
|
|
||||||
|
# ... unless item is ignored!
|
||||||
|
point, snapped = s.snapPoint(QPointF(1, 1), 1, None, None, [item1])
|
||||||
|
self.assertTrue(snapped)
|
||||||
|
self.assertEqual(point, QPointF(0, 0))
|
||||||
|
|
||||||
def testReadWriteXml(self):
|
def testReadWriteXml(self):
|
||||||
p = QgsProject()
|
p = QgsProject()
|
||||||
l = QgsLayout(p)
|
l = QgsLayout(p)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user