Skip to content

Commit 207bcad

Browse files
committedOct 6, 2017
Start porting mouse handles to layout
1 parent b9ecb4f commit 207bcad

File tree

7 files changed

+1300
-2
lines changed

7 files changed

+1300
-2
lines changed
 

‎python/core/layout/qgslayout.sip‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator, QgsLayoutUndoOb
2626
ZItem,
2727
ZGrid,
2828
ZGuide,
29+
ZMouseHandles,
2930
ZMapTool,
3031
ZSnapIndicator,
3132
};

‎src/core/layout/qgslayout.h‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
4747
ZItem = 1, //!< Minimum z value for items
4848
ZGrid = 9998, //!< Z-value for page grids
4949
ZGuide = 9999, //!< Z-value for page guides
50-
ZMapTool = 10000, //!< Z-value for temporary map tool items
51-
ZSnapIndicator = 10001, //!< Z-value for snapping indicator
50+
ZMouseHandles = 10000, //!< Z-value for mouse handles
51+
ZMapTool = 10001, //!< Z-value for temporary map tool items
52+
ZSnapIndicator = 10002, //!< Z-value for snapping indicator
5253
};
5354

5455
/**

‎src/gui/CMakeLists.txt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ SET(QGIS_GUI_SRCS
161161

162162
layout/qgslayoutitemguiregistry.cpp
163163
layout/qgslayoutitemwidget.cpp
164+
layout/qgslayoutmousehandles.cpp
164165
layout/qgslayoutnewitempropertiesdialog.cpp
165166
layout/qgslayoutruler.cpp
166167
layout/qgslayoutunitscombobox.cpp
@@ -657,6 +658,7 @@ SET(QGIS_GUI_MOC_HDRS
657658
layout/qgslayoutdesignerinterface.h
658659
layout/qgslayoutitemguiregistry.h
659660
layout/qgslayoutitemwidget.h
661+
layout/qgslayoutmousehandles.h
660662
layout/qgslayoutnewitempropertiesdialog.h
661663
layout/qgslayoutruler.h
662664
layout/qgslayoutunitscombobox.h

‎src/gui/layout/qgslayoutmousehandles.cpp‎

Lines changed: 1081 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/***************************************************************************
2+
qgslayoutmousehandles.h
3+
-----------------------
4+
begin : September 2017
5+
copyright : (C) 2017 by Nyall Dawson
6+
email : nyall.dawson@gmail.com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
#ifndef QGSLAYOUTMOUSEHANDLES_H
18+
#define QGSLAYOUTMOUSEHANDLES_H
19+
20+
#define SIP_NO_FILE
21+
22+
#include <QGraphicsRectItem>
23+
#include <QObject>
24+
#include <QPointer>
25+
26+
#include "qgis_gui.h"
27+
28+
class QgsLayout;
29+
class QGraphicsView;
30+
class QgsLayoutView;
31+
32+
///@cond PRIVATE
33+
34+
/**
35+
* \ingroup gui
36+
* Handles drawing of selection outlines and mouse handles in a QgsLayoutView
37+
*
38+
* Also is responsible for mouse interactions such as resizing and moving selected items.
39+
*
40+
* \note not available in Python bindings
41+
* \since QGIS 3.0
42+
*
43+
*/
44+
class GUI_EXPORT QgsLayoutMouseHandles: public QObject, public QGraphicsRectItem
45+
{
46+
Q_OBJECT
47+
public:
48+
49+
//! Describes the action (move or resize in different directon) to be done during mouse move
50+
enum MouseAction
51+
{
52+
MoveItem,
53+
ResizeUp,
54+
ResizeDown,
55+
ResizeLeft,
56+
ResizeRight,
57+
ResizeLeftUp,
58+
ResizeRightUp,
59+
ResizeLeftDown,
60+
ResizeRightDown,
61+
SelectItem,
62+
NoAction
63+
};
64+
65+
enum ItemPositionMode
66+
{
67+
UpperLeft,
68+
UpperMiddle,
69+
UpperRight,
70+
MiddleLeft,
71+
Middle,
72+
MiddleRight,
73+
LowerLeft,
74+
LowerMiddle,
75+
LowerRight
76+
};
77+
78+
enum SnapGuideMode
79+
{
80+
Item,
81+
Point
82+
};
83+
84+
QgsLayoutMouseHandles( QgsLayout *layout, QgsLayoutView *view );
85+
86+
/**
87+
* Sets the \a layout for the handles.
88+
* \see layout()
89+
*/
90+
void setLayout( QgsLayout *layout ) { mLayout = layout; }
91+
92+
/**
93+
* Returns the layout for the handles.
94+
* \see setLayout()
95+
*/
96+
QgsLayout *layout() { return mLayout; }
97+
98+
void paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget ) override;
99+
100+
//! Finds out which mouse move action to choose depending on the scene cursor position
101+
QgsLayoutMouseHandles::MouseAction mouseActionForScenePos( QPointF sceneCoordPos );
102+
103+
//! Returns true is user is currently dragging the handles
104+
bool isDragging() { return mIsDragging; }
105+
106+
//! Returns true is user is currently resizing with the handles
107+
bool isResizing() { return mIsResizing; }
108+
109+
protected:
110+
111+
void mouseMoveEvent( QGraphicsSceneMouseEvent *event ) override;
112+
void mouseReleaseEvent( QGraphicsSceneMouseEvent *event ) override;
113+
void mousePressEvent( QGraphicsSceneMouseEvent *event ) override;
114+
void mouseDoubleClickEvent( QGraphicsSceneMouseEvent *event ) override;
115+
void hoverMoveEvent( QGraphicsSceneHoverEvent *event ) override;
116+
void hoverLeaveEvent( QGraphicsSceneHoverEvent *event ) override;
117+
118+
public slots:
119+
120+
//! Sets up listeners to sizeChanged signal for all selected items
121+
void selectionChanged();
122+
123+
//! Redraws handles when selected item size changes
124+
void selectedItemSizeChanged();
125+
126+
//! Redraws handles when selected item rotation changes
127+
void selectedItemRotationChanged();
128+
129+
private:
130+
131+
QgsLayout *mLayout = nullptr;
132+
QPointer< QgsLayoutView > mView;
133+
134+
MouseAction mCurrentMouseMoveAction = NoAction;
135+
//! Start point of the last mouse move action (in scene coordinates)
136+
QPointF mMouseMoveStartPos;
137+
//! Position of the last mouse move event (in scene coordinates)
138+
QPointF mLastMouseEventPos;
139+
//! Position of the mouse at beginning of move/resize (in scene coordinates)
140+
QPointF mBeginMouseEventPos;
141+
//! Position of composer handles at beginning of move/resize (in scene coordinates)
142+
QPointF mBeginHandlePos;
143+
//! Width and height of composer handles at beginning of resize
144+
double mBeginHandleWidth = 0;
145+
double mBeginHandleHeight = 0;
146+
147+
QRectF mResizeRect;
148+
double mResizeMoveX = 0;
149+
double mResizeMoveY = 0;
150+
151+
//! True if user is currently dragging items
152+
bool mIsDragging = false;
153+
//! True is user is currently resizing items
154+
bool mIsResizing = false;
155+
156+
//! Align snap lines
157+
QGraphicsLineItem *mHAlignSnapItem = nullptr;
158+
QGraphicsLineItem *mVAlignSnapItem = nullptr;
159+
160+
QSizeF mCursorOffset;
161+
162+
//! Returns the mouse handle bounds of current selection
163+
QRectF selectionBounds() const;
164+
165+
//! Returns true if all selected items have same rotation, and if so, updates passed rotation variable
166+
bool selectionRotation( double &rotation ) const;
167+
168+
//! Redraws or hides the handles based on the current selection
169+
void updateHandles();
170+
//! Draws the handles
171+
void drawHandles( QPainter *painter, double rectHandlerSize );
172+
//! Draw outlines for selected items
173+
void drawSelectedItemBounds( QPainter *painter );
174+
175+
/** Returns the current (zoom level dependent) tolerance to decide if mouse position is close enough to the
176+
item border for resizing*/
177+
double rectHandlerBorderTolerance();
178+
179+
//! Finds out the appropriate cursor for the current mouse position in the widget (e.g. move in the middle, resize at border)
180+
Qt::CursorShape cursorForPosition( QPointF itemCoordPos );
181+
182+
//! Finds out which mouse move action to choose depending on the cursor position inside the widget
183+
MouseAction mouseActionForPosition( QPointF itemCoordPos );
184+
185+
//! Handles dragging of items during mouse move
186+
void dragMouseMove( QPointF currentPosition, bool lockMovement, bool preventSnap );
187+
188+
//! Calculates the distance of the mouse cursor from thed edge of the mouse handles
189+
QSizeF calcCursorEdgeOffset( QPointF cursorPos );
190+
191+
//! Handles resizing of items during mouse move
192+
void resizeMouseMove( QPointF currentPosition, bool lockAspect, bool fromCenter );
193+
194+
//sets the mouse cursor for the QGraphicsView attached to the composition (workaround qt bug #3732)
195+
void setViewportCursor( Qt::CursorShape cursor );
196+
197+
//resets the composer window status bar to the default message
198+
void resetStatusBar();
199+
};
200+
201+
///@endcond PRIVATE
202+
203+
#endif // QGSLAYOUTMOUSEHANDLES_H

