From 502ac36de30f687256df5b205a27771981a533ee Mon Sep 17 00:00:00 2001 From: Henrik Friedrichsen Date: Thu, 7 Mar 2019 22:34:45 +0100 Subject: [PATCH] get rid of the panel wrapper for more space the screen title is now displayed by the layout --- src/main.rs | 9 ++++--- src/ui/layout.rs | 58 ++++++++++++++++++++++++++++++++------------- src/ui/playlist.rs | 7 +++--- src/ui/queue.rs | 7 +++--- src/ui/search.rs | 6 ++--- src/ui/statusbar.rs | 6 ++--- 6 files changed, 57 insertions(+), 36 deletions(-) diff --git a/src/main.rs b/src/main.rs index eced564..89b3d55 100644 --- a/src/main.rs +++ b/src/main.rs @@ -148,15 +148,14 @@ fn main() { let mut queueview = ui::queue::QueueView::new(queue.clone()); let logview_scroller = ScrollView::new(logview).scroll_strategy(ScrollStrategy::StickToBottom); - let logpanel = Panel::new(logview_scroller).title("Log"); let status = ui::statusbar::StatusBar::new(queue.clone(), spotify.clone()); let layout = ui::layout::Layout::new(status) - .view("search", BoxView::with_full_height(search.view)) - .view("playlists", playlists.view.take().unwrap()) - .view("queue", queueview.view.take().unwrap()) - .view("log", logpanel); + .view("search", BoxView::with_full_height(search.view), "Search") + .view("playlists", playlists.view.take().unwrap(), "Playlists") + .view("queue", queueview.view.take().unwrap(), "Queue") + .view("log", logview_scroller, "Log"); cursive.add_fullscreen_layer(layout.with_id("main")); diff --git a/src/ui/layout.rs b/src/ui/layout.rs index d4fa54c..39b184a 100644 --- a/src/ui/layout.rs +++ b/src/ui/layout.rs @@ -1,14 +1,23 @@ use std::collections::HashMap; +use cursive::align::HAlign; use cursive::direction::Direction; use cursive::event::{AnyCb, Event, EventResult}; +use cursive::theme::ColorStyle; use cursive::traits::View; use cursive::vec::Vec2; use cursive::view::{IntoBoxedView, Selector}; use cursive::Printer; +use unicode_width::UnicodeWidthStr; + +struct Screen { + title: String, + view: Box, +} pub struct Layout { - views: HashMap>, + views: HashMap, + title: String, statusbar: Box, focus: Option, } @@ -17,37 +26,52 @@ impl Layout { pub fn new(status: T) -> Layout { Layout { views: HashMap::new(), + title: String::new(), statusbar: status.as_boxed_view(), focus: None, } } - pub fn add_view, T: IntoBoxedView>(&mut self, id: S, view: T) { + pub fn add_view, T: IntoBoxedView>(&mut self, id: S, view: T, title: &str) { let s = id.into(); - self.views.insert(s.clone(), view.as_boxed_view()); + let screen = Screen { + title: title.to_string(), + view: view.as_boxed_view(), + }; + self.views.insert(s.clone(), screen); self.focus = Some(s); } - pub fn view, T: IntoBoxedView>(mut self, id: S, view: T) -> Self { - (&mut self).add_view(id, view); + pub fn view, T: IntoBoxedView>(mut self, id: S, view: T, title: &str) -> Self { + (&mut self).add_view(id, view, title); + self.title = title.to_owned(); self } pub fn set_view>(&mut self, id: S) { let s = id.into(); + let title = &self.views.get(&s).unwrap().title; + self.title = title.clone(); self.focus = Some(s); } } impl View for Layout { fn draw(&self, printer: &Printer<'_, '_>) { + // screen title + printer.with_color(ColorStyle::title_primary(), |printer| { + let offset = HAlign::Center.get_offset(self.title.width(), printer.size.x); + printer.print((offset, 0), &self.title); + }); + + // screen content if let Some(ref id) = self.focus { - let v = self.views.get(id).unwrap(); + let screen = self.views.get(id).unwrap(); let printer = &printer - .offset((0, 0)) - .cropped((printer.size.x, printer.size.y)) + .offset((0, 1)) + .cropped((printer.size.x, printer.size.y - 3)) .focused(true); - v.draw(printer); + screen.view.draw(printer); } self.statusbar @@ -60,8 +84,8 @@ impl View for Layout { fn on_event(&mut self, event: Event) -> EventResult { if let Some(ref id) = self.focus { - let v = self.views.get_mut(id).unwrap(); - v.on_event(event) + let screen = self.views.get_mut(id).unwrap(); + screen.view.on_event(event) } else { EventResult::Ignored } @@ -69,22 +93,22 @@ impl View for Layout { fn layout(&mut self, size: Vec2) { if let Some(ref id) = self.focus { - let v = self.views.get_mut(id).unwrap(); - v.layout(Vec2::new(size.x, size.y - 2)); + let screen = self.views.get_mut(id).unwrap(); + screen.view.layout(Vec2::new(size.x, size.y - 3)); } } fn call_on_any<'a>(&mut self, s: &Selector, c: AnyCb<'a>) { if let Some(ref id) = self.focus { - let v = self.views.get_mut(id).unwrap(); - v.call_on_any(s, c); + let screen = self.views.get_mut(id).unwrap(); + screen.view.call_on_any(s, c); } } fn take_focus(&mut self, source: Direction) -> bool { if let Some(ref id) = self.focus { - let v = self.views.get_mut(id).unwrap(); - v.take_focus(source) + let screen = self.views.get_mut(id).unwrap(); + screen.view.take_focus(source) } else { false } diff --git a/src/ui/playlist.rs b/src/ui/playlist.rs index 17e39ab..96d856e 100644 --- a/src/ui/playlist.rs +++ b/src/ui/playlist.rs @@ -18,7 +18,7 @@ pub enum PlaylistEvent { } pub struct PlaylistView { - pub view: Option>>>>>, // FIXME: wow + pub view: Option>>>, queue: Arc>, spotify: Arc, } @@ -26,11 +26,10 @@ pub struct PlaylistView { impl PlaylistView { pub fn new(queue: Arc>, spotify: Arc) -> PlaylistView { let playlists = LinearLayout::new(Orientation::Vertical).with_id("playlists"); - let scrollable = ScrollView::new(playlists).full_width().full_height(); - let panel = Panel::new(scrollable).title("Playlists"); + let scrollable = ScrollView::new(playlists).full_screen(); PlaylistView { - view: Some(panel), + view: Some(scrollable), queue: queue, spotify: spotify, } diff --git a/src/ui/queue.rs b/src/ui/queue.rs index d82a328..2c1bab3 100644 --- a/src/ui/queue.rs +++ b/src/ui/queue.rs @@ -14,18 +14,17 @@ use ui::splitbutton::SplitButton; use ui::trackbutton::TrackButton; pub struct QueueView { - pub view: Option>>>>>, // FIXME: wow + pub view: Option>>>, queue: Arc>, } impl QueueView { pub fn new(queue: Arc>) -> QueueView { let queuelist = LinearLayout::new(Orientation::Vertical).with_id("queue_list"); - let scrollable = ScrollView::new(queuelist).full_width().full_height(); - let panel = Panel::new(scrollable).title("Queue"); + let scrollable = ScrollView::new(queuelist).full_screen(); QueueView { - view: Some(panel), + view: Some(scrollable), queue: queue, } } diff --git a/src/ui/search.rs b/src/ui/search.rs index b731c49..c0f520d 100644 --- a/src/ui/search.rs +++ b/src/ui/search.rs @@ -13,7 +13,7 @@ use track::Track; use ui::trackbutton::TrackButton; pub struct SearchView { - pub view: Panel, + pub view: LinearLayout, } impl SearchView { @@ -75,7 +75,7 @@ impl SearchView { let layout = LinearLayout::new(Orientation::Vertical) .child(searchfield) .child(scrollable); - let rootpanel = Panel::new(layout).title("Search"); - return SearchView { view: rootpanel }; + + return SearchView { view: layout }; } } diff --git a/src/ui/statusbar.rs b/src/ui/statusbar.rs index 982fc57..7f65cf7 100644 --- a/src/ui/statusbar.rs +++ b/src/ui/statusbar.rs @@ -45,9 +45,9 @@ impl View for StatusBar { }); let state_icon = match self.spotify.get_current_status() { - PlayerEvent::Playing => " ▶ ", - PlayerEvent::Paused => " ▮▮ ", - PlayerEvent::Stopped | PlayerEvent::FinishedTrack => " ◼ ", + PlayerEvent::Playing => "▶ ", + PlayerEvent::Paused => "▮▮", + PlayerEvent::Stopped | PlayerEvent::FinishedTrack => "◼ ", } .to_string();