Start porting mouse handles to layout

This commit is contained in:
Nyall Dawson 2017-09-29 16:25:03 +10:00
parent b9ecb4f941
commit 207bcad626
7 changed files with 1300 additions and 2 deletions

View File

@ -26,6 +26,7 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator, QgsLayoutUndoOb
ZItem,
ZGrid,
ZGuide,
ZMouseHandles,
ZMapTool,
ZSnapIndicator,
};

View File

@ -47,8 +47,9 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
ZItem = 1, //!< Minimum z value for items
ZGrid = 9998, //!< Z-value for page grids
ZGuide = 9999, //!< Z-value for page guides
ZMapTool = 10000, //!< Z-value for temporary map tool items
ZSnapIndicator = 10001, //!< Z-value for snapping indicator
ZMouseHandles = 10000, //!< Z-value for mouse handles
ZMapTool = 10001, //!< Z-value for temporary map tool items
ZSnapIndicator = 10002, //!< Z-value for snapping indicator
};
/**

View File

@ -161,6 +161,7 @@ SET(QGIS_GUI_SRCS
layout/qgslayoutitemguiregistry.cpp
layout/qgslayoutitemwidget.cpp
layout/qgslayoutmousehandles.cpp
layout/qgslayoutnewitempropertiesdialog.cpp
layout/qgslayoutruler.cpp
layout/qgslayoutunitscombobox.cpp
@ -657,6 +658,7 @@ SET(QGIS_GUI_MOC_HDRS
layout/qgslayoutdesignerinterface.h
layout/qgslayoutitemguiregistry.h
layout/qgslayoutitemwidget.h
layout/qgslayoutmousehandles.h
layout/qgslayoutnewitempropertiesdialog.h
layout/qgslayoutruler.h
layout/qgslayoutunitscombobox.h

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,203 @@
/***************************************************************************
qgslayoutmousehandles.h
-----------------------
begin : September 2017
copyright : (C) 2017 by Nyall Dawson
email : nyall.dawson@gmail.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSLAYOUTMOUSEHANDLES_H
#define QGSLAYOUTMOUSEHANDLES_H
#define SIP_NO_FILE
#include <QGraphicsRectItem>
#include <QObject>
#include <QPointer>
#include "qgis_gui.h"
class QgsLayout;
class QGraphicsView;
class QgsLayoutView;
///@cond PRIVATE
/**
* \ingroup gui
* Handles drawing of selection outlines and mouse handles in a QgsLayoutView
*
* Also is responsible for mouse interactions such as resizing and moving selected items.
*
* \note not available in Python bindings
* \since QGIS 3.0
*
*/
class GUI_EXPORT QgsLayoutMouseHandles: public QObject, public QGraphicsRectItem
{
Q_OBJECT
public:
//! Describes the action (move or resize in different directon) to be done during mouse move
enum MouseAction
{
MoveItem,
ResizeUp,
ResizeDown,
ResizeLeft,
ResizeRight,
ResizeLeftUp,
ResizeRightUp,
ResizeLeftDown,
ResizeRightDown,
SelectItem,
NoAction
};
enum ItemPositionMode
{
UpperLeft,
UpperMiddle,
UpperRight,
MiddleLeft,
Middle,
MiddleRight,
LowerLeft,
LowerMiddle,
LowerRight
};
enum SnapGuideMode
{
Item,
Point
};
QgsLayoutMouseHandles( QgsLayout *layout, QgsLayoutView *view );
/**
* Sets the \a layout for the handles.
* \see layout()
*/
void setLayout( QgsLayout *layout ) { mLayout = layout; }
/**
* Returns the layout for the handles.
* \see setLayout()
*/
QgsLayout *layout() { return mLayout; }
void paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget ) override;
//! Finds out which mouse move action to choose depending on the scene cursor position
QgsLayoutMouseHandles::MouseAction mouseActionForScenePos( QPointF sceneCoordPos );
//! Returns true is user is currently dragging the handles
bool isDragging() { return mIsDragging; }
//! Returns true is user is currently resizing with the handles
bool isResizing() { return mIsResizing; }
protected:
void mouseMoveEvent( QGraphicsSceneMouseEvent *event ) override;
void mouseReleaseEvent( QGraphicsSceneMouseEvent *event ) override;
void mousePressEvent( QGraphicsSceneMouseEvent *event ) override;
void mouseDoubleClickEvent( QGraphicsSceneMouseEvent *event ) override;
void hoverMoveEvent( QGraphicsSceneHoverEvent *event ) override;
void hoverLeaveEvent( QGraphicsSceneHoverEvent *event ) override;
public slots:
//! Sets up listeners to sizeChanged signal for all selected items
void selectionChanged();
//! Redraws handles when selected item size changes
void selectedItemSizeChanged();
//! Redraws handles when selected item rotation changes
void selectedItemRotationChanged();
private:
QgsLayout *mLayout = nullptr;
QPointer< QgsLayoutView > mView;
MouseAction mCurrentMouseMoveAction = NoAction;
//! Start point of the last mouse move action (in scene coordinates)
QPointF mMouseMoveStartPos;
//! Position of the last mouse move event (in scene coordinates)
QPointF mLastMouseEventPos;
//! Position of the mouse at beginning of move/resize (in scene coordinates)
QPointF mBeginMouseEventPos;
//! Position of composer handles at beginning of move/resize (in scene coordinates)
QPointF mBeginHandlePos;
//! Width and height of composer handles at beginning of resize
double mBeginHandleWidth = 0;
double mBeginHandleHeight = 0;
QRectF mResizeRect;
double mResizeMoveX = 0;
double mResizeMoveY = 0;
//! True if user is currently dragging items
bool mIsDragging = false;
//! True is user is currently resizing items
bool mIsResizing = false;
//! Align snap lines
QGraphicsLineItem *mHAlignSnapItem = nullptr;
QGraphicsLineItem *mVAlignSnapItem = nullptr;
QSizeF mCursorOffset;
//! Returns the mouse handle bounds of current selection
QRectF selectionBounds() const;
//! Returns true if all selected items have same rotation, and if so, updates passed rotation variable
bool selectionRotation( double &rotation ) const;
//! Redraws or hides the handles based on the current selection
void updateHandles();
//! Draws the handles
void drawHandles( QPainter *painter, double rectHandlerSize );
//! Draw outlines for selected items
void drawSelectedItemBounds( QPainter *painter );
/** Returns the current (zoom level dependent) tolerance to decide if mouse position is close enough to the
item border for resizing*/
double rectHandlerBorderTolerance();
//! Finds out the appropriate cursor for the current mouse position in the widget (e.g. move in the middle, resize at border)
Qt::CursorShape cursorForPosition( QPointF itemCoordPos );
//! Finds out which mouse move action to choose depending on the cursor position inside the widget
MouseAction mouseActionForPosition( QPointF itemCoordPos );
//! Handles dragging of items during mouse move
void dragMouseMove( QPointF currentPosition, bool lockMovement, bool preventSnap );
//! Calculates the distance of the mouse cursor from thed edge of the mouse handles
QSizeF calcCursorEdgeOffset( QPointF cursorPos );
//! Handles resizing of items during mouse move
void resizeMouseMove( QPointF currentPosition, bool lockAspect, bool fromCenter );
//sets the mouse cursor for the QGraphicsView attached to the composition (workaround qt bug #3732)
void setViewportCursor( Qt::CursorShape cursor );
//resets the composer window status bar to the default message
void resetStatusBar();
};
///@endcond PRIVATE
#endif // QGSLAYOUTMOUSEHANDLES_H

