get rid of the panel wrapper for more space
the screen title is now displayed by the layout
This commit is contained in:
@@ -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"));
|
||||
|
||||
|
||||
@@ -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<dyn View>,
|
||||
}
|
||||
|
||||
pub struct Layout {
|
||||
views: HashMap<String, Box<dyn View>>,
|
||||
views: HashMap<String, Screen>,
|
||||
title: String,
|
||||
statusbar: Box<dyn View>,
|
||||
focus: Option<String>,
|
||||
}
|
||||
@@ -17,37 +26,52 @@ impl Layout {
|
||||
pub fn new<T: IntoBoxedView>(status: T) -> Layout {
|
||||
Layout {
|
||||
views: HashMap::new(),
|
||||
title: String::new(),
|
||||
statusbar: status.as_boxed_view(),
|
||||
focus: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_view<S: Into<String>, T: IntoBoxedView>(&mut self, id: S, view: T) {
|
||||
pub fn add_view<S: Into<String>, 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<S: Into<String>, T: IntoBoxedView>(mut self, id: S, view: T) -> Self {
|
||||
(&mut self).add_view(id, view);
|
||||
pub fn view<S: Into<String>, 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<S: Into<String>>(&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
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ pub enum PlaylistEvent {
|
||||
}
|
||||
|
||||
pub struct PlaylistView {
|
||||
pub view: Option<Panel<BoxView<BoxView<ScrollView<IdView<LinearLayout>>>>>>, // FIXME: wow
|
||||
pub view: Option<BoxView<ScrollView<IdView<LinearLayout>>>>,
|
||||
queue: Arc<Mutex<Queue>>,
|
||||
spotify: Arc<Spotify>,
|
||||
}
|
||||
@@ -26,11 +26,10 @@ pub struct PlaylistView {
|
||||
impl PlaylistView {
|
||||
pub fn new(queue: Arc<Mutex<Queue>>, spotify: Arc<Spotify>) -> 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,
|
||||
}
|
||||
|
||||
@@ -14,18 +14,17 @@ use ui::splitbutton::SplitButton;
|
||||
use ui::trackbutton::TrackButton;
|
||||
|
||||
pub struct QueueView {
|
||||
pub view: Option<Panel<BoxView<BoxView<ScrollView<IdView<LinearLayout>>>>>>, // FIXME: wow
|
||||
pub view: Option<BoxView<ScrollView<IdView<LinearLayout>>>>,
|
||||
queue: Arc<Mutex<Queue>>,
|
||||
}
|
||||
|
||||
impl QueueView {
|
||||
pub fn new(queue: Arc<Mutex<Queue>>) -> 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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ use track::Track;
|
||||
use ui::trackbutton::TrackButton;
|
||||
|
||||
pub struct SearchView {
|
||||
pub view: Panel<LinearLayout>,
|
||||
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 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user