shits broken but i still gotta eat
This commit is contained in:
parent
e2902e862d
commit
ea31535bfb
6 changed files with 185 additions and 134 deletions
|
@ -119,6 +119,8 @@ template $AudreyUiWindow: Adw.ApplicationWindow {
|
||||||
margin-end: 24;
|
margin-end: 24;
|
||||||
|
|
||||||
styles [ "frame" ]
|
styles [ "frame" ]
|
||||||
|
model: bind template.playlist_model;
|
||||||
|
playlist-pos: bind template.playlist-pos;
|
||||||
//playbin: bind template.playbin;
|
//playbin: bind template.playbin;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -130,6 +132,10 @@ template $AudreyUiWindow: Adw.ApplicationWindow {
|
||||||
song: bind template.song;
|
song: bind template.song;
|
||||||
playing_cover_art: bind template.playing_cover_art;
|
playing_cover_art: bind template.playing_cover_art;
|
||||||
show_cover_art: bind $show_playbar_cover_art (stack.visible-child-name) as <bool>;
|
show_cover_art: bind $show_playbar_cover_art (stack.visible-child-name) as <bool>;
|
||||||
|
|
||||||
|
volume: bind template.volume bidirectional;
|
||||||
|
mute: bind template.mute bidirectional;
|
||||||
|
pause: bind template.pause bidirectional;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ impl Playbin {
|
||||||
"loadfile",
|
"loadfile",
|
||||||
&entry.stream_url(),
|
&entry.stream_url(),
|
||||||
"insert-at-play",
|
"insert-at-play",
|
||||||
index.to_string(),
|
&index.to_string(),
|
||||||
])
|
])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
entries.insert(index, entry);
|
entries.insert(index, entry);
|
||||||
|
|
|
@ -4,8 +4,8 @@ pub use song::Song;
|
||||||
mod imp {
|
mod imp {
|
||||||
use crate::{Playbin, PlaybinSong};
|
use crate::{Playbin, PlaybinSong};
|
||||||
use adw::{gio, glib, prelude::*, subclass::prelude::*};
|
use adw::{gio, glib, prelude::*, subclass::prelude::*};
|
||||||
use glib::subclass::InitializingObject;
|
use glib::{subclass::InitializingObject, WeakRef};
|
||||||
use std::cell::RefCell;
|
use std::cell::{Cell, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use tracing::{event, Level};
|
use tracing::{event, Level};
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@ mod imp {
|
||||||
#[properties(wrapper_type = super::PlayQueue)]
|
#[properties(wrapper_type = super::PlayQueue)]
|
||||||
pub struct PlayQueue {
|
pub struct PlayQueue {
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
pub(super) model: RefCell<Option<gio::ListStore>>,
|
pub(super) model: WeakRef<gio::ListModel>,
|
||||||
|
#[property(get, set)]
|
||||||
pub(super) playbin: RefCell<Option<Rc<Playbin>>>,
|
_playlist_pos: Cell<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
@ -39,8 +39,6 @@ mod imp {
|
||||||
impl ObjectImpl for PlayQueue {
|
impl ObjectImpl for PlayQueue {
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
|
|
||||||
self.obj().set_model(gio::ListStore::new::<PlaybinSong>());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,13 +59,17 @@ mod imp {
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
fn on_song_list_setup(&self, item: >k::ListItem, _factory: >k::SignalListItemFactory) {
|
fn on_song_list_setup(&self, item: >k::ListItem, _factory: >k::SignalListItemFactory) {
|
||||||
let child = super::Song::new(Some(&self.obj().window()));
|
let child: super::Song = glib::Object::new();
|
||||||
|
|
||||||
child.set_draggable(true);
|
child.set_draggable(true);
|
||||||
child.set_show_position(true);
|
child.set_show_position(true);
|
||||||
child.set_show_artist(true);
|
child.set_show_artist(true);
|
||||||
child.set_show_cover(true);
|
child.set_show_cover(true);
|
||||||
|
|
||||||
|
self.obj()
|
||||||
|
.bind_property("playlist-pos", &child, "playlist-pos")
|
||||||
|
.build();
|
||||||
|
|
||||||
item.set_child(Some(&child));
|
item.set_child(Some(&child));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,11 +89,7 @@ mod imp {
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
fn on_row_activated(&self, position: u32) {
|
fn on_row_activated(&self, position: u32) {
|
||||||
self.playbin
|
self.obj().window().play_index(position as i64);
|
||||||
.borrow()
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.play_entry(position as usize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,27 +113,6 @@ glib::wrapper! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlayQueue {
|
impl PlayQueue {
|
||||||
pub fn set_playbin(&self, playbin: &Rc<Playbin>) {
|
|
||||||
assert!(self
|
|
||||||
.imp()
|
|
||||||
.playbin
|
|
||||||
.replace(Some(Rc::clone(playbin)))
|
|
||||||
.is_none()); // only set once
|
|
||||||
|
|
||||||
playbin
|
|
||||||
.stopped()
|
|
||||||
.connect_object(self, |_playbin, play_queue, ()| {
|
|
||||||
play_queue.model().unwrap().remove_all();
|
|
||||||
true
|
|
||||||
});
|
|
||||||
playbin
|
|
||||||
.entry_removed()
|
|
||||||
.connect_object(self, |_playbin, play_queue, index| {
|
|
||||||
play_queue.model().unwrap().remove(index as u32);
|
|
||||||
true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn window(&self) -> crate::ui::Window {
|
fn window(&self) -> crate::ui::Window {
|
||||||
self.root().unwrap().dynamic_cast().unwrap()
|
self.root().unwrap().dynamic_cast().unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,9 @@ mod imp {
|
||||||
#[template(resource = "/eu/callcc/audrey/play_queue_song.ui")]
|
#[template(resource = "/eu/callcc/audrey/play_queue_song.ui")]
|
||||||
#[properties(wrapper_type = super::Song)]
|
#[properties(wrapper_type = super::Song)]
|
||||||
pub struct Song {
|
pub struct Song {
|
||||||
|
#[property(get, set = Self::set_playlist_pos)]
|
||||||
|
playlist_pos: Cell<i64>,
|
||||||
|
|
||||||
#[property(set, get)]
|
#[property(set, get)]
|
||||||
draggable: Cell<bool>,
|
draggable: Cell<bool>,
|
||||||
#[property(set, get)]
|
#[property(set, get)]
|
||||||
|
@ -57,11 +60,13 @@ mod imp {
|
||||||
#[weak(rename_to = self_)]
|
#[weak(rename_to = self_)]
|
||||||
self,
|
self,
|
||||||
move |_, _, _| {
|
move |_, _, _| {
|
||||||
|
/*
|
||||||
self_
|
self_
|
||||||
.obj()
|
.obj()
|
||||||
.window()
|
.window()
|
||||||
.playbin()
|
.playbin()
|
||||||
.remove_entry(self_.obj().displayed_position() as usize - 1)
|
.remove_entry(self_.obj().displayed_position() as usize - 1)*/
|
||||||
|
todo!()
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
|
@ -121,7 +126,7 @@ mod imp {
|
||||||
fn on_drag_begin(&self, drag: &gdk::Drag) {
|
fn on_drag_begin(&self, drag: &gdk::Drag) {
|
||||||
let drag_widget = gtk::ListBox::new();
|
let drag_widget = gtk::ListBox::new();
|
||||||
|
|
||||||
let drag_row = super::Song::new(None);
|
let drag_row: super::Song = glib::Object::new();
|
||||||
drag_row.set_draggable(false);
|
drag_row.set_draggable(false);
|
||||||
drag_row.set_show_position(self.obj().show_position());
|
drag_row.set_show_position(self.obj().show_position());
|
||||||
drag_row.set_show_artist(self.obj().show_artist());
|
drag_row.set_show_artist(self.obj().show_artist());
|
||||||
|
@ -160,10 +165,18 @@ mod imp {
|
||||||
true */
|
true */
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_playlist_pos(&self, playlist_pos: i64) {
|
||||||
|
self.playlist_pos.set(playlist_pos);
|
||||||
|
self.obj()
|
||||||
|
.set_current(playlist_pos == self.position.get() as i64);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use crate::PlaybinSong;
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
|
use adw::subclass::prelude::*;
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
|
||||||
|
@ -174,40 +187,21 @@ glib::wrapper! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Song {
|
impl Song {
|
||||||
pub fn new(window: Option<&crate::ui::Window>) -> Self {
|
|
||||||
let song: Self = Object::new();
|
|
||||||
|
|
||||||
if let Some(window) = window {
|
|
||||||
use crate::Event;
|
|
||||||
|
|
||||||
crate::event::spawn_object_listener(
|
|
||||||
window.receiver(),
|
|
||||||
&song,
|
|
||||||
|song, event| match event {
|
|
||||||
Event::PlaybinCurrentEntryChanged => {
|
|
||||||
song.set_current(
|
|
||||||
song.window().playbin().current_entry()
|
|
||||||
== Some(song.position() as usize),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
song
|
|
||||||
}
|
|
||||||
|
|
||||||
fn window(&self) -> crate::ui::Window {
|
fn window(&self) -> crate::ui::Window {
|
||||||
self.root().unwrap().dynamic_cast().unwrap()
|
self.root().unwrap().dynamic_cast().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bind(&self, position: u32, window: &crate::ui::Window) {
|
pub fn bind(&self, position: u32, window: &crate::ui::Window) {
|
||||||
|
let song: PlaybinSong = window
|
||||||
|
.playlist_model()
|
||||||
|
.item(position)
|
||||||
|
.unwrap()
|
||||||
|
.dynamic_cast()
|
||||||
|
.unwrap();
|
||||||
self.set_displayed_position(position + 1);
|
self.set_displayed_position(position + 1);
|
||||||
self.set_song(&window.playbin().entries()[position as usize]);
|
self.set_song(&song);
|
||||||
self.set_current(window.playbin().current_entry() == Some(position as usize));
|
|
||||||
self.set_position(position);
|
self.set_position(position);
|
||||||
|
self.set_playlist_pos(window.playlist_pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unbind(&self) {}
|
pub fn unbind(&self) {}
|
||||||
|
|
|
@ -19,9 +19,12 @@ mod imp {
|
||||||
show_cover_art: Cell<bool>,
|
show_cover_art: Cell<bool>,
|
||||||
|
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
volume: Cell<i32>,
|
_volume: Cell<i64>,
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
mute: Cell<bool>,
|
_mute: Cell<bool>,
|
||||||
|
#[property(get, set)]
|
||||||
|
_pause: Cell<bool>,
|
||||||
|
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
position: Cell<f64>,
|
position: Cell<f64>,
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
|
@ -157,6 +160,10 @@ mod imp {
|
||||||
fn on_mute_toggle(&self) {
|
fn on_mute_toggle(&self) {
|
||||||
self.obj().set_mute(!self.obj().mute());
|
self.obj().set_mute(!self.obj().mute());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn window(&self) -> crate::ui::Window {
|
||||||
|
self.obj().root().unwrap().dynamic_cast().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Playbar {
|
impl Drop for Playbar {
|
||||||
|
|
195
src/ui/window.rs
195
src/ui/window.rs
|
@ -1,9 +1,10 @@
|
||||||
mod imp {
|
mod imp {
|
||||||
use crate::{Playbin, PlaybinSong};
|
use crate::mpv;
|
||||||
|
use crate::PlaybinSong;
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use adw::subclass::prelude::*;
|
use adw::subclass::prelude::*;
|
||||||
use glib::subclass::InitializingObject;
|
use glib::subclass::InitializingObject;
|
||||||
use gtk::{gdk, glib};
|
use gtk::{gdk, gio, glib};
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use tracing::{event, Level};
|
use tracing::{event, Level};
|
||||||
|
@ -29,16 +30,38 @@ mod imp {
|
||||||
|
|
||||||
pub(super) setup: crate::ui::Setup,
|
pub(super) setup: crate::ui::Setup,
|
||||||
|
|
||||||
pub(super) playbin: Rc<Playbin>,
|
|
||||||
pub(super) api: RefCell<Option<Rc<crate::subsonic::Client>>>,
|
pub(super) api: RefCell<Option<Rc<crate::subsonic::Client>>>,
|
||||||
|
|
||||||
pub(super) _sender: async_broadcast::Sender<crate::Event>,
|
pub(super) mpv: mpv::Handle,
|
||||||
pub(super) inactive_receiver: async_broadcast::InactiveReceiver<crate::Event>,
|
#[property(get)]
|
||||||
|
playlist_model: gio::ListStore,
|
||||||
|
|
||||||
|
#[property(type = i64, get = Self::volume, set = Self::set_volume)]
|
||||||
|
_volume: (),
|
||||||
|
#[property(type = bool, get = Self::mute, set = Self::set_mute)]
|
||||||
|
_mute: (),
|
||||||
|
#[property(type = bool, get = Self::pause, set = Self::set_pause)]
|
||||||
|
_pause: (),
|
||||||
|
#[property(type = i64, get = Self::playlist_pos)]
|
||||||
|
_playlist_pos: (),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Window {
|
impl Default for Window {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let (sender, receiver) = async_broadcast::broadcast(100); // TODO: constantize
|
let mpv = mpv::Handle::new();
|
||||||
|
mpv.set_property("audio-client-name", "audrey").unwrap();
|
||||||
|
mpv.set_property("user-agent", crate::USER_AGENT).unwrap();
|
||||||
|
mpv.set_property("video", false).unwrap();
|
||||||
|
mpv.set_property("prefetch-playlist", true).unwrap();
|
||||||
|
mpv.set_property("gapless-audio", true).unwrap();
|
||||||
|
|
||||||
|
mpv.observe_property(0, "volume").unwrap();
|
||||||
|
mpv.observe_property(1, "mute").unwrap();
|
||||||
|
mpv.observe_property(2, "pause").unwrap();
|
||||||
|
mpv.observe_property(3, "playlist-pos").unwrap();
|
||||||
|
|
||||||
|
// "Useful to drain property changes before a new file is loaded."
|
||||||
|
mpv.add_hook(0, "on_before_start_file", 0).unwrap();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
playbar: Default::default(),
|
playbar: Default::default(),
|
||||||
|
@ -47,10 +70,14 @@ mod imp {
|
||||||
playing_cover_art: Default::default(),
|
playing_cover_art: Default::default(),
|
||||||
song: Default::default(),
|
song: Default::default(),
|
||||||
setup: Default::default(),
|
setup: Default::default(),
|
||||||
playbin: Rc::new(Playbin::new(sender.clone())),
|
|
||||||
api: Default::default(),
|
api: Default::default(),
|
||||||
_sender: sender,
|
mpv,
|
||||||
inactive_receiver: receiver.deactivate(),
|
playlist_model: gio::ListStore::new::<PlaybinSong>(),
|
||||||
|
|
||||||
|
_volume: (),
|
||||||
|
_mute: (),
|
||||||
|
_pause: (),
|
||||||
|
_playlist_pos: (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,52 +103,56 @@ mod imp {
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
|
|
||||||
crate::event::spawn_object_listener(
|
let window = self.obj().downgrade();
|
||||||
self.inactive_receiver.activate_cloned(),
|
glib::spawn_future_local(async move {
|
||||||
self.obj().as_ref(),
|
while let Some(window) = window.upgrade() {
|
||||||
|window, event| {
|
let listener = window.imp().mpv.wakeup_listener();
|
||||||
use crate::Event;
|
while let Some(event) = window.imp().mpv.wait_event(0.0) {
|
||||||
match dbg!(event) {
|
use crate::mpv::Event;
|
||||||
Event::PlaybinVolumeChanged => {
|
|
||||||
window
|
match event {
|
||||||
.imp()
|
Event::PropertyChange(event) => match event.reply_userdata {
|
||||||
.playbar
|
0 => {
|
||||||
.set_volume(window.playbin().volume() as i32);
|
assert_eq!(event.name, "volume");
|
||||||
|
window.notify("volume");
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::PlaybinMutedChanged => {
|
1 => {
|
||||||
window.imp().playbar.set_mute(window.playbin().muted());
|
assert_eq!(event.name, "mute");
|
||||||
|
window.notify("mute");
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::PlaybinEntryInserted(index) => {
|
2 => {
|
||||||
window
|
assert_eq!(event.name, "pause");
|
||||||
.imp()
|
window.notify("pause");
|
||||||
.play_queue
|
|
||||||
.model()
|
|
||||||
.unwrap()
|
|
||||||
.insert(index as u32, &window.playbin().entries()[index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {}
|
3 => {
|
||||||
|
assert_eq!(event.name, "playlist-pos");
|
||||||
|
window.notify("playlist-pos");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
);
|
|
||||||
|
|
||||||
let playbin = Rc::downgrade(&self.playbin);
|
mpv::Event::Hook(event) => match event.reply_userdata {
|
||||||
glib::spawn_future_local(glib::clone!(async move {
|
0 => {
|
||||||
loop {
|
assert_eq!(&event.name, "on_before_start_file");
|
||||||
match playbin.upgrade() {
|
event!(Level::DEBUG, "on_before_start_file triggered");
|
||||||
None => break,
|
// just use this as a barrier
|
||||||
Some(playbin) => {
|
window.imp().mpv.continue_hook(event.id).unwrap();
|
||||||
let listener = playbin.tick();
|
}
|
||||||
drop(playbin);
|
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
|
||||||
|
_ => event!(Level::DEBUG, "unhandled {event:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drop(window);
|
||||||
listener.await;
|
listener.await;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
self.play_queue.set_playbin(&self.playbin);
|
|
||||||
|
|
||||||
// set up mpris
|
// set up mpris
|
||||||
let window = self.obj().clone();
|
let window = self.obj().clone();
|
||||||
|
@ -147,9 +178,11 @@ mod imp {
|
||||||
crate::Mpris::setup(conn.object_server(), &window)
|
crate::Mpris::setup(conn.object_server(), &window)
|
||||||
.await
|
.await
|
||||||
.expect("could not serve mpris");
|
.expect("could not serve mpris");
|
||||||
|
/*
|
||||||
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");
|
||||||
|
*/
|
||||||
|
|
||||||
drop(window); // don't keep this alive
|
drop(window); // don't keep this alive
|
||||||
|
|
||||||
|
@ -179,11 +212,18 @@ mod imp {
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
async fn shuffle_all(&self) {
|
async fn shuffle_all(&self) {
|
||||||
self.obj().set_can_click_shuffle_all(false);
|
self.obj().set_can_click_shuffle_all(false);
|
||||||
self.playbin.stop();
|
|
||||||
|
self.mpv.command(["stop"]).unwrap();
|
||||||
|
self.playlist_model.remove_all();
|
||||||
|
|
||||||
let api = self.api.borrow();
|
let api = self.api.borrow();
|
||||||
let api = api.as_ref().unwrap();
|
let api = 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() {
|
||||||
self.playbin.push_entry(PlaybinSong::from_child(api, &song));
|
let song = PlaybinSong::from_child(api, &song);
|
||||||
|
self.mpv
|
||||||
|
.command(["loadfile", &song.stream_url(), "append-play"])
|
||||||
|
.unwrap();
|
||||||
|
self.playlist_model.append(&song);
|
||||||
}
|
}
|
||||||
self.obj().set_can_click_shuffle_all(true);
|
self.obj().set_can_click_shuffle_all(true);
|
||||||
}
|
}
|
||||||
|
@ -221,6 +261,34 @@ mod imp {
|
||||||
*/
|
*/
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn volume(&self) -> i64 {
|
||||||
|
self.mpv.get_property("volume").unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_volume(&self, volume: i64) {
|
||||||
|
self.mpv.set_property("volume", volume).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mute(&self) -> bool {
|
||||||
|
self.mpv.get_property("mute").unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_mute(&self, mute: bool) {
|
||||||
|
self.mpv.set_property("mute", mute).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pause(&self) -> bool {
|
||||||
|
self.mpv.get_property("pause").unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_pause(&self, pause: bool) {
|
||||||
|
self.mpv.set_property("pause", pause).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn playlist_pos(&self) -> i64 {
|
||||||
|
self.mpv.get_property("playlist-pos").unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Window {
|
impl Drop for Window {
|
||||||
|
@ -233,7 +301,6 @@ mod imp {
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use adw::subclass::prelude::*;
|
use adw::subclass::prelude::*;
|
||||||
use gtk::{gio, glib};
|
use gtk::{gio, glib};
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct Window(ObjectSubclass<imp::Window>)
|
pub struct Window(ObjectSubclass<imp::Window>)
|
||||||
|
@ -246,19 +313,14 @@ impl Window {
|
||||||
let window: Self = glib::Object::builder().property("application", app).build();
|
let window: Self = glib::Object::builder().property("application", app).build();
|
||||||
|
|
||||||
// manual bidirectional sync
|
// manual bidirectional sync
|
||||||
|
/*
|
||||||
window
|
window
|
||||||
.imp()
|
.imp()
|
||||||
.playbar
|
.playbar
|
||||||
.set_volume(window.imp().playbin.volume() as i32);
|
.set_volume(window.imp().mpv.get_property::<i64>("volume") as i32);
|
||||||
window.imp().playbar.connect_notify_local(
|
*/
|
||||||
Some("volume"),
|
|
||||||
glib::clone!(
|
|
||||||
#[weak(rename_to = playbin)]
|
|
||||||
window.imp().playbin,
|
|
||||||
move |playbar, _| playbin.set_volume(playbar.volume() as i64)
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
/*
|
||||||
window.imp().playbar.set_mute(window.imp().playbin.muted());
|
window.imp().playbar.set_mute(window.imp().playbin.muted());
|
||||||
window.imp().playbar.connect_notify_local(
|
window.imp().playbar.connect_notify_local(
|
||||||
Some("mute"),
|
Some("mute"),
|
||||||
|
@ -276,9 +338,10 @@ impl Window {
|
||||||
playbar.set_duration(entry.duration() as f64);
|
playbar.set_duration(entry.duration() as f64);
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
);
|
);*/
|
||||||
|
|
||||||
// update position every 100 ms
|
// update position every 100 ms
|
||||||
|
/*
|
||||||
glib::source::timeout_add_local(std::time::Duration::from_millis(100), {
|
glib::source::timeout_add_local(std::time::Duration::from_millis(100), {
|
||||||
let playbar = window.imp().playbar.downgrade();
|
let playbar = window.imp().playbar.downgrade();
|
||||||
let playbin = Rc::downgrade(&window.imp().playbin);
|
let playbin = Rc::downgrade(&window.imp().playbin);
|
||||||
|
@ -294,7 +357,7 @@ impl Window {
|
||||||
playbar.set_position(playbin.position().unwrap_or(0.0));
|
playbar.set_position(playbin.position().unwrap_or(0.0));
|
||||||
glib::ControlFlow::Continue
|
glib::ControlFlow::Continue
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
|
|
||||||
window
|
window
|
||||||
.imp()
|
.imp()
|
||||||
|
@ -302,12 +365,13 @@ impl Window {
|
||||||
.connected()
|
.connected()
|
||||||
.connect_object(&window, |_setup, window, api| {
|
.connect_object(&window, |_setup, window, api| {
|
||||||
window.imp().api.replace(Some(api));
|
window.imp().api.replace(Some(api));
|
||||||
window.imp().playbin.stop();
|
//window.imp().playbin.stop();
|
||||||
window.set_can_click_shuffle_all(true);
|
window.set_can_click_shuffle_all(true);
|
||||||
true
|
true
|
||||||
});
|
});
|
||||||
window.imp().setup.load();
|
window.imp().setup.load();
|
||||||
|
|
||||||
|
/*
|
||||||
window
|
window
|
||||||
.imp()
|
.imp()
|
||||||
.playbin
|
.playbin
|
||||||
|
@ -317,16 +381,19 @@ impl Window {
|
||||||
.imp()
|
.imp()
|
||||||
.now_playing(&playbin.entries()[playbin.current_entry().unwrap()]);
|
.now_playing(&playbin.entries()[playbin.current_entry().unwrap()]);
|
||||||
true
|
true
|
||||||
});
|
});*/
|
||||||
|
|
||||||
window
|
window
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn playbin(&self) -> &crate::Playbin {
|
pub fn playbin(&self) -> ! {
|
||||||
&self.imp().playbin
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn receiver(&self) -> async_broadcast::Receiver<crate::Event> {
|
pub fn play_index(&self, index: i64) {
|
||||||
self.imp().inactive_receiver.activate_cloned()
|
self.imp()
|
||||||
|
.mpv
|
||||||
|
.command(["playlist-play-index", &index.to_string()])
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue