summaryrefslogtreecommitdiffstats
path: root/src/views/main.rs
blob: e1e9f1d12641e3da3a77774c45e82dbd0f38a002 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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::event::Key;
use cursive::traits::Resizable;
use cursive::view::Nameable;
use cursive::view::Selector;
use cursive::view::SizeConstraint;
use cursive::view::ViewNotFound;
use cursive::views::NamedView;
use cursive::views::ResizedView;
use getset::{Getters, MutGetters};

use crate::tabs::*;
use crate::runtime::Runtime;

pub const MAIN_VIEW_NAME: &'static str = "main_view";

#[derive(Getters, MutGetters)]
pub struct MainView {
    rt: Rc<Runtime>,

    #[getset(get = "pub", get_mut = "pub")]
    tabs: crate::tabs::Tabs,
}

impl MainView {
    pub fn new(rt: Rc<Runtime>) -> Result<NamedView<Self>> {
        let default_query = rt.config().notmuch_default_query();
        let tabs = Tabs::new(default_query, rt.clone())?;

        Ok(MainView { rt, tabs }.with_name(MAIN_VIEW_NAME))
    }

    pub fn add_tab_for_query(&mut self, query: &str) -> Result<()> {
        self.tabs.add_tab_for_query(self.rt.clone(), query)
    }

    pub fn get_current_tab(&self) -> Option<&crate::tabs::Tab> {
        debug!("Getting current tab");
        if let Some(mux) = self.tabs.get_active_tab() {
            debug!("Found current tab, returning mux: {:?}", mux.type_id());
            mux.downcast_ref::<crate::tabs::Tab>()
        } else {
            debug!("No current tab found");
            None
        }
    }

    pub fn get_current_mux(&self) -> Option<&Box<dyn cursive::View>> {
        debug!("Get current mux");
        if let Some(tab) = self.get_current_tab() {
            debug!("Some(mux) found, getting current view");
            return tab.mux().get_current_view()
        }
        debug!("No mux found");

        None
    }

    pub fn get_current_tab_mut(&mut self) -> Option<&mut crate::tabs::Tab> {
        debug!("Getting current tab (mut)");
        if let Some(mux) = self.tabs.get_active_tab_mut() {
            debug!("Got current tab (mut), casting ot crate::tabs::Tab");
            mux.downcast_mut::<crate::tabs::Tab>()
        } else {
            debug!("Did not get current tab (mut)");
            None
        }
    }

    pub fn get_current_mux_mut(&mut self) -> Option<&mut Box<dyn cursive::View>> {
        debug!("Getting current tab (mut)");
        if let Some(mut tab) = self.get_current_tab_mut() {
            debug!("Got current tab (mut), getting view from mux (mut)");
            return tab.mux_mut().get_current_view_mut()
        }

        debug!("Did not get current tab (mut))");
        None
    }

}

impl View for MainView {
    fn draw(&self, printer: &Printer) {
        self.tabs.draw(printer);
    }

    fn layout(&mut self, xy: XY<usize>) {
        self.tabs.layout(xy)
    }

    fn needs_relayout(&self) -> bool {
        self.tabs.needs_relayout()
    }

    fn required_size(&mut self, constraint: XY<usize>) -> XY<usize> {
        self.tabs.required_size(constraint)
    }

    fn on_event(&mut self, e: Event) -> EventResult {
        debug!("Received event: {:?}", e);
        self.tabs.on_event(e)
    }

    fn call_on_any<'a>(&mut self, s: &Selector, tpl: &'a mut (dyn FnMut(&mut (dyn View + 'static)) + 'a)) {
        self.tabs.call_on_any(s, tpl);
    }

    fn focus_view(&mut self, s: &Selector) -> Result<(), ViewNotFound> {
        self.tabs.focus_view(s)
    }

    fn take_focus(&mut self, source: Direction) -> bool {
        self.tabs.take_focus(source)
    }

    fn important_area(&self, view_size: XY<usize>) -> Rect {
        self.tabs.important_area(view_size)
    }

    fn type_name(&self) -> &'static str {
        self.tabs.type_name()
    }

}