Skip to content

Commit

Permalink
[FEATURE] [needs-docs] add new vertical and horizontal equispaced dis…
Browse files Browse the repository at this point in the history
…tributions
  • Loading branch information
nastasi-oq committed Mar 9, 2019
1 parent 4f1dd95 commit 7c6b66b
Show file tree
Hide file tree
Showing 9 changed files with 243 additions and 6 deletions.
2 changes: 2 additions & 0 deletions images/images.qrc
Expand Up @@ -167,10 +167,12 @@
<file>themes/default/mActionDataSourceManager.svg</file>
<file>themes/default/mActionDistributeBottom.svg</file>
<file>themes/default/mActionDistributeHCenter.svg</file>
<file>themes/default/mActionDistributeHSpace.svg</file>
<file>themes/default/mActionDistributeLeft.svg</file>
<file>themes/default/mActionDistributeRight.svg</file>
<file>themes/default/mActionDistributeTop.svg</file>
<file>themes/default/mActionDistributeVCenter.svg</file>
<file>themes/default/mActionDistributeVSpace.svg</file>
<file>themes/default/mActionAddLayer.svg</file>
<file>themes/default/mActionAddMeshLayer.svg</file>
<file>themes/default/mActionAddAllToOverview.svg</file>
Expand Down
49 changes: 49 additions & 0 deletions images/themes/default/mActionDistributeHSpace.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 49 additions & 0 deletions images/themes/default/mActionDistributeVSpace.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions python/core/auto_generated/layout/qgslayoutaligner.sip.in
Expand Up @@ -38,9 +38,11 @@ sets of layout items, e.g. aligning a group of items to top or left sides.
{
DistributeLeft,
DistributeHCenter,
DistributeHSpace,
DistributeRight,
DistributeTop,
DistributeVCenter,
DistributeVSpace,
DistributeBottom,
};

