[needs-docs] Partial WIP of dragging rulers to create guide lines

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)
This commit is contained in:
Nyall Dawson 2017-07-25 21:23:06 +10:00
parent ef6727518d
commit b0956c9bd7
4 changed files with 118 additions and 13 deletions

View File

@ -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 );

View File

@ -80,7 +80,7 @@ void QgsLayoutGuide::update()
switch ( mOrientation )
{
case Horizontal:
if ( layoutPos > page->rect().width() )
if ( layoutPos > page->rect().height() )
{
mLineItem->hide();
}
@ -93,7 +93,7 @@ void QgsLayoutGuide::update()
break;
case Vertical:
if ( layoutPos > page->rect().height() )
if ( layoutPos > page->rect().width() )
{
mLineItem->hide();
}

View File

@ -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() );
}
}

View File

@ -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[];
@ -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 );