‎src/gui/layout/qgslayoutview.cpp‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "qgslayoutviewtooltemporarykeypan.h"
2323
#include "qgslayoutviewtooltemporarykeyzoom.h"
2424
#include "qgslayoutviewtooltemporarymousepan.h"
25+
#include "qgslayoutmousehandles.h"
2526
#include "qgslayoutruler.h"
2627
#include "qgssettings.h"
2728
#include "qgsrectangle.h"
@@ -88,6 +89,12 @@ void QgsLayoutView::setCurrentLayout( QgsLayout *layout )
8889
connect( &layout->guides(), &QAbstractItemModel::modelReset, mVerticalRuler, [ = ] { mVerticalRuler->update(); } );
8990
}
9091

92+
//add mouse selection handles to layout, and initially hide
93+
mMouseHandles = new QgsLayoutMouseHandles( layout, this );
94+
mMouseHandles->hide();
95+
mMouseHandles->setZValue( QgsLayout::ZMouseHandles );
96+
layout->addItem( mMouseHandles );
97+
9198
//emit layoutSet, so that designer dialogs can update for the new layout
9299
emit layoutSet( layout );
93100
}

‎src/gui/layout/qgslayoutview.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class QgsLayoutViewToolTemporaryMousePan;
3535
class QgsLayoutRuler;
3636
class QgsLayoutViewMenuProvider;
3737
class QgsLayoutViewSnapMarker;
38+
class QgsLayoutMouseHandles;
3839

3940
/**
4041
* \ingroup gui
@@ -300,6 +301,8 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
300301

301302
std::unique_ptr< QgsLayoutViewSnapMarker > mSnapMarker;
302303

304+
QgsLayoutMouseHandles *mMouseHandles = nullptr; //owned by scene
305+
303306
int mCurrentPage = 0;
304307

305308
friend class TestQgsLayoutView;

0 commit comments

Comments
 (0)
Please sign in to comment.