warns and clips
This commit is contained in:
parent
f2f6c67383
commit
b7f42bce44
6 changed files with 51 additions and 110 deletions
|
@ -136,6 +136,8 @@ template $AudreyUiWindow: Adw.ApplicationWindow {
|
||||||
volume: bind template.volume bidirectional;
|
volume: bind template.volume bidirectional;
|
||||||
mute: bind template.mute bidirectional;
|
mute: bind template.mute bidirectional;
|
||||||
pause: bind template.pause bidirectional;
|
pause: bind template.pause bidirectional;
|
||||||
|
position: bind template.time-pos;
|
||||||
|
duration: bind template.song as <$AudreyPlaybinSong>.duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,10 @@ impl Error {
|
||||||
.to_str()
|
.to_str()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_property_unavailable(self) -> bool {
|
||||||
|
self.0 == ffi::mpv_error_MPV_ERROR_PROPERTY_UNAVAILABLE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
|
|
|
@ -2,11 +2,9 @@ pub mod song;
|
||||||
pub use song::Song;
|
pub use song::Song;
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
use crate::{Playbin, PlaybinSong};
|
|
||||||
use adw::{gio, glib, prelude::*, subclass::prelude::*};
|
use adw::{gio, glib, prelude::*, subclass::prelude::*};
|
||||||
use glib::{subclass::InitializingObject, WeakRef};
|
use glib::{subclass::InitializingObject, WeakRef};
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
|
||||||
use tracing::{event, Level};
|
use tracing::{event, Level};
|
||||||
|
|
||||||
#[derive(gtk::CompositeTemplate, glib::Properties, Default)]
|
#[derive(gtk::CompositeTemplate, glib::Properties, Default)]
|
||||||
|
@ -100,11 +98,8 @@ mod imp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::Playbin;
|
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use adw::subclass::prelude::*;
|
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct PlayQueue(ObjectSubclass<imp::PlayQueue>)
|
pub struct PlayQueue(ObjectSubclass<imp::PlayQueue>)
|
||||||
|
|
|
@ -172,8 +172,6 @@ mod imp {
|
||||||
|
|
||||||
use crate::PlaybinSong;
|
use crate::PlaybinSong;
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use adw::subclass::prelude::*;
|
|
||||||
use glib::Object;
|
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
|
|
|
@ -145,15 +145,7 @@ mod imp {
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
fn on_play_pause_clicked(&self, _button: >k::Button) {
|
fn on_play_pause_clicked(&self, _button: >k::Button) {
|
||||||
/*
|
self.window().set_pause(!self.window().pause());
|
||||||
let playbin = self.playbin.upgrade().unwrap();
|
|
||||||
|
|
||||||
if playbin.state() == crate::playbin::State::Playing {
|
|
||||||
playbin.pause();
|
|
||||||
} else {
|
|
||||||
playbin.play();
|
|
||||||
}*/
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
|
|
134
src/ui/window.rs
134
src/ui/window.rs
|
@ -44,6 +44,8 @@ mod imp {
|
||||||
_pause: (),
|
_pause: (),
|
||||||
#[property(type = i64, get = Self::playlist_pos)]
|
#[property(type = i64, get = Self::playlist_pos)]
|
||||||
_playlist_pos: (),
|
_playlist_pos: (),
|
||||||
|
#[property(type = f64, get = Self::time_pos)]
|
||||||
|
_time_pos: (),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Window {
|
impl Default for Window {
|
||||||
|
@ -78,6 +80,7 @@ mod imp {
|
||||||
_mute: (),
|
_mute: (),
|
||||||
_pause: (),
|
_pause: (),
|
||||||
_playlist_pos: (),
|
_playlist_pos: (),
|
||||||
|
_time_pos: (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,7 +138,18 @@ mod imp {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
|
|
||||||
mpv::Event::Hook(event) => match event.reply_userdata {
|
Event::StartFile(_) => {
|
||||||
|
let song: PlaybinSong = window
|
||||||
|
.playlist_model()
|
||||||
|
.item(window.playlist_pos() as u32)
|
||||||
|
.unwrap()
|
||||||
|
.dynamic_cast()
|
||||||
|
.unwrap();
|
||||||
|
window.set_song(Some(&song));
|
||||||
|
// TODO: load cover art
|
||||||
|
}
|
||||||
|
|
||||||
|
Event::Hook(event) => match event.reply_userdata {
|
||||||
0 => {
|
0 => {
|
||||||
assert_eq!(&event.name, "on_before_start_file");
|
assert_eq!(&event.name, "on_before_start_file");
|
||||||
event!(Level::DEBUG, "on_before_start_file triggered");
|
event!(Level::DEBUG, "on_before_start_file triggered");
|
||||||
|
@ -182,7 +196,7 @@ mod imp {
|
||||||
crate::mpris::Player::setup(conn.object_server(), &window.imp().playbin)
|
crate::mpris::Player::setup(conn.object_server(), &window.imp().playbin)
|
||||||
.await
|
.await
|
||||||
.expect("could not serve mpris player");
|
.expect("could not serve mpris player");
|
||||||
*/
|
FIXME */
|
||||||
|
|
||||||
drop(window); // don't keep this alive
|
drop(window); // don't keep this alive
|
||||||
|
|
||||||
|
@ -191,6 +205,19 @@ mod imp {
|
||||||
.await
|
.await
|
||||||
.expect("could not register name in session bus");
|
.expect("could not register name in session bus");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// notify of new time-pos every 100 ms
|
||||||
|
glib::source::timeout_add_local(std::time::Duration::from_millis(100), {
|
||||||
|
let window = self.obj().downgrade();
|
||||||
|
move || {
|
||||||
|
let window = match window.upgrade() {
|
||||||
|
None => return glib::ControlFlow::Break,
|
||||||
|
Some(window) => window,
|
||||||
|
};
|
||||||
|
window.notify("time-pos");
|
||||||
|
glib::ControlFlow::Continue
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,10 +243,12 @@ mod imp {
|
||||||
self.mpv.command(["stop"]).unwrap();
|
self.mpv.command(["stop"]).unwrap();
|
||||||
self.playlist_model.remove_all();
|
self.playlist_model.remove_all();
|
||||||
|
|
||||||
|
let api = {
|
||||||
let api = self.api.borrow();
|
let api = self.api.borrow();
|
||||||
let api = api.as_ref().unwrap();
|
Rc::clone(api.as_ref().unwrap())
|
||||||
|
};
|
||||||
for song in api.get_random_songs(10).await.unwrap().into_iter() {
|
for song in api.get_random_songs(10).await.unwrap().into_iter() {
|
||||||
let song = PlaybinSong::from_child(api, &song);
|
let song = PlaybinSong::from_child(&api, &song);
|
||||||
self.mpv
|
self.mpv
|
||||||
.command(["loadfile", &song.stream_url(), "append-play"])
|
.command(["loadfile", &song.stream_url(), "append-play"])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -233,35 +262,6 @@ mod imp {
|
||||||
self.setup.present(Some(self.obj().as_ref()));
|
self.setup.present(Some(self.obj().as_ref()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn now_playing(&self, _song: &PlaybinSong) {
|
|
||||||
/*
|
|
||||||
this.song = song;
|
|
||||||
// api.scrobble.begin (this.song.id); TODO
|
|
||||||
|
|
||||||
if (this.cancel_loading_art != null) {
|
|
||||||
this.cancel_loading_art.cancel ();
|
|
||||||
}
|
|
||||||
this.cancel_loading_art = new GLib.Cancellable ();
|
|
||||||
|
|
||||||
this.playing_cover_art = null; // TODO: preload next art somehow
|
|
||||||
this.cover_art_loading = true;
|
|
||||||
|
|
||||||
string song_id = this.song.id;
|
|
||||||
this.api.cover_art.begin (song_id, -1, Priority.DEFAULT, this.cancel_loading_art, (obj, res) => {
|
|
||||||
try {
|
|
||||||
this.playing_cover_art = Gdk.Texture.for_pixbuf (this.api.cover_art.end (res));
|
|
||||||
this.cover_art_loading = false;
|
|
||||||
} catch (Error e) {
|
|
||||||
if (!(e is IOError.CANCELLED)) {
|
|
||||||
warning ("could not load cover for %s: %s", song_id, e.message);
|
|
||||||
this.cover_art_loading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn volume(&self) -> i64 {
|
fn volume(&self) -> i64 {
|
||||||
self.mpv.get_property("volume").unwrap()
|
self.mpv.get_property("volume").unwrap()
|
||||||
}
|
}
|
||||||
|
@ -289,6 +289,15 @@ mod imp {
|
||||||
fn playlist_pos(&self) -> i64 {
|
fn playlist_pos(&self) -> i64 {
|
||||||
self.mpv.get_property("playlist-pos").unwrap()
|
self.mpv.get_property("playlist-pos").unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn time_pos(&self) -> f64 {
|
||||||
|
match self.mpv.get_property("time-pos") {
|
||||||
|
Ok(time_pos) => Ok(time_pos),
|
||||||
|
Err(err) if err.is_property_unavailable() => Ok(0.0), //placeholder
|
||||||
|
Err(err) => Err(err),
|
||||||
|
}
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Window {
|
impl Drop for Window {
|
||||||
|
@ -312,53 +321,6 @@ impl Window {
|
||||||
pub fn new(app: &impl IsA<gtk::Application>) -> Self {
|
pub fn new(app: &impl IsA<gtk::Application>) -> Self {
|
||||||
let window: Self = glib::Object::builder().property("application", app).build();
|
let window: Self = glib::Object::builder().property("application", app).build();
|
||||||
|
|
||||||
// manual bidirectional sync
|
|
||||||
/*
|
|
||||||
window
|
|
||||||
.imp()
|
|
||||||
.playbar
|
|
||||||
.set_volume(window.imp().mpv.get_property::<i64>("volume") as i32);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
window.imp().playbar.set_mute(window.imp().playbin.muted());
|
|
||||||
window.imp().playbar.connect_notify_local(
|
|
||||||
Some("mute"),
|
|
||||||
glib::clone!(
|
|
||||||
#[weak(rename_to = playbin)]
|
|
||||||
window.imp().playbin,
|
|
||||||
move |playbar, _| playbin.set_muted(playbar.mute())
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
window.imp().playbin.file_started().connect_object(
|
|
||||||
&*window.imp().playbar,
|
|
||||||
|playbin, playbar, ()| {
|
|
||||||
let entry = &playbin.entries()[playbin.current_entry().unwrap()];
|
|
||||||
playbar.set_duration(entry.duration() as f64);
|
|
||||||
true
|
|
||||||
},
|
|
||||||
);*/
|
|
||||||
|
|
||||||
// update position every 100 ms
|
|
||||||
/*
|
|
||||||
glib::source::timeout_add_local(std::time::Duration::from_millis(100), {
|
|
||||||
let playbar = window.imp().playbar.downgrade();
|
|
||||||
let playbin = Rc::downgrade(&window.imp().playbin);
|
|
||||||
move || {
|
|
||||||
let playbar = match playbar.upgrade() {
|
|
||||||
None => return glib::ControlFlow::Break,
|
|
||||||
Some(playbar) => playbar,
|
|
||||||
};
|
|
||||||
let playbin = match playbin.upgrade() {
|
|
||||||
None => return glib::ControlFlow::Break,
|
|
||||||
Some(playbin) => playbin,
|
|
||||||
};
|
|
||||||
playbar.set_position(playbin.position().unwrap_or(0.0));
|
|
||||||
glib::ControlFlow::Continue
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
window
|
window
|
||||||
.imp()
|
.imp()
|
||||||
.setup
|
.setup
|
||||||
|
@ -371,18 +333,6 @@ impl Window {
|
||||||
});
|
});
|
||||||
window.imp().setup.load();
|
window.imp().setup.load();
|
||||||
|
|
||||||
/*
|
|
||||||
window
|
|
||||||
.imp()
|
|
||||||
.playbin
|
|
||||||
.file_started()
|
|
||||||
.connect_object(&window, |playbin, window, ()| {
|
|
||||||
window
|
|
||||||
.imp()
|
|
||||||
.now_playing(&playbin.entries()[playbin.current_entry().unwrap()]);
|
|
||||||
true
|
|
||||||
});*/
|
|
||||||
|
|
||||||
window
|
window
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue