Spread several dropped pictures over the folio in a grid

Pictures dropped together were cascaded 20 px apart from the drop
point; once scaled to fit the folio they lay almost on top of each
other. They are now laid out side by side in a roughly square grid
over the folio's drawing area, inside the same 20 % margin, each
shrunk into its cell with its proportions kept. A single dropped
picture still lands on the drop point.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Beat Hangartner
2026-10-04 23:08:23 +02:00
parent c76bc5eb4e
commit 360065036c
4 changed files with 128 additions and 30 deletions
+22 -2
View File
@@ -24,6 +24,7 @@
#include <QUrl>
#include <algorithm>
#include <cmath>
namespace
{
@@ -119,7 +120,26 @@ QRectF ImageDrop::keepInside(const QRectF &picture, const QRectF &area)
return result;
}
QPointF ImageDrop::cascadeOffset(int index)
QList<QRectF> ImageDrop::gridLayout(const QList<QSizeF> &sizes, const QRectF &area)
{
return QPointF(cascadeStep * index, cascadeStep * index);
QList<QRectF> rects;
const int count = int(sizes.size());
if (count == 0)
return rects;
const int columns = int(std::ceil(std::sqrt(qreal(count))));
const int rows = (count + columns - 1) / columns;
const QSizeF cell(area.width() / columns, area.height() / rows);
const QSizeF room = cell * (1.0 - gridGap);
for (int i = 0; i < count; ++i)
{
const QSizeF size = sizes.at(i);
qreal scale = 1.0;
if (!size.isEmpty() && !room.isEmpty())
scale = std::min({1.0, room.width() / size.width(), room.height() / size.height()});
QRectF r(QPointF(), size * scale);
r.moveCenter(area.topLeft() + QPointF(cell.width() * (i % columns + 0.5),
cell.height() * (i / columns + 0.5)));
rects << r;
}
return rects;
}