forked from Shinonome/dots-hyprland
sidebar: booru: better image layout
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user