View File

@ -22,6 +22,7 @@
#include "qgslayoutviewtooltemporarykeypan.h"
#include "qgslayoutviewtooltemporarykeyzoom.h"
#include "qgslayoutviewtooltemporarymousepan.h"
#include "qgslayoutmousehandles.h"
#include "qgslayoutruler.h"
#include "qgssettings.h"
#include "qgsrectangle.h"
@ -88,6 +89,12 @@ void QgsLayoutView::setCurrentLayout( QgsLayout *layout )
connect( &layout->guides(), &QAbstractItemModel::modelReset, mVerticalRuler, [ = ] { mVerticalRuler->update(); } );
}
//add mouse selection handles to layout, and initially hide
mMouseHandles = new QgsLayoutMouseHandles( layout, this );
mMouseHandles->hide();
mMouseHandles->setZValue( QgsLayout::ZMouseHandles );
layout->addItem( mMouseHandles );
//emit layoutSet, so that designer dialogs can update for the new layout
emit layoutSet( layout );
}

View File

@ -35,6 +35,7 @@ class QgsLayoutViewToolTemporaryMousePan;
class QgsLayoutRuler;
class QgsLayoutViewMenuProvider;
class QgsLayoutViewSnapMarker;
class QgsLayoutMouseHandles;
/**
* \ingroup gui
@ -300,6 +301,8 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
std::unique_ptr< QgsLayoutViewSnapMarker > mSnapMarker;
QgsLayoutMouseHandles *mMouseHandles = nullptr; //owned by scene
int mCurrentPage = 0;
friend class TestQgsLayoutView;