summaryrefslogtreecommitdiffstats
path: root/src/tabs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tabs.rs')
-rw-r--r--src/tabs.rs166
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()
+ }
+}
+