#![allow(unused_imports)] use cursive::direction::Orientation; use cursive::event::{AnyCb, Event, EventResult, Key}; use cursive::traits::{Boxable, Finder, Identifiable, View}; use cursive::view::{Selector, ViewWrapper}; use cursive::views::{EditView, IdView, ViewRef}; use cursive::{Cursive, Printer, Vec2}; use std::cell::RefCell; use std::sync::{Arc, Mutex, RwLock}; use queue::Queue; use spotify::Spotify; use track::Track; use ui::listview::ListView; pub struct SearchView { results: Arc>>, edit: IdView, list: IdView>, edit_focused: bool, } impl SearchView { pub fn new(spotify: Arc, queue: Arc) -> SearchView { let results = Arc::new(RwLock::new(Vec::new())); let searchfield = EditView::new() .on_submit(move |s, input| { if input.len() > 0 { s.call_on_id("search", |v: &mut SearchView| { v.run_search(input, spotify.clone()); v.focus_view(&Selector::Id("list")).unwrap(); }); } }) .with_id("search_edit"); let list = ListView::new(results.clone(), queue).with_id("list"); SearchView { results: results, edit: searchfield, list: list, edit_focused: true, } } pub fn run_search>(&mut self, query: S, spotify: Arc) { let query = query.into(); let q = query.clone(); self.edit .call_on(&Selector::Id("search_edit"), |v: &mut EditView| { v.set_content(q); }); if let Ok(results) = spotify.search(&query, 50, 0) { let tracks = results .tracks .items .iter() .map(|ft| Track::new(ft)) .collect(); let mut r = self.results.write().unwrap(); *r = tracks; self.edit_focused = false; } } fn pass_event_focused(&mut self, event: Event) -> EventResult { match self.edit_focused { true => self.edit.on_event(event), false => self.list.on_event(event) } } } impl View for SearchView { fn draw(&self, printer: &Printer<'_, '_>) { { let printer = &printer .offset((0, 0)) .cropped((printer.size.x, 1)) .focused(self.edit_focused); self.edit.draw(printer); } let printer = &printer .offset((0, 1)) .cropped((printer.size.x, printer.size.y - 1)) .focused(!self.edit_focused); self.list.draw(printer); } fn layout(&mut self, size: Vec2) { self.edit.layout(Vec2::new(size.x, 1)); self.list.layout(Vec2::new(size.x, size.y - 1)); } fn call_on_any<'a>(&mut self, selector: &Selector<'_>, mut callback: AnyCb<'a>) { self.edit.call_on_any(selector, Box::new(|v| callback(v))); self.list.call_on_any(selector, Box::new(|v| callback(v))); } fn focus_view(&mut self, selector: &Selector<'_>) -> Result<(), ()> { if let Selector::Id(s) = selector { self.edit_focused = s == &"search_edit"; Ok(()) } else { Err(()) } } fn on_event(&mut self, event: Event) -> EventResult { let ret = match event { Event::Key(Key::Tab) => { self.edit_focused = !self.edit_focused; EventResult::Consumed(None) } Event::Key(Key::Esc) if self.edit_focused => { self.edit_focused = false; EventResult::Consumed(None) } _ => self.pass_event_focused(event) }; ret } }