play queue now works again (sort of)
This commit is contained in:
parent
0a5f8a9162
commit
ec0992ce54
8 changed files with 121 additions and 34 deletions
|
@ -5,7 +5,7 @@ template $AudreyUiPlayQueue: Adw.Bin {
|
||||||
name: "play-queue";
|
name: "play-queue";
|
||||||
|
|
||||||
child: Stack {
|
child: Stack {
|
||||||
visible-child-name: bind $visible_child_name (template.playbin as <$AudreyPlaybin>.play-queue-length) as <string>;
|
visible-child-name: bind $visible_child_name (template.model as <$GListStore>.n-items) as <string>;
|
||||||
|
|
||||||
StackPage {
|
StackPage {
|
||||||
name: "empty";
|
name: "empty";
|
||||||
|
@ -31,7 +31,7 @@ template $AudreyUiPlayQueue: Adw.Bin {
|
||||||
activate => $on_row_activated () swapped;
|
activate => $on_row_activated () swapped;
|
||||||
|
|
||||||
model: NoSelection {
|
model: NoSelection {
|
||||||
model: bind template.playbin as <$AudreyPlaybin>.play_queue;
|
model: bind template.model;
|
||||||
};
|
};
|
||||||
|
|
||||||
factory: SignalListItemFactory {
|
factory: SignalListItemFactory {
|
||||||
|
|
|
@ -35,7 +35,7 @@ template $AudreyUiPlayQueueSong: Box {
|
||||||
margin-top: 1;
|
margin-top: 1;
|
||||||
margin-bottom: 1;
|
margin-bottom: 1;
|
||||||
pixel-size: 50;
|
pixel-size: 50;
|
||||||
paintable: bind template.song as <$AudreyPlaybinSong>.thumbnail;
|
//paintable: bind template.song as <$AudreyPlaybinSong>.thumbnail;
|
||||||
}
|
}
|
||||||
|
|
||||||
Box title_box {
|
Box title_box {
|
||||||
|
|
|
@ -119,7 +119,7 @@ template $AudreyUiWindow: Adw.ApplicationWindow {
|
||||||
margin-end: 24;
|
margin-end: 24;
|
||||||
|
|
||||||
styles [ "frame" ]
|
styles [ "frame" ]
|
||||||
playbin: bind template.playbin;
|
//playbin: bind template.playbin;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,9 @@ where
|
||||||
|
|
||||||
pub fn remove_entry(&self, index: usize) {
|
pub fn remove_entry(&self, index: usize) {
|
||||||
let mut entries = self.entries.borrow_mut();
|
let mut entries = self.entries.borrow_mut();
|
||||||
self.mpv.command(["remove", &index.to_string()]).unwrap();
|
self.mpv
|
||||||
|
.command(["playlist-remove", &index.to_string()])
|
||||||
|
.unwrap();
|
||||||
entries.remove(index as usize);
|
entries.remove(index as usize);
|
||||||
|
|
||||||
drop(entries);
|
drop(entries);
|
||||||
|
@ -241,6 +243,22 @@ where
|
||||||
self.muted_changed.signal()
|
self.muted_changed.signal()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn current_entry_changed(&self) -> Signal<'_, Self, ()> {
|
||||||
|
self.current_entry_changed.signal()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn entry_inserted(&self) -> Signal<'_, Self, usize> {
|
||||||
|
self.entry_inserted.signal()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stopped(&self) -> Signal<'_, Self, ()> {
|
||||||
|
self.stopped.signal()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn entry_removed(&self) -> Signal<'_, Self, usize> {
|
||||||
|
self.entry_removed.signal()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn file_started(&self) -> Signal<'_, Self, ()> {
|
pub fn file_started(&self) -> Signal<'_, Self, ()> {
|
||||||
self.file_started.signal()
|
self.file_started.signal()
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub struct Signal<'a, E, T> {
|
||||||
just_connected: &'a RefCell<Vec<SignalHandlerBox<E, T>>>,
|
just_connected: &'a RefCell<Vec<SignalHandlerBox<E, T>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Default)]
|
||||||
pub struct SignalHandler(Weak<Cell<bool>>);
|
pub struct SignalHandler(Weak<Cell<bool>>);
|
||||||
|
|
||||||
impl SignalHandler {
|
impl SignalHandler {
|
||||||
|
|
|
@ -2,15 +2,22 @@ pub mod song;
|
||||||
pub use song::Song;
|
pub use song::Song;
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
use adw::{glib, prelude::*, subclass::prelude::*};
|
use crate::playbin::Song as PlaybinSong;
|
||||||
|
use adw::{gio, glib, prelude::*, subclass::prelude::*};
|
||||||
use glib::{subclass::InitializingObject, WeakRef};
|
use glib::{subclass::InitializingObject, WeakRef};
|
||||||
|
use std::cell::{Cell, RefCell};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
type Playbin = crate::playbin2::Playbin<PlaybinSong>;
|
||||||
|
|
||||||
#[derive(gtk::CompositeTemplate, glib::Properties, Default)]
|
#[derive(gtk::CompositeTemplate, glib::Properties, Default)]
|
||||||
#[template(resource = "/eu/callcc/audrey/play_queue.ui")]
|
#[template(resource = "/eu/callcc/audrey/play_queue.ui")]
|
||||||
#[properties(wrapper_type = super::PlayQueue)]
|
#[properties(wrapper_type = super::PlayQueue)]
|
||||||
pub struct PlayQueue {
|
pub struct PlayQueue {
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
playbin: WeakRef<crate::Playbin>,
|
pub(super) model: RefCell<Option<gio::ListStore>>,
|
||||||
|
|
||||||
|
pub(super) playbin: RefCell<Option<Rc<Playbin>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
@ -30,7 +37,13 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::derived_properties]
|
#[glib::derived_properties]
|
||||||
impl ObjectImpl for PlayQueue {}
|
impl ObjectImpl for PlayQueue {
|
||||||
|
fn constructed(&self) {
|
||||||
|
self.parent_constructed();
|
||||||
|
|
||||||
|
self.obj().set_model(gio::ListStore::new::<PlaybinSong>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl WidgetImpl for PlayQueue {}
|
impl WidgetImpl for PlayQueue {}
|
||||||
|
|
||||||
|
@ -49,7 +62,7 @@ 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(&self.playbin.upgrade().unwrap());
|
let child = super::Song::new(self.playbin.borrow().as_ref().unwrap());
|
||||||
|
|
||||||
child.set_draggable(true);
|
child.set_draggable(true);
|
||||||
child.set_show_position(true);
|
child.set_show_position(true);
|
||||||
|
@ -81,7 +94,11 @@ mod imp {
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
fn on_row_activated(&self, position: u32) {
|
fn on_row_activated(&self, position: u32) {
|
||||||
self.obj().playbin().unwrap().select_track(position);
|
self.playbin
|
||||||
|
.borrow()
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.play_entry(position as usize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,10 +109,47 @@ mod imp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use crate::playbin::Song as PlaybinSong;
|
||||||
|
use adw::subclass::prelude::*;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
type Playbin = crate::playbin2::Playbin<PlaybinSong>;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct PlayQueue(ObjectSubclass<imp::PlayQueue>)
|
pub struct PlayQueue(ObjectSubclass<imp::PlayQueue>)
|
||||||
@extends adw::Bin, gtk::Widget,
|
@extends adw::Bin, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
.entry_inserted()
|
||||||
|
.connect_object(self, |playbin, play_queue, index| {
|
||||||
|
play_queue
|
||||||
|
.model()
|
||||||
|
.unwrap()
|
||||||
|
.insert(index as u32, &playbin.entries()[index]);
|
||||||
|
true
|
||||||
|
});
|
||||||
|
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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
mod imp {
|
mod imp {
|
||||||
|
use crate::playbin::Song as PlaybinSong;
|
||||||
|
use crate::signal::SignalHandler;
|
||||||
use glib::{subclass::InitializingObject, WeakRef};
|
use glib::{subclass::InitializingObject, WeakRef};
|
||||||
use gtk::{gdk, gio, glib, prelude::*, subclass::prelude::*};
|
use gtk::{gdk, gio, glib, prelude::*, subclass::prelude::*};
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
type Playbin = crate::playbin2::Playbin<PlaybinSong>;
|
||||||
|
|
||||||
#[derive(gtk::CompositeTemplate, glib::Properties, Default)]
|
#[derive(gtk::CompositeTemplate, glib::Properties, Default)]
|
||||||
#[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 {
|
||||||
pub(super) playbin: WeakRef<crate::Playbin>,
|
|
||||||
|
|
||||||
#[property(set, get)]
|
#[property(set, get)]
|
||||||
draggable: Cell<bool>,
|
draggable: Cell<bool>,
|
||||||
#[property(set, get)]
|
#[property(set, get)]
|
||||||
|
@ -24,12 +27,13 @@ mod imp {
|
||||||
#[property(set, get)]
|
#[property(set, get)]
|
||||||
displayed_position: Cell<u32>,
|
displayed_position: Cell<u32>,
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
song: RefCell<Option<crate::playbin::Song>>,
|
song: RefCell<Option<PlaybinSong>>,
|
||||||
|
|
||||||
pub(super) connection: Cell<Option<glib::SignalHandlerId>>,
|
|
||||||
|
|
||||||
drag_pos: Cell<(i32, i32)>,
|
drag_pos: Cell<(i32, i32)>,
|
||||||
drag_widget: Cell<Option<gtk::ListBox>>,
|
drag_widget: Cell<Option<gtk::ListBox>>,
|
||||||
|
|
||||||
|
pub(super) playbin: RefCell<Option<Rc<Playbin>>>,
|
||||||
|
pub(super) connection: Cell<SignalHandler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
@ -61,7 +65,7 @@ mod imp {
|
||||||
self_
|
self_
|
||||||
.obj()
|
.obj()
|
||||||
.playbin()
|
.playbin()
|
||||||
.remove_track(self_.obj().displayed_position() - 1)
|
.remove_entry(self_.obj().displayed_position() as usize - 1)
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
|
@ -169,10 +173,14 @@ mod imp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use crate::playbin::Song as PlaybinSong;
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use adw::subclass::prelude::*;
|
use adw::subclass::prelude::*;
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
type Playbin = crate::playbin2::Playbin<PlaybinSong>;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct Song(ObjectSubclass<imp::Song>)
|
pub struct Song(ObjectSubclass<imp::Song>)
|
||||||
|
@ -181,36 +189,38 @@ glib::wrapper! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Song {
|
impl Song {
|
||||||
pub fn new(playbin: &crate::Playbin) -> Self {
|
pub fn new(playbin: &Rc<Playbin>) -> Self {
|
||||||
let song: Self = Object::new();
|
let song: Self = Object::new();
|
||||||
song.imp().playbin.set(Some(playbin));
|
|
||||||
|
assert!(song
|
||||||
|
.imp()
|
||||||
|
.playbin
|
||||||
|
.replace(Some(Rc::clone(playbin)))
|
||||||
|
.is_none()); // only set once
|
||||||
|
|
||||||
song
|
song
|
||||||
}
|
}
|
||||||
|
|
||||||
fn playbin(&self) -> crate::Playbin {
|
fn playbin(&self) -> Rc<Playbin> {
|
||||||
self.imp().playbin.upgrade().unwrap()
|
Rc::clone(self.imp().playbin.borrow().as_ref().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bind(&self, position: u32, song: &crate::playbin::Song) {
|
pub fn bind(&self, position: u32, song: &crate::playbin::Song) {
|
||||||
self.set_displayed_position(position + 1);
|
self.set_displayed_position(position + 1);
|
||||||
self.set_song(song);
|
self.set_song(song);
|
||||||
self.set_current(self.playbin().play_queue_position() == position);
|
self.set_current(self.playbin().current_entry() == Some(position as usize));
|
||||||
self.imp()
|
self.imp()
|
||||||
.connection
|
.connection
|
||||||
.replace(Some(self.playbin().connect_notify_local(
|
.replace(self.playbin().current_entry_changed().connect_object(
|
||||||
Some("play-queue-position"),
|
|
||||||
glib::clone!(
|
|
||||||
#[weak(rename_to = self_)]
|
|
||||||
self,
|
self,
|
||||||
move |playbin: &crate::Playbin, _| {
|
move |playbin, song, ()| {
|
||||||
self_.set_current(playbin.play_queue_position() == position)
|
song.set_current(playbin.current_entry() == Some(position as usize));
|
||||||
}
|
true
|
||||||
),
|
},
|
||||||
)));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unbind(&self) {
|
pub fn unbind(&self) {
|
||||||
self.playbin()
|
self.imp().connection.take().disconnect();
|
||||||
.disconnect(self.imp().connection.take().unwrap());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,9 @@ mod imp {
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub(super) playbar: TemplateChild<crate::ui::Playbar>,
|
pub(super) playbar: TemplateChild<crate::ui::Playbar>,
|
||||||
|
|
||||||
|
#[template_child]
|
||||||
|
pub(super) play_queue: TemplateChild<crate::ui::PlayQueue>,
|
||||||
|
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
playbin: RefCell<crate::Playbin>,
|
playbin: RefCell<crate::Playbin>,
|
||||||
|
|
||||||
|
@ -72,6 +75,8 @@ mod imp {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
self.play_queue.set_playbin(&self.playbin2);
|
||||||
|
|
||||||
// set up mpris
|
// set up mpris
|
||||||
let window = self.obj().clone();
|
let window = self.obj().clone();
|
||||||
glib::spawn_future_local(async move {
|
glib::spawn_future_local(async move {
|
||||||
|
|
Loading…
Reference in a new issue