diff options
Diffstat (limited to 'src/tabs.rs')
-rw-r--r-- | src/tabs.rs | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/src/tabs.rs b/src/tabs.rs new file mode 100644 index 0000000..e0963fe --- /dev/null +++ b/src/tabs.rs @@ -0,0 +1,166 @@ +use std::ops::Deref; +use std::ops::DerefMut; +use std::rc::Rc; + +use anyhow::Result; +use cursive::Printer; +use cursive::Rect; +use cursive::View; +use cursive::XY; +use cursive::direction::Direction; +use cursive::event::Event; +use cursive::event::EventResult; +use cursive::view::Selector; +use cursive::view::ViewNotFound; + +use crate::runtime::Runtime; +use crate::views::maillist::MaillistView; + +#[derive(Hash, Eq, PartialEq, Clone, parse_display::Display)] +pub enum TabPanelName { + #[display("Query: {}")] + NotmuchQuery(String), + + #[display("Other")] + Other, +} + +pub struct Tabs(cursive_tabs::TabPanel<TabPanelName>); + +impl Deref for Tabs { + type Target = cursive_tabs::TabPanel<TabPanelName>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Tabs { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl Tabs { + pub fn new(query: &str, rt: Rc<Runtime>) -> Result<Self> { + let tab_ident = TabPanelName::NotmuchQuery(query.to_string()); + let tp = cursive_tabs::TabPanel::new() + .with_bar_alignment(cursive_tabs::Align::Start) + .with_bar_placement(cursive_tabs::Placement::VerticalLeft) + .with_tab(tab_ident, Tab::for_query(rt, query)?); + + Ok(Tabs(tp)) + } +} + +impl View for Tabs { + fn draw(&self, printer: &Printer) { + self.0.draw(printer); + } + + fn layout(&mut self, xy: XY<usize>) { + self.0.layout(xy) + } + + fn needs_relayout(&self) -> bool { + self.0.needs_relayout() + } + + fn required_size(&mut self, constraint: XY<usize>) -> XY<usize> { + self.0.required_size(constraint) + } + + fn on_event(&mut self, e: Event) -> EventResult { + self.0.on_event(e) + } + + fn call_on_any<'a>(&mut self, s: &Selector, tpl: &'a mut (dyn FnMut(&mut (dyn View + 'static)) + 'a)) { + self.0.call_on_any(s, tpl); + } + + fn focus_view(&mut self, s: &Selector) -> Result<(), ViewNotFound> { + self.0.focus_view(s) + } + + fn take_focus(&mut self, source: Direction) -> bool { + self.0.take_focus(source) + } + + fn important_area(&self, view_size: XY<usize>) -> Rect { + self.0.important_area(view_size) + } + + fn type_name(&self) -> &'static str { + self.0.type_name() + } + +} + +pub struct Tab { + mux: cursive_multiplex::Mux, + nodes: Vec<cursive_multiplex::Id>, + rt: Rc<Runtime>, +} + +impl Tab { + fn new(rt: Rc<Runtime>) -> Self { + Tab { + mux: cursive_multiplex::Mux::new(), + nodes: vec![], + rt, + } + } + + fn for_query(rt: Rc<Runtime>, query: &str) -> Result<Self> { + use failure::Fail; + + let mut this = Self::new(rt.clone()); + let root = this.mux.root().build().unwrap(); + let list = MaillistView::for_query(rt, query)?; + this.nodes.push(this.mux.add_right_of(list, root).map_err(|e| e.compat())?); + Ok(this) + } +} + +impl View for Tab { + fn draw(&self, printer: &Printer) { + self.mux.draw(printer); + } + + fn layout(&mut self, xy: XY<usize>) { + self.mux.layout(xy) + } + + fn needs_relayout(&self) -> bool { + self.mux.needs_relayout() + } + + fn required_size(&mut self, constraint: XY<usize>) -> XY<usize> { + self.mux.required_size(constraint) + } + + fn on_event(&mut self, e: Event) -> EventResult { + self.mux.on_event(e) + } + + fn call_on_any<'a>(&mut self, s: &Selector, tpl: &'a mut (dyn FnMut(&mut (dyn View + 'static)) + 'a)) { + self.mux.call_on_any(s, tpl); + } + + fn focus_view(&mut self, s: &Selector) -> Result<(), ViewNotFound> { + self.mux.focus_view(s) + } + + fn take_focus(&mut self, source: Direction) -> bool { + self.mux.take_focus(source) + } + + fn important_area(&self, view_size: XY<usize>) -> Rect { + self.mux.important_area(view_size) + } + + fn type_name(&self) -> &'static str { + self.mux.type_name() + } +} + |