Skip to content
Permalink
Browse files

Port more node tool actions

  • Loading branch information
nyalldawson committed Oct 17, 2017
1 parent ab7bb72 commit 938b2392773e259f6e93ab3e3a2096d896d6fceb
@@ -62,6 +62,7 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
UndoRotation,
UndoShapeStyle,
UndoShapeCornerRadius,
UndoNodeMove,
};

explicit QgsLayoutItem( QgsLayout *layout, bool manageZValue = true );
@@ -179,6 +179,13 @@ class QgsLayoutView: QGraphicsView
.. seealso:: distributeSelectedItems()
%End

QPointF deltaForKeyEvent( QKeyEvent *event );
%Docstring
Returns the delta (in layout coordinates) by which to move items
for the given key ``event``.
:rtype: QPointF
%End

public slots:

void zoomFull();
@@ -26,15 +26,23 @@ class QgsLayoutViewToolEditNodes : QgsLayoutViewTool
Constructor for QgsLayoutViewToolEditNodes.
%End

virtual void activate();
void deleteSelectedNode();
%Docstring
Deletes the selected node from the item.
%End

virtual void activate();

virtual void layoutPressEvent( QgsLayoutViewMouseEvent *event );

virtual void layoutMoveEvent( QgsLayoutViewMouseEvent *event );

virtual void layoutReleaseEvent( QgsLayoutViewMouseEvent *event );

virtual void layoutDoubleClickEvent( QgsLayoutViewMouseEvent *event );

virtual void keyPressEvent( QKeyEvent *event );

virtual void deactivate();


@@ -385,7 +385,10 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla

