rip off amberol

This commit is contained in:
Erica Z 2024-11-13 22:28:49 +01:00
parent a25333ec79
commit 641161c059
4 changed files with 76 additions and 22 deletions

25
Cargo.lock generated
View file

@ -221,6 +221,7 @@ dependencies = [
"bindgen",
"bytes",
"chrono",
"color-thief",
"event-listener",
"futures",
"gettext-rs",
@ -334,6 +335,12 @@ version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytemuck"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d"
[[package]]
name = "byteorder"
version = "1.5.0"
@ -455,6 +462,15 @@ dependencies = [
"libloading",
]
[[package]]
name = "color-thief"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6460d760cf38ce67c9e0318f896538820acc54f2d0a3bfc5b2c557211066c98"
dependencies = [
"rgb",
]
[[package]]
name = "concurrent-queue"
version = "2.5.0"
@ -2081,6 +2097,15 @@ dependencies = [
"windows-registry",
]
[[package]]
name = "rgb"
version = "0.8.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a"
dependencies = [
"bytemuck",
]
[[package]]
name = "ring"
version = "0.17.8"

View file

@ -8,6 +8,7 @@ adw = { version = "0.7.0", package = "libadwaita", features = ["v1_6"] }
async-channel = "2.3.1"
bytes = "1.8.0"
chrono = { version = "0.4.38", features = ["serde"] }
color-thief = "0.2.2"
event-listener = "5.3.1"
futures = "0.3.31"
gettext-rs = { version = "0.7.2", features = ["gettext-system"] }

View file

@ -1,3 +1,13 @@
window.background > * {
/* from amberol */
background: linear-gradient(127deg, color-mix(in srgb, var(--background-color-0) 55%, transparent), color-mix(in srgb, var(--background-color-0) 0%, transparent) 70.71%),
linear-gradient(217deg, color-mix(in srgb, var(--background-color-1) 55%, transparent), color-mix(in srgb, var(--background-color-1) 0%, transparent) 70.71%),
linear-gradient(336deg, color-mix(in srgb, var(--background-color-2) 55%, transparent), color-mix(in srgb, var(--background-color-2) 0%, transparent) 70.71%);
transition-property: background;
transition-duration: 250ms;
transition-timing-function: ease;
}
#seek-scale slider {
margin: 0px;
opacity: 0%;

View file

@ -87,6 +87,8 @@ mod imp {
#[property(get, set)]
refreshing_albums: Cell<bool>,
css_provider: gtk::CssProvider,
}
impl Default for Window {
@ -146,6 +148,8 @@ mod imp {
mpris_player: Default::default(),
refreshing_albums: Cell::new(true),
css_provider: gtk::CssProvider::new(),
}
}
}
@ -171,6 +175,10 @@ mod imp {
fn constructed(&self) {
self.parent_constructed();
if let Some(display) = gdk::Display::default() {
gtk::style_context_add_provider_for_display(&display, &self.css_provider, 420);
}
use gio::ActionEntry;
let action_seek_backward = ActionEntry::builder("seek-backward")
@ -671,32 +679,41 @@ mod imp {
match window.song() {
Some(song) if song.id() == song_id => {
let texture = gdk::Texture::from_bytes(&glib::Bytes::from_owned(bytes))
.expect("could not create texture from cover art for {song_id}");
let loader = gtk::gdk_pixbuf::PixbufLoader::new(); // TODO: pass mime type?
loader.write(&bytes).unwrap();
loader.close().unwrap();
let pixbuf = loader.pixbuf().unwrap();
let texture = gdk::Texture::for_pixbuf(&pixbuf);
window.set_playing_cover_art(Some(&texture.clone().into()));
// from g4music
let snapshot = gtk::Snapshot::new();
snapshot.push_blur(512.0 * 0.1);
snapshot.push_opacity(0.5);
texture.snapshot(&snapshot, 512.0, 512.0);
snapshot.pop();
snapshot.pop();
use gtk::graphene;
let rect = graphene::Rect::new(0.0, 0.0, 512.0, 512.0);
if let Some(node) = snapshot.clone().to_node() {
window.set_background(Some(
window
.native()
.unwrap()
.renderer()
.unwrap()
.render_texture(node, Some(&rect)),
));
// from amberol
let palette = color_thief::get_palette(
pixbuf.pixel_bytes().unwrap().as_ref(),
if pixbuf.has_alpha() {
color_thief::ColorFormat::Rgba
} else {
todo!();
color_thief::ColorFormat::Rgb
},
5,
4,
)
.unwrap();
let mut css = String::new();
css.push_str(":root {");
let n_colors = palette.len();
for (i, color) in palette.into_iter().enumerate() {
css.push_str(&format!("--background-color-{i}: {color}; "));
}
for i in n_colors..3 {
css.push_str(&format!(
"--background-color-{i}: var(--window-bg-color); "
));
}
css.push_str("}");
window.imp().css_provider.load_from_string(&css);
}
_ => {
event!(
@ -762,6 +779,7 @@ mod imp {
match self.state.get() {
State::Active => {}
State::FileLoading => {}
State::FileLoaded => {}
State::Seeking => {}
other => panic!("invalid state transition: EndFile from {other:?}"),