Expand Down
12 changes: 12 additions & 0 deletions src/app/layout/qgslayoutdesignerdialog.cpp
Expand Up @@ -411,9 +411,11 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
distributeToolButton->setToolButtonStyle( Qt::ToolButtonIconOnly );
distributeToolButton->addAction( mActionDistributeLeft );
distributeToolButton->addAction( mActionDistributeHCenter );
distributeToolButton->addAction( mActionDistributeHSpace );
distributeToolButton->addAction( mActionDistributeRight );
distributeToolButton->addAction( mActionDistributeTop );
distributeToolButton->addAction( mActionDistributeVCenter );
distributeToolButton->addAction( mActionDistributeVSpace );
distributeToolButton->addAction( mActionDistributeBottom );
distributeToolButton->setDefaultAction( mActionDistributeLeft );
mActionsToolbar->addWidget( distributeToolButton );
Expand Down Expand Up @@ -582,6 +584,10 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
{
mView->distributeSelectedItems( QgsLayoutAligner::DistributeHCenter );
} );
connect( mActionDistributeHSpace, &QAction::triggered, this, [ = ]
{
mView->distributeSelectedItems( QgsLayoutAligner::DistributeHSpace );
} );
connect( mActionDistributeRight, &QAction::triggered, this, [ = ]
{
mView->distributeSelectedItems( QgsLayoutAligner::DistributeRight );
Expand All @@ -594,6 +600,10 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
{
mView->distributeSelectedItems( QgsLayoutAligner::DistributeVCenter );
} );
connect( mActionDistributeVSpace, &QAction::triggered, this, [ = ]
{
mView->distributeSelectedItems( QgsLayoutAligner::DistributeVSpace );
} );
connect( mActionDistributeBottom, &QAction::triggered, this, [ = ]
{
mView->distributeSelectedItems( QgsLayoutAligner::DistributeBottom );
Expand Down Expand Up @@ -4330,9 +4340,11 @@ void QgsLayoutDesignerDialog::toggleActions( bool layoutAvailable )
mActionAlignBottom->setEnabled( layoutAvailable );
mActionDistributeLeft->setEnabled( layoutAvailable );
mActionDistributeHCenter->setEnabled( layoutAvailable );
mActionDistributeHSpace->setEnabled( layoutAvailable );
mActionDistributeRight->setEnabled( layoutAvailable );
mActionDistributeTop->setEnabled( layoutAvailable );
mActionDistributeVCenter->setEnabled( layoutAvailable );
mActionDistributeVSpace->setEnabled( layoutAvailable );
mActionDistributeBottom->setEnabled( layoutAvailable );
mActionResizeNarrowest->setEnabled( layoutAvailable );
mActionResizeWidest->setEnabled( layoutAvailable );
Expand Down
79 changes: 74 additions & 5 deletions src/core/layout/qgslayoutaligner.cpp
Expand Up @@ -97,6 +97,66 @@ void QgsLayoutAligner::distributeItems( QgsLayout *layout, const QList<QgsLayout
if ( items.size() < 2 )
return;

double minCoord = std::numeric_limits<double>::max();
double maxCoord = std::numeric_limits<double>::lowest();
QMap< double, QgsLayoutItem * > itemCoords;

double step;

// equispaced distribution doesn't follow the same approach of the other distribution types
if ( distribution == DistributeHSpace || distribution == DistributeVSpace )
{
double length = 0.0;

for ( QgsLayoutItem *item : items )
{
QRectF itemBBox = item->sceneBoundingRect();
double item_min, item_max;

item_min = ( distribution == DistributeHSpace ? itemBBox.left() :
itemBBox.top() );
item_max = ( distribution == DistributeHSpace ? itemBBox.right() :
itemBBox.bottom() );

minCoord = std::min( minCoord, item_min );
maxCoord = std::max( maxCoord, item_max );
length += ( item_max - item_min );
itemCoords.insert( item_min, item );
}
step = ( maxCoord - minCoord - length ) / ( items.size() - 1 );

double currentVal = minCoord;
layout->undoStack()->beginMacro( undoText( distribution ) );
for ( auto itemIt = itemCoords.constBegin(); itemIt != itemCoords.constEnd(); ++itemIt )
{
QgsLayoutItem *item = itemIt.value();
QPointF shifted = item->pos();

layout->undoStack()->beginCommand( itemIt.value(), QString() );

if ( distribution == DistributeHSpace )
{
shifted.setX( currentVal );
}
else
{
shifted.setY( currentVal );
}

QgsLayoutPoint newPos = layout->convertFromLayoutUnits( shifted, item->positionWithUnits().units() );
item->attemptMove( newPos );

layout->undoStack()->endCommand();

currentVal += ( distribution == DistributeHSpace ? item->rect().width() :
item->rect().height() ) + step;

layout->undoStack()->endMacro();
}

return;
}

auto collectReferenceCoord = [distribution]( QgsLayoutItem * item )->double
{
QRectF itemBBox = item->sceneBoundingRect();
Expand All @@ -114,15 +174,16 @@ void QgsLayoutAligner::distributeItems( QgsLayout *layout, const QList<QgsLayout
return itemBBox.center().y();
case DistributeBottom:
return itemBBox.bottom();
case DistributeHSpace:
case DistributeVSpace:
// not reachable branch, just to avoid compilation warning
return 0.0;
}
// no warnings
return itemBBox.left();
};


double minCoord = std::numeric_limits<double>::max();
double maxCoord = std::numeric_limits<double>::lowest();
QMap< double, QgsLayoutItem * > itemCoords;
for ( QgsLayoutItem *item : items )
{
double refCoord = collectReferenceCoord( item );
Expand All @@ -131,7 +192,7 @@ void QgsLayoutAligner::distributeItems( QgsLayout *layout, const QList<QgsLayout
itemCoords.insert( refCoord, item );
}

double step = ( maxCoord - minCoord ) / ( items.size() - 1 );
step = ( maxCoord - minCoord ) / ( items.size() - 1 );

auto distributeItemToCoord = [layout, distribution]( QgsLayoutItem * item, double refCoord )
{
Expand All @@ -156,6 +217,10 @@ void QgsLayoutAligner::distributeItems( QgsLayout *layout, const QList<QgsLayout
case DistributeBottom:
shifted.setY( refCoord - item->rect().height() );
break;
case DistributeHSpace:
case DistributeVSpace:
// not reachable branch, just to avoid compilation warning
break;
}

// need to keep item units
Expand Down Expand Up @@ -302,13 +367,17 @@ QString QgsLayoutAligner::undoText( Distribution distribution )
case DistributeLeft:
return QObject::tr( "Distribute Items by Left" );
case DistributeHCenter:
return QObject::tr( "Distribute Items by Center" );
return QObject::tr( "Distribute Items by Horizontal Center" );
case DistributeHSpace:
return QObject::tr( "Distribute Items by Horizontal Equispaced" );
case DistributeRight:
return QObject::tr( "Distribute Items by Right" );
case DistributeTop:
return QObject::tr( "Distribute Items by Top" );
case DistributeVCenter:
return QObject::tr( "Distribute Items by Vertical Center" );
case DistributeVSpace:
return QObject::tr( "Distribute Items by Vertical Equispaced" );
case DistributeBottom:
return QObject::tr( "Distribute Items by Bottom" );
}
Expand Down
2 changes: 2 additions & 0 deletions src/core/layout/qgslayoutaligner.h
Expand Up @@ -54,9 +54,11 @@ class CORE_EXPORT QgsLayoutAligner
{
DistributeLeft, //!< Distribute left edges
DistributeHCenter, //!< Distribute horizontal centers
DistributeHSpace, //!< Distribute horizontal equispaced
DistributeRight, //!< Distribute right edges
DistributeTop, //!< Distribute top edges
DistributeVCenter, //!< Distribute vertical centers
DistributeVSpace, //!< Distribute vertical equispaced
DistributeBottom, //!< Distribute bottom edges
};

Expand Down
28 changes: 27 additions & 1 deletion src/ui/layout/qgslayoutdesignerbase.ui
Expand Up @@ -317,10 +317,12 @@
</property>
<addaction name="mActionDistributeLeft"/>
<addaction name="mActionDistributeHCenter"/>
<addaction name="mActionDistributeHSpace"/>
<addaction name="mActionDistributeRight"/>
<addaction name="separator"/>
<addaction name="mActionDistributeTop"/>
<addaction name="mActionDistributeVCenter"/>
<addaction name="mActionDistributeVSpace"/>
<addaction name="mActionDistributeBottom"/>
</widget>
<widget class="QMenu" name="menuResize">
Expand Down Expand Up @@ -918,12 +920,24 @@
<normaloff>:/images/themes/default/mActionDistributeHCenter.svg</normaloff>:/images/themes/default/mActionDistributeHCenter.svg</iconset>
</property>
<property name="text">
<string>Distribute &amp;Centers</string>
<string>Distribute horizontal &amp;Centers</string>
</property>
<property name="toolTip">
<string>Distributes horizontal centers of items equidistantly</string>
</property>
</action>
<action name="mActionDistributeHSpace">
<property name="icon">
<iconset resource="../../../images/images.qrc">
<normaloff>:/images/themes/default/mActionDistributeHSpace.svg</normaloff>:/images/themes/default/mActionDistributeHSpace.svg</iconset>
</property>
<property name="text">
<string>Distribute &amp;Horizontally Equispaced</string>
</property>
<property name="toolTip">
<string>Distributes items equidistantly with respect to their horizontal edges</string>
</property>
</action>
<action name="mActionDistributeRight">
<property name="icon">
<iconset resource="../../../images/images.qrc">
Expand Down Expand Up @@ -960,6 +974,18 @@
<string>Distributes vertical centers of items equidistantly</string>
</property>
</action>
<action name="mActionDistributeVSpace">
<property name="icon">
<iconset resource="../../../images/images.qrc">
<normaloff>:/images/themes/default/mActionDistributeVSpace.svg</normaloff>:/images/themes/default/mActionDistributeVSpace.svg</iconset>
</property>
<property name="text">
<string>Distribute Vertically &amp;Equispaced</string>
</property>
<property name="toolTip">
<string>Distributes items equidistantly with respect to their vertical edges</string>
</property>
</action>
<action name="mActionDistributeBottom">
<property name="icon">
<iconset resource="../../../images/images.qrc">
Expand Down

0 comments on commit 7c6b66b

Please sign in to comment.