sidebar: booru: better image layout

This commit is contained in:
end-4
2024-04-02 21:55:36 +07:00
parent 516d24117c
commit 2dd100c5d9
3 changed files with 58 additions and 41 deletions
+57 -40
View File
@@ -160,26 +160,11 @@ const BooruPage = (taglist) => {
const imagePath = `${USER_CACHE_DIR}/ags/media/waifus/${data.md5}.${data.file_ext}`; const imagePath = `${USER_CACHE_DIR}/ags/media/waifus/${data.md5}.${data.file_ext}`;
const widgetStyleContext = imageArea.get_style_context(); const widgetStyleContext = imageArea.get_style_context();
const widgetWidth = widgetStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL); const widgetWidth = widgetStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const widgetHeight = widgetStyleContext.get_property('min-height', Gtk.StateFlags.NORMAL); const widgetHeight = widgetWidth / data.aspect_ratio;
imageArea.set_size_request(widgetWidth, widgetHeight); imageArea.set_size_request(widgetWidth, widgetHeight);
const showImage = () => { const showImage = () => {
const imageDimensionsStr = exec(`identify -format {\\"w\\":%w,\\"h\\":%h} '${imagePath}'`)
const imageDimensionsJson = JSON.parse(imageDimensionsStr);
let imageWidth = imageDimensionsJson.w;
let imageHeight = imageDimensionsJson.h;
// Fill
const scale = imageWidth / imageHeight;
if (imageWidth > imageHeight) {
imageWidth = widgetHeight * scale;
imageHeight = widgetHeight;
} else {
imageHeight = widgetWidth / scale;
imageWidth = widgetWidth;
}
// const pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(imagePath, widgetWidth, widgetHeight); // const pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(imagePath, widgetWidth, widgetHeight);
const pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(imagePath, imageWidth, imageHeight, false); const pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(imagePath, widgetWidth, widgetHeight, false);
imageArea.connect("draw", (widget, cr) => { imageArea.connect("draw", (widget, cr) => {
const borderRadius = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL); const borderRadius = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
@@ -192,7 +177,7 @@ const BooruPage = (taglist) => {
cr.clip(); cr.clip();
// Paint image as bg // Paint image as bg
Gdk.cairo_set_source_pixbuf(cr, pixbuf, (widgetWidth - imageWidth) / 2, (widgetHeight - imageHeight) / 2); Gdk.cairo_set_source_pixbuf(cr, pixbuf, (widgetWidth - widgetWidth) / 2, (widgetHeight - widgetHeight) / 2);
cr.paint(); cr.paint();
}); });
self.queue_draw(); self.queue_draw();
@@ -271,16 +256,15 @@ const BooruPage = (taglist) => {
downloadIndicator, downloadIndicator,
] ]
}); });
const pageImageGrid = Grid({ const pageImages = Box({
// columnHomogeneous: true, homogeneous: true,
// rowHomogeneous: true,
className: 'sidebar-booru-imagegrid', className: 'sidebar-booru-imagegrid',
}); })
const pageImageRevealer = Revealer({ const pageImageRevealer = Revealer({
transition: 'slide_down', transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge, transitionDuration: userOptions.animations.durationLarge,
revealChild: false, revealChild: false,
child: pageImageGrid, child: pageImages,
}); });
const thisPage = Box({ const thisPage = Box({
homogeneous: true, homogeneous: true,
@@ -288,27 +272,62 @@ const BooruPage = (taglist) => {
attribute: { attribute: {
'imagePath': '', 'imagePath': '',
'isNsfw': false, 'isNsfw': false,
'imageData': '', 'update': (data, force = false) => { // TODO: Use columns. Sort min to max h/w ratio then greedily put em in...
'update': (data, force = false) => { // Sort by .aspect_ratio
const imageData = data; data = data.sort(
thisPage.attribute.imageData = imageData; (a, b) => a.aspect_ratio - b.aspect_ratio
);
if (data.length == 0) { if (data.length == 0) {
downloadState.shown = 'error'; downloadState.shown = 'error';
return; return;
} }
const imageColumns = userOptions.sidebar.imageColumns; const imageColumns = userOptions.sidebar.imageColumns;
const imageRows = data.length / imageColumns; const imageRows = data.length / imageColumns;
// Add stuff
for (let i = 0; i < imageRows; i++) { // Init cols
pageImages.children = Array.from(
{ length: imageColumns },
(_, i) => Box({
attribute: { height: 0 },
vertical: true,
})
);
// Greedy add O(n^2) 😭
for (let i = 0; i < data.length; i++) {
// Find column with lowest length
let minHeight = Infinity;
let minIndex = -1;
for (let j = 0; j < imageColumns; j++) { for (let j = 0; j < imageColumns; j++) {
if (i * imageColumns + j >= Math.min(userOptions.sidebar.imageBooruCount, data.length)) break; const height = pageImages.children[j].attribute.height;
pageImageGrid.attach( if (height < minHeight) {
PreviewImage(data[i * imageColumns + j]), minHeight = height;
j, i, 1, 1 minIndex = j;
); }
} }
// Add image to it
pageImages.children[minIndex].pack_start(PreviewImage(data[i], minIndex), false, false, 0)
pageImages.children[minIndex].attribute.height += 1 / data[i].aspect_ratio; // we want height/width
} }
pageImageGrid.show_all(); // Show all
// for(let i = 0; i < imageColumns; i++) {
// pageImages.children[i].show_all();
// }
pageImages.show_all();
// each image: PreviewImage(data[i * imageColumns + j])
// Add stuff
// for (let i = 0; i < imageRows; i++) {
// for (let j = 0; j < imageColumns; j++) {
// if (i * imageColumns + j >= Math.min(userOptions.sidebar.imageBooruCount, data.length)) break;
// pageImages.attach(
// PreviewImage(data[i * imageColumns + j]),
// j, i, 1, 1
// );
// }
// }
pageImages.show_all();
// Reveal stuff // Reveal stuff
Utils.timeout(IMAGE_REVEAL_DELAY, Utils.timeout(IMAGE_REVEAL_DELAY,
@@ -348,10 +367,8 @@ const booruContent = Box({
}, 'newResponse') }, 'newResponse')
.hook(BooruService, (box, id) => { .hook(BooruService, (box, id) => {
if (id === undefined) return; if (id === undefined) return;
const data = BooruService.responses[id]; if (!BooruService.responses[id]) return;
if (!data) return; box.attribute.map.get(id)?.attribute.update(BooruService.responses[id]);
const page = box.attribute.map.get(id);
page?.attribute.update(data);
}, 'updateResponse') }, 'updateResponse')
, ,
}); });
@@ -376,7 +393,7 @@ export const booruView = Scrollable({
const viewport = scrolledWindow.child; const viewport = scrolledWindow.child;
viewport.set_focus_vadjustment(new Gtk.Adjustment(undefined)); viewport.set_focus_vadjustment(new Gtk.Adjustment(undefined));
}) })
// Always scroll to bottom with new content // Scroll to bottom with new content if chat entry not focused
const adjustment = scrolledWindow.get_vadjustment(); const adjustment = scrolledWindow.get_vadjustment();
adjustment.connect("changed", () => { adjustment.connect("changed", () => {
if (!chatEntry.hasFocus) return; if (!chatEntry.hasFocus) return;
-1
View File
@@ -829,7 +829,6 @@ $waifu_image_overlay_transparency: 0.7;
@include small-rounding; @include small-rounding;
margin: 0.273rem; margin: 0.273rem;
min-width: 11.932rem; min-width: 11.932rem;
min-height: 11.932rem;
// background-color: rgba(100, 200, 0, 0.3); // background-color: rgba(100, 200, 0, 0.3);
} }
+1
View File
@@ -107,6 +107,7 @@ class BooruService extends Service {
// console.log(parsedData) // console.log(parsedData)
this._responses.push(parsedData.map(obj => { this._responses.push(parsedData.map(obj => {
return { return {
aspect_ratio: obj.width / obj.height,
id: obj.id, id: obj.id,
tags: obj.tags, tags: obj.tags,
md5: obj.md5, md5: obj.md5,