more refined queue events + playlist delete binding

- move from listview to linearlayout + scrollview
- doesn't redraw the whole view on queue changes anymore
- uses new cursive functions for linearlayout (needs cursive git)

closes #3
This commit is contained in:
Henrik Friedrichsen
2019-03-04 00:56:34 +01:00
parent 38592e3a4c
commit 9507add6a4
5 changed files with 105 additions and 42 deletions

View File

@@ -9,23 +9,23 @@ use std::sync::Arc;
use std::sync::Mutex;
use librespot::core::spotify_id::SpotifyId;
use rspotify::spotify::model::track::FullTrack;
use queue::Queue;
use queue::{Queue, QueueChange};
use spotify::Spotify;
use ui::trackbutton::TrackButton;
pub struct QueueView {
pub view: Option<Panel<LinearLayout>>,
pub view: Option<Panel<BoxView<BoxView<ScrollView<IdView<LinearLayout>>>>>>, // FIXME: wow
queue: Arc<Mutex<Queue>>,
spotify: Arc<Spotify>,
}
impl QueueView {
pub fn new(queue: Arc<Mutex<Queue>>, spotify: Arc<Spotify>) -> QueueView {
let queuelist = ListView::new().with_id("queue_list").full_width();
let queuelist = LinearLayout::new(Orientation::Vertical).with_id("queue_list");
let scrollable = ScrollView::new(queuelist).full_width().full_height();
let layout = LinearLayout::new(Orientation::Vertical).child(scrollable);
let panel = Panel::new(layout).title("Queue");
let panel = Panel::new(scrollable).title("Queue");
QueueView {
view: Some(panel),
@@ -34,32 +34,83 @@ impl QueueView {
}
}
pub fn redraw(&self, s: &mut Cursive) {
let view_ref: Option<ViewRef<ListView>> = s.find_id("queue_list");
fn cb_delete(cursive: &mut Cursive, queue: &mut Queue) {
let view_ref: Option<ViewRef<LinearLayout>> = cursive.find_id("queue_list");
if let Some(queuelist) = view_ref {
let index = queuelist.get_focus_index();
queue.remove(index);
}
}
fn cb_play(cursive: &mut Cursive, queue: &mut Queue, spotify: &Spotify) {
let view_ref: Option<ViewRef<LinearLayout>> = cursive.find_id("queue_list");
if let Some(queuelist) = view_ref {
let index = queuelist.get_focus_index();
let track = queue.remove(index).expect("could not dequeue track");
let trackid = SpotifyId::from_base62(&track.id).expect("could not load track");
spotify.load(trackid);
spotify.play();
}
}
pub fn handle_ev(&self, cursive: &mut Cursive, ev: QueueChange) {
let view_ref: Option<ViewRef<LinearLayout>> = cursive.find_id("queue_list");
if let Some(mut queuelist) = view_ref {
queuelist.clear();
let queue_ref = self.queue.clone();
let queue = self.queue.lock().unwrap();
for (index, track) in queue.iter().enumerate() {
let mut button = TrackButton::new(&track);
let spotify = self.spotify.clone();
// <enter> dequeues the selected track
let queue_ref = queue_ref.clone();
button.add_callback(Key::Enter, move |_cursive| {
let track = queue_ref
.lock()
.unwrap()
.remove(index)
.expect("could not dequeue track");
let trackid = SpotifyId::from_base62(&track.id).expect("could not load track");
spotify.load(trackid);
spotify.play();
});
queuelist.add_child("", button);
match ev {
QueueChange::Enqueue => {
let queue = self.queue.lock().expect("could not lock queue");
let track = queue.peek().expect("queue is empty");
let button = self.create_button(&track);
queuelist.insert_child(0, button);
}
QueueChange::Dequeue => {
queuelist.remove_child(0);
}
QueueChange::Remove(index) => {
queuelist.remove_child(index);
}
QueueChange::Show => self.populate(&mut queuelist),
}
}
}
fn create_button(&self, track: &FullTrack) -> TrackButton {
let mut button = TrackButton::new(&track);
// 'd' deletes the selected track
{
let queue_ref = self.queue.clone();
button.add_callback('d', move |cursive| {
Self::cb_delete(
cursive,
&mut queue_ref.lock().expect("could not lock queue"),
);
});
}
// <enter> dequeues the selected track
{
let queue_ref = self.queue.clone();
let spotify = self.spotify.clone();
button.add_callback(Key::Enter, move |cursive| {
Self::cb_play(
cursive,
&mut queue_ref.lock().expect("could not lock queue"),
&spotify,
);
});
}
button
}
pub fn populate(&self, queuelist: &mut LinearLayout) {
while queuelist.len() > 0 {
queuelist.remove_child(0);
}
let queue = self.queue.lock().expect("could not lock queue");
for track in queue.iter() {
let button = self.create_button(&track);
queuelist.add_child(button);
}
}
}