Skip to content

Commit

Permalink
[needs-docs] Partial WIP of dragging rulers to create guide lines
Browse files Browse the repository at this point in the history
Unlike in 2.x, Layouts in 3.0 adopt the standard UX of dragging
out rulers to create guide lines (instead of clicking on a ruler
position to create a guide)
  • Loading branch information
nyalldawson committed Aug 7, 2017
1 parent ef67275 commit b0956c9
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 13 deletions.
4 changes: 4 additions & 0 deletions python/gui/layout/qgslayoutruler.sip
Expand Up @@ -72,6 +72,10 @@ class QgsLayoutRuler: QWidget

virtual void mouseMoveEvent( QMouseEvent *event );

virtual void mousePressEvent( QMouseEvent *event );

virtual void mouseReleaseEvent( QMouseEvent *event );


signals:
void cursorPosChanged( QPointF );
Expand Down
4 changes: 2 additions & 2 deletions src/core/layout/qgslayoutguidecollection.cpp
Expand Up @@ -80,7 +80,7 @@ void QgsLayoutGuide::update()
switch ( mOrientation )
{
case Horizontal:
if ( layoutPos > page->rect().width() )
if ( layoutPos > page->rect().height() )
{
mLineItem->hide();
}
Expand All @@ -93,7 +93,7 @@ void QgsLayoutGuide::update()
break;

case Vertical:
if ( layoutPos > page->rect().height() )
if ( layoutPos > page->rect().width() )
{
mLineItem->hide();
}
Expand Down
118 changes: 107 additions & 11 deletions src/gui/layout/qgslayoutruler.cpp
Expand Up @@ -428,22 +428,118 @@ void QgsLayoutRuler::mouseMoveEvent( QMouseEvent *event )
mMarkerPos = event->posF();
update();

//update cursor position in status bar
QPointF displayPos = mTransform.inverted().map( event->posF() );
switch ( mOrientation )
QPointF displayPos;
if ( mCreatingGuide )
{
case Qt::Horizontal:
// event -> layout coordinates
QgsLayout *layout = mView->currentLayout();
QPoint viewPoint = mView->mapFromGlobal( mapToGlobal( event->pos() ) );
displayPos = mView->mapToScene( viewPoint );
int pageNo = layout->pageCollection()->pageNumberForPoint( displayPos );
QgsLayoutItemPage *page = layout->pageCollection()->page( pageNo );

switch ( mOrientation )
{
//mouse is over a horizontal ruler, so don't show a y coordinate
displayPos.setY( 0 );
break;
case Qt::Horizontal:
{
//mouse is creating a horizontal ruler, so don't show x coordinate
mGuideItem->setLine( 0, displayPos.y(), page->rect().width(), displayPos.y() );
displayPos.setX( 0 );
break;
}
case Qt::Vertical:
{
//mouse is creating a vertical ruler, so don't show a y coordinate
mGuideItem->setLine( displayPos.x(), 0, displayPos.x(), page->rect().height() );
displayPos.setY( 0 );
break;
}
}
case Qt::Vertical:
}
else
{
//update cursor position in status bar
displayPos = mTransform.inverted().map( event->posF() );
switch ( mOrientation )
{
//mouse is over a vertical ruler, so don't show an x coordinate
displayPos.setX( 0 );
break;
case Qt::Horizontal:
{
//mouse is over a horizontal ruler, so don't show a y coordinate
displayPos.setY( 0 );
break;
}
case Qt::Vertical:
{
//mouse is over a vertical ruler, so don't show an x coordinate
displayPos.setX( 0 );
break;
}
}
}
emit cursorPosChanged( displayPos );
}

void QgsLayoutRuler::mousePressEvent( QMouseEvent *event )
{
if ( event->button() == Qt::LeftButton )
{
mCreatingGuide = true;
mGuideItem.reset( new QGraphicsLineItem() );

mGuideItem->setZValue( QgsLayout::ZGuide );
QPen linePen( Qt::DashLine );
linePen.setColor( Qt::red );
linePen.setWidthF( 0 );
mGuideItem->setPen( linePen );

mView->currentLayout()->addItem( mGuideItem.get() );

switch ( mOrientation )
{
case Qt::Horizontal:
{
QApplication::setOverrideCursor( Qt::SplitVCursor );
break;
}
case Qt::Vertical:
QApplication::setOverrideCursor( Qt::SplitHCursor );
break;
}
}
}

void QgsLayoutRuler::mouseReleaseEvent( QMouseEvent *event )
{
if ( event->button() == Qt::LeftButton )
{
mCreatingGuide = false;
QApplication::restoreOverrideCursor();
mGuideItem.reset();

QgsLayout *layout = mView->currentLayout();

// create guide
QPoint viewPoint = mView->mapFromGlobal( mapToGlobal( event->pos() ) );
QPointF scenePos = mView->mapToScene( viewPoint );
int page = layout->pageCollection()->pageNumberForPoint( scenePos );
std::unique_ptr< QgsLayoutGuide > guide;
switch ( mOrientation )
{
case Qt::Horizontal:
{
//mouse is creating a horizontal guide
double posOnPage = layout->pageCollection()->positionOnPage( scenePos ).y();
guide.reset( new QgsLayoutGuide( QgsLayoutGuide::Horizontal, QgsLayoutMeasurement( posOnPage, layout->units() ) ) );
break;
}
case Qt::Vertical:
{
//mouse is creating a vertical guide
guide.reset( new QgsLayoutGuide( QgsLayoutGuide::Vertical, QgsLayoutMeasurement( scenePos.x(), layout->units() ) ) );
break;
}
}
guide->setPage( page );
mView->currentLayout()->guides().addGuide( guide.release() );
}
}
5 changes: 5 additions & 0 deletions src/gui/layout/qgslayoutruler.h
Expand Up @@ -81,6 +81,8 @@ class GUI_EXPORT QgsLayoutRuler: public QWidget
protected:
void paintEvent( QPaintEvent *event ) override;
void mouseMoveEvent( QMouseEvent *event ) override;
void mousePressEvent( QMouseEvent *event ) override;
void mouseReleaseEvent( QMouseEvent *event ) override;

private:
static const int VALID_SCALE_MULTIPLES[];
Expand All @@ -102,6 +104,9 @@ class GUI_EXPORT QgsLayoutRuler: public QWidget
int mTextBaseline;
int mMinSpacingVerticalLabels;

bool mCreatingGuide = false;
std::unique_ptr< QGraphicsLineItem > mGuideItem;

//! Calculates the optimum labeled units for ruler so that labels are a good distance apart
int optimumScale( double minPixelDiff, int &magnitude, int &multiple );

Expand Down

0 comments on commit b0956c9

Please sign in to comment.