24 if ( !layout || items.size() < 2 )
29 QRectF itemBBox = boundingRectOfItems( items );
30 if ( !itemBBox.isValid() )
39 refCoord = itemBBox.left();
42 refCoord = itemBBox.center().x();
45 refCoord = itemBBox.right();
48 refCoord = itemBBox.top();
51 refCoord = itemBBox.center().y();
54 refCoord = itemBBox.bottom();
63 QPointF shifted = item->pos();
67 shifted.setX( refCoord );
70 shifted.setX( refCoord - item->rect().width() / 2.0 );
73 shifted.setX( refCoord - item->rect().width() );
76 shifted.setY( refCoord );
79 shifted.setY( refCoord - item->rect().height() / 2.0 );
82 shifted.setY( refCoord - item->rect().height() );
88 item->attemptMove( newPos,
false );
97 if ( items.size() < 2 )
103 distributeEquispacedItems( layout, items, distribution );
107 auto collectReferenceCoord = [distribution](
QgsLayoutItem * item )->
double 109 QRectF itemBBox = item->sceneBoundingRect();
110 switch ( distribution )
113 return itemBBox.left();
115 return itemBBox.center().x();
117 return itemBBox.right();
119 return itemBBox.top();
121 return itemBBox.center().y();
123 return itemBBox.bottom();
127 return std::numeric_limits<double>::quiet_NaN();
130 return itemBBox.left();
134 double minCoord = std::numeric_limits<double>::max();
135 double maxCoord = std::numeric_limits<double>::lowest();
136 QMap< double, QgsLayoutItem * > itemCoords;
139 double refCoord = collectReferenceCoord( item );
140 minCoord = std::min( minCoord, refCoord );
141 maxCoord = std::max( maxCoord, refCoord );
142 itemCoords.insert( refCoord, item );
145 const double step = ( maxCoord - minCoord ) / ( items.size() - 1 );
147 auto distributeItemToCoord = [layout, distribution](
QgsLayoutItem * item,
double refCoord )
149 QPointF shifted = item->pos();
150 switch ( distribution )
153 shifted.setX( refCoord );
156 shifted.setX( refCoord - item->rect().width() / 2.0 );
159 shifted.setX( refCoord - item->rect().width() );
162 shifted.setY( refCoord );
165 shifted.setY( refCoord - item->rect().height() / 2.0 );
168 shifted.setY( refCoord - item->rect().height() );
178 item->attemptMove( newPos,
false );
183 double currentVal = minCoord;
184 for (
auto itemIt = itemCoords.constBegin(); itemIt != itemCoords.constEnd(); ++itemIt )
187 distributeItemToCoord( itemIt.value(), currentVal );
197 if ( !( items.size() >= 2 || ( items.size() == 1 && resize ==
ResizeToSquare ) ) )
202 QRectF itemBBox = item->sceneBoundingRect();
208 return itemBBox.width();
211 return itemBBox.height();
214 return itemBBox.width();
217 double newSize = collectSize( items.at( 0 ) );
220 double size = collectSize( item );
225 newSize = std::min( size, newSize );
229 newSize = std::max( size, newSize );
236 auto resizeItemToSize = [layout, resize](
QgsLayoutItem * item,
double size )
238 QSizeF newSize = item->rect().size();
243 newSize.setWidth( size );
247 newSize.setHeight( size );
251 if ( newSize.width() > newSize.height() )
252 newSize.setHeight( newSize.width() );
254 newSize.setWidth( newSize.height() );
261 item->attemptResize( newSizeWithUnits );
268 resizeItemToSize( item, newSize );
274 QRectF QgsLayoutAligner::boundingRectOfItems(
const QList<QgsLayoutItem *> &items )
281 auto it = items.constBegin();
285 double minX = currentItem->pos().x();
286 double minY = currentItem->pos().y();
287 double maxX = minX + currentItem->rect().width();
288 double maxY = minY + currentItem->rect().height();
290 double currentMinX, currentMinY, currentMaxX, currentMaxY;
292 for ( ; it != items.constEnd(); ++it )
295 currentMinX = currentItem->pos().x();
296 currentMinY = currentItem->pos().y();
297 currentMaxX = currentMinX + currentItem->rect().width();
298 currentMaxY = currentMinY + currentItem->rect().height();
300 if ( currentMinX < minX )
302 if ( currentMaxX > maxX )
304 if ( currentMinY < minY )
306 if ( currentMaxY > maxY )
310 return QRectF( QPointF( minX, minY ), QPointF( maxX, maxY ) );
313 QString QgsLayoutAligner::undoText(
Distribution distribution )
315 switch ( distribution )
318 return QObject::tr(
"Distribute Items by Left" );
320 return QObject::tr(
"Distribute Items by Horizontal Center" );
322 return QObject::tr(
"Distribute Horizontal Spacing Equally" );
324 return QObject::tr(
"Distribute Items by Right" );
326 return QObject::tr(
"Distribute Items by Top" );
328 return QObject::tr(
"Distribute Items by Vertical Center" );
330 return QObject::tr(
"Distribute Vertical Spacing Equally" );
332 return QObject::tr(
"Distribute Items by Bottom" );
342 return QObject::tr(
"Resize Items to Narrowest" );
344 return QObject::tr(
"Resize Items to Widest" );
346 return QObject::tr(
"Resize Items to Shortest" );
348 return QObject::tr(
"Resize Items to Tallest" );
350 return QObject::tr(
"Resize Items to Square" );
355 QString QgsLayoutAligner::undoText(
Alignment alignment )
360 return QObject::tr(
"Align Items to Left" );
362 return QObject::tr(
"Align Items to Center" );
364 return QObject::tr(
"Align Items to Right" );
366 return QObject::tr(
"Align Items to Top" );
368 return QObject::tr(
"Align Items to Vertical Center" );
370 return QObject::tr(
"Align Items to Bottom" );
378 double minCoord = std::numeric_limits<double>::max();
379 double maxCoord = std::numeric_limits<double>::lowest();
380 QMap< double, QgsLayoutItem * > itemCoords;
384 QRectF itemBBox = item->sceneBoundingRect();
391 minCoord = std::min( minCoord, item_min );
392 maxCoord = std::max( maxCoord, item_max );
393 length += ( item_max - item_min );
394 itemCoords.insert( item_min, item );
396 const double step = ( maxCoord - minCoord - length ) / ( items.size() - 1 );
398 double currentVal = minCoord;
400 for (
auto itemIt = itemCoords.constBegin(); itemIt != itemCoords.constEnd(); ++itemIt )
403 QPointF shifted = item->pos();
409 shifted.setX( currentVal );
413 shifted.setY( currentVal );
422 item->rect().height() ) + step;
QgsLayoutPoint positionWithUnits() const
Returns the item's current position, including units.
Base class for graphical items within a QgsLayout.
QgsLayoutUndoStack * undoStack()
Returns a pointer to the layout's undo stack, which manages undo/redo states for the layout and it's ...
Distribute horizontal equispaced.
Resize height to match shortest height.
static void alignItems(QgsLayout *layout, const QList< QgsLayoutItem * > &items, Alignment alignment)
Aligns a set of items from a layout in place.
Distribute vertical centers.
This class provides a method of storing points, consisting of an x and y coordinate, for use in QGIS layouts.
QgsUnitTypes::LayoutUnit units() const
Returns the units for the point.
void endCommand()
Saves final state of an object and pushes the active command to the undo history. ...
Distribution
Distribution options.
static void distributeItems(QgsLayout *layout, const QList< QgsLayoutItem * > &items, Distribution distribution)
Distributes a set of items from a layout in place.
Resize height to match tallest height.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
void beginMacro(const QString &commandText)
Starts a macro command, with the given descriptive commandText.
Resize width to match widest width.
void beginCommand(QgsLayoutUndoObjectInterface *object, const QString &commandText, int id=0)
Begins a new undo command for the specified object.
virtual void attemptMove(const QgsLayoutPoint &point, bool useReferencePoint=true, bool includesFrame=false, int page=-1)
Attempts to move the item to a specified point.
Align horizontal centers.
QgsLayoutMeasurement convertFromLayoutUnits(double length, QgsUnitTypes::LayoutUnit unit) const
Converts a length measurement from the layout's native units to a specified target unit...
Alignment
Alignment options.
Distribute vertical equispaced.
Distribute horizontal centers.
void endMacro()
Ends a macro command.
This class provides a method of storing sizes, consisting of a width and height, for use in QGIS layo...
static void resizeItems(QgsLayout *layout, const QList< QgsLayoutItem * > &items, Resize resize)
Resizes a set of items from a layout in place.
Resize width to match narrowest width.