use cairo instead of css for waifu images

major memory improvement woo
This commit is contained in:
end-4 2024-01-07 10:28:15 +07:00
parent 1ce492579b
commit d21cfa628a

View file

@ -1,6 +1,6 @@
const { Gdk, Gio, GLib, Gtk, Pango } = imports.gi; const { Gdk, GdkPixbuf, Gio, GLib, Gtk, Pango } = imports.gi;
import { App, Utils, Widget } from '../../../imports.js'; import { App, Utils, Widget } from '../../../imports.js';
const { Box, Button, Entry, EventBox, Icon, Label, Revealer, Scrollable, Stack } = Widget; const { Box, Button, Entry, EventBox, Icon, Label, Overlay, Revealer, Scrollable, Stack } = Widget;
const { execAsync, exec } = Utils; const { execAsync, exec } = Utils;
import { MaterialIcon } from "../../../lib/materialicon.js"; import { MaterialIcon } from "../../../lib/materialicon.js";
import { MarginRevealer } from '../../../lib/advancedwidgets.js'; import { MarginRevealer } from '../../../lib/advancedwidgets.js';
@ -83,49 +83,58 @@ const WaifuImage = (taglist) => {
downloadIndicator, downloadIndicator,
] ]
}); });
const blockImageActions = Box({ const blockImageActions = Revealer({
className: 'sidebar-waifu-image-actions spacing-h-3', transition: 'crossfade',
children: [ revealChild: false,
Box({ hexpand: true }), child: Box({
ImageAction({ vertical: true,
name: 'Go to source', children: [
icon: 'link', Box({
action: () => execAsync(['xdg-open', `${thisBlock._imageData.source}`]).catch(print), className: 'sidebar-waifu-image-actions spacing-h-3',
}), children: [
ImageAction({ Box({ hexpand: true }),
name: 'Hoard', ImageAction({
icon: 'save', name: 'Go to source',
action: () => execAsync(['bash', '-c', `mkdir -p ~/Pictures/waifus && cp ${thisBlock._imagePath} ~/Pictures/waifus`]).catch(print), icon: 'link',
}), action: () => execAsync(['xdg-open', `${thisBlock._imageData.source}`]).catch(print),
ImageAction({ }),
name: 'Open externally', ImageAction({
icon: 'open_in_new', name: 'Hoard',
action: () => execAsync(['xdg-open', `${thisBlock._imagePath}`]).catch(print), icon: 'save',
}), action: () => execAsync(['bash', '-c', `mkdir -p ~/Pictures/waifus && cp ${thisBlock._imagePath} ~/Pictures/waifus`]).catch(print),
] }),
}) ImageAction({
const blockImage = Box({ name: 'Open externally',
className: 'test', icon: 'open_in_new',
hpack: 'start', action: () => execAsync(['xdg-open', `${thisBlock._imagePath}`]).catch(print),
vertical: true, }),
className: 'sidebar-waifu-image', ]
homogeneous: true,
children: [
Revealer({
transition: 'crossfade',
revealChild: false,
child: Box({
vertical: true,
children: [blockImageActions],
}) })
}) ],
] })
}) })
const blockImage = Widget.DrawingArea({
className: 'sidebar-waifu-image',
});
// const blockImage = Box({});
// const blockImage = Image({
// hpack: 'start',
// vertical: true,
// className: 'sidebar-waifu-image',
// // homogeneous: true,
// })
const blockImageRevealer = Revealer({ const blockImageRevealer = Revealer({
transition: 'slide_down', transition: 'slide_down',
transitionDuration: 150, transitionDuration: 150,
revealChild: false, revealChild: false,
child: blockImage, child: Overlay({
child: Box({
homogeneous: true,
className: 'sidebar-waifu-image',
children: [blockImage],
}),
overlays: [blockImageActions],
}),
}); });
const thisBlock = Box({ const thisBlock = Box({
className: 'sidebar-chat-message', className: 'sidebar-chat-message',
@ -141,29 +150,48 @@ const WaifuImage = (taglist) => {
} }
thisBlock._imagePath = `${GLib.get_user_cache_dir()}/ags/media/waifus/${signature}${extension}`; thisBlock._imagePath = `${GLib.get_user_cache_dir()}/ags/media/waifus/${signature}${extension}`;
downloadState.shown = 'download'; downloadState.shown = 'download';
// Width allocation // Width/height
const widgetWidth = Math.min(Math.floor(waifuContent.get_allocated_width() * 0.75), width); const widgetWidth = Math.min(Math.floor(waifuContent.get_allocated_width() * 0.85), width);
blockImage.set_size_request(widgetWidth, Math.ceil(widgetWidth * height / width)); const widgetHeight = Math.ceil(widgetWidth * height / width);
// Start download blockImage.set_size_request(widgetWidth, widgetHeight);
const showImage = () => { const showImage = () => {
downloadState.shown = 'done'; downloadState.shown = 'done';
// blockImage.css = `background-color: ${dominant_color};`; const pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(thisBlock._imagePath, widgetWidth, widgetHeight, false);
blockImage.css = `background-image:url('${thisBlock._imagePath}');`; // TODO: use proper image widget
blockImage.set_size_request(widgetWidth, widgetHeight);
blockImage.connect("draw", (widget, cr) => {
const borderRadius = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
// Draw a rounded rectangle
cr.arc(borderRadius, borderRadius, borderRadius, Math.PI, 1.5 * Math.PI);
cr.arc(widgetWidth - borderRadius, borderRadius, borderRadius, 1.5 * Math.PI, 2 * Math.PI);
cr.arc(widgetWidth - borderRadius, widgetHeight - borderRadius, borderRadius, 0, 0.5 * Math.PI);
cr.arc(borderRadius, widgetHeight - borderRadius, borderRadius, 0.5 * Math.PI, Math.PI);
cr.closePath();
cr.clip();
// Paint image as bg
Gdk.cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
cr.paint();
});
// Reveal stuff
Utils.timeout(IMAGE_REVEAL_DELAY, () => { Utils.timeout(IMAGE_REVEAL_DELAY, () => {
blockImageRevealer.revealChild = true; blockImageRevealer.revealChild = true;
}) })
Utils.timeout(IMAGE_REVEAL_DELAY + blockImageRevealer.transitionDuration, Utils.timeout(IMAGE_REVEAL_DELAY + blockImageRevealer.transitionDuration,
() => blockImage.get_children()[0].revealChild = true () => blockImageActions.revealChild = true
); );
downloadIndicator._hide(); downloadIndicator._hide();
} }
// Show
if (!force && fileExists(thisBlock._imagePath)) showImage(); if (!force && fileExists(thisBlock._imagePath)) showImage();
else Utils.execAsync(['bash', '-c', `wget -O '${thisBlock._imagePath}' '${url}'`]) else Utils.execAsync(['bash', '-c', `wget -O '${thisBlock._imagePath}' '${url}'`])
.then(showImage) .then(showImage)
.catch(print); .catch(print);
blockHeading.get_children().forEach((child) => { blockHeading.get_children().forEach((child) => {
child.setCss(`border-color: ${dominant_color};`); child.setCss(`border-color: ${dominant_color};`);
}) })
colorIndicator.css = `background-color: ${dominant_color};`; colorIndicator.css = `background-color: ${dominant_color};`;
}], }],
], ],
@ -176,6 +204,7 @@ const WaifuImage = (taglist) => {
blockHeading, blockHeading,
Box({ Box({
vertical: true, vertical: true,
hpack: 'start',
children: [blockImageRevealer], children: [blockImageRevealer],
}) })
] ]