connect( mActionDeleteSelection, &QAction::triggered, this, [ = ]
{
mView->deleteSelectedItems();
if ( mView->tool() == mNodesTool )
mNodesTool->deleteSelectedNode();
else
mView->deleteSelectedItems();
} );
connect( mActionGroupItems, &QAction::triggered, this, [ = ]
{
@@ -95,6 +95,7 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
UndoRotation, //!< Rotation adjustment
UndoShapeStyle, //!< Shape symbol style
UndoShapeCornerRadius, //!< Shape corner radius
UndoNodeMove, //!< Node move
};

/**
@@ -25,7 +25,7 @@ QgsLayoutViewRubberBand *QgsLayoutItemAbstractGuiMetadata::createRubberBand( Qgs
return new QgsLayoutViewRectangularRubberBand( view );
}

QAbstractGraphicsShapeItem *QgsLayoutItemAbstractGuiMetadata::createNodeRubberBand( QgsLayoutView *view )
QAbstractGraphicsShapeItem *QgsLayoutItemAbstractGuiMetadata::createNodeRubberBand( QgsLayoutView * )
{
return nullptr;
}
@@ -274,6 +274,48 @@ void QgsLayoutView::resizeSelectedItems( QgsLayoutAligner::Resize resize )
QgsLayoutAligner::resizeItems( currentLayout(), selectedItems, resize );
}

QPointF QgsLayoutView::deltaForKeyEvent( QKeyEvent *event )
{
// increment used for cursor key item movement
double increment = 1.0;
if ( event->modifiers() & Qt::ShiftModifier )
{
//holding shift while pressing cursor keys results in a big step
increment = 10.0;
}
else if ( event->modifiers() & Qt::AltModifier )
{
//holding alt while pressing cursor keys results in a 1 pixel step
double viewScale = transform().m11();
if ( viewScale > 0 )
{
increment = 1 / viewScale;
}
}

double deltaX = 0;
double deltaY = 0;
switch ( event->key() )
{
case Qt::Key_Left:
deltaX = -increment;
break;
case Qt::Key_Right:
deltaX = increment;
break;
case Qt::Key_Up:
deltaY = -increment;
break;
case Qt::Key_Down:
deltaY = increment;
break;
default:
break;
}

return QPointF( deltaX, deltaY );
}

void QgsLayoutView::zoomFull()
{
fitInView( scene()->sceneRect(), Qt::KeepAspectRatio );
@@ -811,47 +853,11 @@ void QgsLayoutView::keyPressEvent( QKeyEvent *event )
QgsLayout *l = currentLayout();
const QList<QgsLayoutItem *> layoutItemList = l->selectedLayoutItems();

// increment used for cursor key item movement
double increment = 1.0;
if ( event->modifiers() & Qt::ShiftModifier )
{
//holding shift while pressing cursor keys results in a big step
increment = 10.0;
}
else if ( event->modifiers() & Qt::AltModifier )
{
//holding alt while pressing cursor keys results in a 1 pixel step
double viewScale = transform().m11();
if ( viewScale > 0 )
{
increment = 1 / viewScale;
}
}

double deltaX = 0;
double deltaY = 0;
switch ( event->key() )
{
case Qt::Key_Left:
deltaX = -increment;
break;
case Qt::Key_Right:
deltaX = increment;
break;
case Qt::Key_Up:
deltaY = -increment;
break;
case Qt::Key_Down:
deltaY = increment;
break;
default:
break;
}

auto moveItem = [ l, deltaX, deltaY ]( QgsLayoutItem * item )
QPointF delta = deltaForKeyEvent( event );
auto moveItem = [ l, delta ]( QgsLayoutItem * item )
{
QgsLayoutPoint itemPos = item->positionWithUnits();
QgsLayoutPoint deltaPos = l->convertFromLayoutUnits( QPointF( deltaX, deltaY ), itemPos.units() );
QgsLayoutPoint deltaPos = l->convertFromLayoutUnits( delta, itemPos.units() );
itemPos.setX( itemPos.x() + deltaPos.x() );
itemPos.setY( itemPos.y() + deltaPos.y() );
item->attemptMove( itemPos );
@@ -208,6 +208,12 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
*/
void resizeSelectedItems( QgsLayoutAligner::Resize resize );

/**
* Returns the delta (in layout coordinates) by which to move items
* for the given key \a event.
*/
QPointF deltaForKeyEvent( QKeyEvent *event );

public slots:

/**
@@ -26,6 +26,34 @@ QgsLayoutViewToolEditNodes::QgsLayoutViewToolEditNodes( QgsLayoutView *view )
setFlags( QgsLayoutViewTool::FlagSnaps );
}

void QgsLayoutViewToolEditNodes::deleteSelectedNode()
{
if ( mNodesItem && mNodesItemIndex != -1 )
{
layout()->undoStack()->beginCommand( mNodesItem, tr( "Remove Item Node" ) );
if ( mNodesItem->removeNode( mNodesItemIndex ) )
{
layout()->undoStack()->endCommand();
if ( mNodesItem->nodesSize() > 0 )
{
mNodesItemIndex = mNodesItem->selectedNode();
// setSelectedNode( mNodesItem, mNodesItemIndex );
}
else
{
mNodesItemIndex = -1;
mNodesItem = nullptr;
}
if ( mNodesItem )
mNodesItem->update();
}
else
{
layout()->undoStack()->cancelCommand();
}
}
}

void QgsLayoutViewToolEditNodes::activate()
{
displayNodes( true );
@@ -65,7 +93,7 @@ void QgsLayoutViewToolEditNodes::layoutPressEvent( QgsLayoutViewMouseEvent *even
}
}

if ( mNodesItemIndex != -1 )
if ( mNodesItem && mNodesItemIndex != -1 )
{
layout()->undoStack()->beginCommand( mNodesItem, tr( "Move Item Node" ) );
setSelectedNode( mNodesItem, mNodesItemIndex );
@@ -83,7 +111,7 @@ void QgsLayoutViewToolEditNodes::layoutMoveEvent( QgsLayoutViewMouseEvent *event
return;
}

if ( mNodesItemIndex != -1 && event->layoutPoint() != mMoveContentStartPos )
if ( mNodesItem && mNodesItemIndex != -1 && event->layoutPoint() != mMoveContentStartPos )
{
mNodesItem->moveNode( mNodesItemIndex, event->snappedPoint() );
}
@@ -111,6 +139,89 @@ void QgsLayoutViewToolEditNodes::layoutReleaseEvent( QgsLayoutViewMouseEvent *ev
}
}

void QgsLayoutViewToolEditNodes::layoutDoubleClickEvent( QgsLayoutViewMouseEvent *event )
{
if ( event->button() != Qt::LeftButton )
{
event->ignore();
return;
}

// erase status previously set by the mousePressEvent method
if ( mNodesItemIndex != -1 )
{
mNodesItem = nullptr;
mNodesItemIndex = -1;
deselectNodes();
}

// search items in layout
const QList<QGraphicsItem *> itemsAtCursorPos = view()->items( event->pos().x(), event->pos().y(),
mMoveContentSearchRadius,
mMoveContentSearchRadius );

if ( itemsAtCursorPos.isEmpty() )
return;

bool rc = false;
for ( QGraphicsItem *graphicsItem : itemsAtCursorPos )
{
QgsLayoutNodesItem *item = dynamic_cast<QgsLayoutNodesItem *>( graphicsItem );

if ( item && !item->isLocked() )
{
layout()->undoStack()->beginCommand( item, tr( "Add Item Node" ) );
rc = item->addNode( event->layoutPoint() );

if ( rc )
{
layout()->undoStack()->endCommand();
mNodesItem = item;
mNodesItemIndex = mNodesItem->nodeAtPosition( event->layoutPoint() );
}
else
layout()->undoStack()->cancelCommand();
}

if ( rc )
break;
}

if ( rc )
{
setSelectedNode( mNodesItem, mNodesItemIndex );
mNodesItem->update();
}
}

void QgsLayoutViewToolEditNodes::keyPressEvent( QKeyEvent *event )
{
if ( mNodesItem && mNodesItemIndex != -1 && ( event->key() == Qt::Key_Left
|| event->key() == Qt::Key_Right
|| event->key() == Qt::Key_Up
|| event->key() == Qt::Key_Down ) )
{
QPointF currentPos;

if ( mNodesItem->nodePosition( mNodesItemIndex, currentPos ) )
{
QPointF delta = view()->deltaForKeyEvent( event );

currentPos.setX( currentPos.x() + delta.x() );
currentPos.setY( currentPos.y() + delta.y() );

layout()->undoStack()->beginCommand( mNodesItem, tr( "Move Item Node" ), QgsLayoutItem::UndoNodeMove );
mNodesItem->moveNode( mNodesItemIndex, currentPos );
layout()->undoStack()->endCommand();
layout()->update();
}
}
else
{
event->ignore();
}
}

void QgsLayoutViewToolEditNodes::deactivate()
{
displayNodes( false );
@@ -126,9 +237,8 @@ void QgsLayoutViewToolEditNodes::displayNodes( bool display )
for ( QgsLayoutNodesItem *item : qgis::as_const( nodesShapes ) )
{
item->setDisplayNodes( display );
item->update();
}

layout()->update();
}

void QgsLayoutViewToolEditNodes::deselectNodes()
@@ -139,9 +249,8 @@ void QgsLayoutViewToolEditNodes::deselectNodes()
for ( QgsLayoutNodesItem *item : qgis::as_const( nodesShapes ) )
{
item->deselectNode();
item->update();
}

layout()->update();
}

void QgsLayoutViewToolEditNodes::setSelectedNode( QgsLayoutNodesItem *shape, int index )
@@ -39,18 +39,24 @@ class GUI_EXPORT QgsLayoutViewToolEditNodes : public QgsLayoutViewTool
*/
QgsLayoutViewToolEditNodes( QgsLayoutView *view SIP_TRANSFERTHIS );

void activate() override;
/**
* Deletes the selected node from the item.
*/
void deleteSelectedNode();

void activate() override;
void layoutPressEvent( QgsLayoutViewMouseEvent *event ) override;
void layoutMoveEvent( QgsLayoutViewMouseEvent *event ) override;
void layoutReleaseEvent( QgsLayoutViewMouseEvent *event ) override;
void layoutDoubleClickEvent( QgsLayoutViewMouseEvent *event ) override;
void keyPressEvent( QKeyEvent *event ) override;
void deactivate() override;

private:

const double mMoveContentSearchRadius = 25;

QgsLayoutNodesItem *mNodesItem = nullptr;
QPointer< QgsLayoutNodesItem > mNodesItem;
int mNodesItemIndex = -1;

//! Start position of content move

0 comments on commit 938b239

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