Refactor command handling

This commit is contained in:
KoffeinFlummi
2019-03-28 03:05:25 +01:00
parent 83a394790f
commit 486bc7617e
10 changed files with 380 additions and 349 deletions

View File

@@ -1,20 +1,21 @@
use std::cmp::{max, min};
use std::sync::{Arc, RwLock, RwLockReadGuard};
use std::sync::{Arc, RwLock};
use cursive::align::HAlign;
use cursive::event::{Event, EventResult, MouseButton, MouseEvent};
use cursive::theme::{ColorStyle, ColorType, PaletteColor};
use cursive::traits::View;
use cursive::view::ScrollBase;
use cursive::{Printer, Rect, Vec2};
use cursive::{Cursive, Printer, Rect, Vec2};
use unicode_width::UnicodeWidthStr;
use queue::Queue;
use traits::ListItem;
use traits::{ListItem, ViewExt};
use commands::CommandResult;
pub struct ListView<I: 'static + ListItem> {
content: Arc<RwLock<Vec<I>>>,
last_content_length: usize,
last_content_len: usize,
selected: usize,
last_size: Vec2,
scrollbar: ScrollBase,
@@ -25,7 +26,7 @@ impl<I: ListItem> ListView<I> {
pub fn new(content: Arc<RwLock<Vec<I>>>, queue: Arc<Queue>) -> Self {
Self {
content,
last_content_length: 0,
last_content_len: 0,
selected: 0,
last_size: Vec2::new(0, 0),
scrollbar: ScrollBase::new(),
@@ -33,13 +34,6 @@ impl<I: ListItem> ListView<I> {
}
}
pub fn with_selected(&self, cb: Box<Fn(&I) -> ()>) {
match self.content.read().unwrap().get(self.selected) {
Some(x) => cb(x),
None => error!("listview: invalid item index: {})", self.selected),
}
}
pub fn get_selected_index(&self) -> usize {
self.selected
}
@@ -54,12 +48,6 @@ impl<I: ListItem> ListView<I> {
let new = self.selected as i32 + delta;
self.move_focus_to(max(new, 0) as usize);
}
pub fn content(&self) -> RwLockReadGuard<Vec<I>> {
self.content
.read()
.expect("could not readlock listview content")
}
}
impl<I: ListItem> View for ListView<I> {
@@ -116,13 +104,13 @@ impl<I: ListItem> View for ListView<I> {
}
fn layout(&mut self, size: Vec2) {
self.last_content_length = self.content.read().unwrap().len();
self.last_content_len = self.content.read().unwrap().len();
self.last_size = size;
self.scrollbar.set_heights(size.y, self.last_content_length);
self.scrollbar.set_heights(size.y, self.last_content_len);
}
fn needs_relayout(&self) -> bool {
self.content.read().unwrap().len() != self.last_content_length
self.content.read().unwrap().len() != self.last_content_len
}
fn on_event(&mut self, e: Event) -> EventResult {
@@ -184,3 +172,53 @@ impl<I: ListItem> View for ListView<I> {
}
}
}
impl<I: ListItem> ViewExt for ListView<I> {
fn on_command(&mut self,
_s: &mut Cursive,
cmd: &String,
args: &[String]
) -> Result<CommandResult, String> {
if cmd == "play" {
let content = self.content.read().unwrap();
if let Some(item) = content.get(self.selected) {
item.play(self.queue.clone());
}
return Ok(CommandResult::Consumed(None));
}
if cmd == "queue" {
let content = self.content.read().unwrap();
if let Some(item) = content.get(self.selected) {
item.queue(self.queue.clone());
}
return Ok(CommandResult::Consumed(None));
}
if cmd != "move" {
return Ok(CommandResult::Ignored);
}
if let Some(dir) = args.get(0) {
let amount: i32 = args
.get(1)
.unwrap_or(&"1".to_string())
.parse()
.map_err(|e| format!("{:?}", e))?;
let len = self.content.read().unwrap().len();
if dir == "up" && self.selected > 0 {
self.move_focus(amount * -1);
return Ok(CommandResult::Consumed(None));
}
if dir == "down" && self.selected < len - 1 {
self.move_focus(amount);
return Ok(CommandResult::Consumed(None));
}
}
Ok(CommandResult::Ignored)
}
}