booru: better layout when expanded

This commit is contained in:
end-4
2025-05-06 11:23:52 +02:00
parent e38a0bdac7
commit 418ac5da0c
2 changed files with 44 additions and 29 deletions
@@ -118,7 +118,6 @@ Scope { // Scope
sidebarRoot.currentTab = (sidebarRoot.currentTab - 1 + root.tabButtonList.length) % root.tabButtonList.length; sidebarRoot.currentTab = (sidebarRoot.currentTab - 1 + root.tabButtonList.length) % root.tabButtonList.length;
} }
else if (event.key === Qt.Key_O) { else if (event.key === Qt.Key_O) {
console.log("Extending sidebar")
sidebarRoot.extend = !sidebarRoot.extend; sidebarRoot.extend = !sidebarRoot.extend;
} }
event.accepted = true; event.accepted = true;
@@ -23,7 +23,7 @@ Rectangle {
property string nsfwPath property string nsfwPath
property real availableWidth: parent.width property real availableWidth: parent.width
property real rowTooShortThreshold: 185 property real rowTooShortThreshold: 190
property real imageSpacing: 5 property real imageSpacing: 5
property real responsePadding: 5 property real responsePadding: 5
@@ -103,7 +103,6 @@ Rectangle {
visible: root.responseData.tags.length > 0 visible: root.responseData.tags.length > 0
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft
Layout.fillWidth: { Layout.fillWidth: {
console.log(root.responseData)
return true return true
} }
implicitHeight: tagRowLayout.implicitHeight implicitHeight: tagRowLayout.implicitHeight
@@ -181,42 +180,59 @@ Rectangle {
Repeater { Repeater {
model: ScriptModel { model: ScriptModel {
values: { values: {
// Group two images every row, ensuring they are of the same height // Greedily add images to a row as long as rowHeight >= rowTooShortThreshold
// If the height ends up being too small, put one image in the row and continue
// In other words, this is similar to Android's gallery layout at largest zoom level
let i = 0; let i = 0;
let rows = []; let rows = [];
const responseList = root.responseData.images; const responseList = root.responseData.images;
const minRowHeight = rowTooShortThreshold;
const availableImageWidth = availableWidth - root.imageSpacing - (responsePadding * 2);
while (i < responseList.length) { while (i < responseList.length) {
let row = { let row = {
height: 0, height: 0,
images: [], images: [],
}; };
const availableImageWidth = availableWidth - root.imageSpacing - (responsePadding * 2) let j = i;
if (i + 1 < responseList.length) { let combinedAspect = 0;
const img1 = responseList[i]; let rowHeight = 0;
const img2 = responseList[i + 1];
// Calculate combined height if both are in the same row // Try to add as many images as possible without going below minRowHeight
// Let h = row height, w1 = h * aspect1, w2 = h * aspect2 while (j < responseList.length) {
// w1 + w2 = availableWidth => h = availableWidth / (aspect1 + aspect2) combinedAspect += responseList[j].aspect_ratio;
const combinedAspect = img1.aspect_ratio + img2.aspect_ratio; // Subtract imageSpacing for each gap between images in the row
const rowHeight = availableImageWidth / combinedAspect; let imagesInRow = j - i + 1;
if (rowHeight >= rowTooShortThreshold) { let totalSpacing = root.imageSpacing * (imagesInRow - 1);
row.height = rowHeight; let rowAvailableWidth = availableImageWidth - totalSpacing;
row.images.push(img1); rowHeight = rowAvailableWidth / combinedAspect;
row.images.push(img2); if (rowHeight < minRowHeight) {
rows.push(row); combinedAspect -= responseList[j].aspect_ratio;
i += 2; imagesInRow -= 1;
continue; totalSpacing = root.imageSpacing * (imagesInRow - 1);
rowAvailableWidth = availableImageWidth - totalSpacing;
rowHeight = rowAvailableWidth / combinedAspect;
break;
} }
j++;
}
// If we couldn't add any image (shouldn't happen), add at least one
if (j === i) {
row.images.push(responseList[i]);
row.height = availableImageWidth / responseList[i].aspect_ratio;
rows.push(row);
i++;
} else {
for (let k = i; k < j; k++) {
row.images.push(responseList[k]);
}
// Recalculate spacing for the final row
let imagesInRow = j - i;
let totalSpacing = root.imageSpacing * (imagesInRow - 1);
let rowAvailableWidth = availableImageWidth - totalSpacing;
row.height = rowAvailableWidth / combinedAspect;
rows.push(row);
i = j;
} }
// Otherwise, put only one image in the row
const rowHeight = (availableWidth - (responsePadding * 2)) / responseList[i].aspect_ratio;
rows.push({
height: rowHeight,
images: [responseList[i]],
});
i += 1;
} }
return rows; return rows;
} }