diff --git a/melib/src/addressbook.rs b/melib/src/addressbook.rs index 44804b97c..543f3a4a7 100644 --- a/melib/src/addressbook.rs +++ b/melib/src/addressbook.rs @@ -50,8 +50,9 @@ pub struct Card { url: String, key: String, + color: u8, last_edited: DateTime, - extra_properties: FnvHashMap + extra_properties: FnvHashMap, } impl AddressBook { @@ -102,6 +103,7 @@ impl Card { last_edited: Local::now(), extra_properties: FnvHashMap::default(), + color: 0, } } diff --git a/ui/src/components.rs b/ui/src/components.rs index 1ede70492..f6a160d92 100644 --- a/ui/src/components.rs +++ b/ui/src/components.rs @@ -144,7 +144,7 @@ impl Entity { /// Types implementing this Trait can draw on the terminal and receive events. /// If a type wants to skip drawing if it has not changed anything, it can hold some flag in its /// fields (eg self.dirty = false) and act upon that in their `draw` implementation. -pub trait Component: Display + Debug { +pub trait Component: Display + Debug + Send { fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context); fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool; fn is_dirty(&self) -> bool { diff --git a/ui/src/components/contacts/contact_list.rs b/ui/src/components/contacts/contact_list.rs index a812e8f3a..0c8cbf999 100644 --- a/ui/src/components/contacts/contact_list.rs +++ b/ui/src/components/contacts/contact_list.rs @@ -87,7 +87,7 @@ impl Component for ContactList { if self.dirty { self.initialize(context); clear_area(grid, area); - copy_area(grid, &self.content, area, ((0, 0), (MAX_COLS - 1, self.content.size().1 - 1))); + copy_area(grid, &self.content, area, ((0, 0), (MAX_COLS - 1, self.content.size().1.saturating_sub(1)))); context.dirty_areas.push_back(area); self.dirty = false; } @@ -113,7 +113,7 @@ impl Component for ContactList { } } match event.event_type { - UIEventType::Input(Key::Char('e')) => { + UIEventType::Input(Key::Char('e')) if self.length > 0 => { let account = &mut context.accounts[self.account_pos]; let book = &mut account.address_book; let card = book[&self.id_positions[self.cursor_pos]].clone(); diff --git a/ui/src/components/mail/view.rs b/ui/src/components/mail/view.rs index 0113aee24..335609854 100644 --- a/ui/src/components/mail/view.rs +++ b/ui/src/components/mail/view.rs @@ -323,7 +323,7 @@ impl Component for MailView { self.pager = None; self.mode = ViewMode::Subview; } - ViewMode::Subview => {} + ViewMode::Subview | ViewMode::ContactSelector(_) => {} _ => { let buf = { let text = self.attachment_to_text(&body); @@ -349,7 +349,8 @@ impl Component for MailView { } }, ViewMode::ContactSelector(ref mut s) => { - s.draw(grid, (set_y(upper_left, y + 1), bottom_right), context); + clear_area(grid, (set_y(upper_left, y + 1), bottom_right)); + s.draw(grid, (set_y(upper_left, y + 1), bottom_right), context); } _ => { if let Some(p) = self.pager.as_mut() { @@ -415,6 +416,7 @@ impl Component for MailView { entries.push((envelope.from()[0].get_email().into_bytes(), format!("{}", envelope.from()[0]))); entries.push((String::from("foo@bar.de").into_bytes(), String::from("Johann de Vir "))); self.mode = ViewMode::ContactSelector(Selector::new(entries, true)); + self.dirty = true; //context.accounts.context(self.coordinates.0).address_book.add_card(new_card); }, UIEventType::Input(Key::Esc) | UIEventType::Input(Key::Alt('')) => { @@ -604,6 +606,11 @@ impl Component for MailView { self.dirty || self.pager.as_ref().map(|p| p.is_dirty()).unwrap_or(false) || self.subview.as_ref().map(|p| p.is_dirty()).unwrap_or(false) + || if let ViewMode::ContactSelector(ref s) = self.mode { + s.is_dirty() + } else { + false + } } fn set_dirty(&mut self) { self.dirty = true; diff --git a/ui/src/components/utilities.rs b/ui/src/components/utilities.rs index daa3c2f64..3205b8231 100644 --- a/ui/src/components/utilities.rs +++ b/ui/src/components/utilities.rs @@ -864,6 +864,7 @@ impl fmt::Display for Selector { impl Component for Selector { fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) { + eprintln!("drawing"); let (width, height) = self.content.size(); copy_area_with_break( grid, @@ -897,14 +898,17 @@ impl Component for Selector { false, ); } + self.dirty = true; return true; }, UIEventType::Input(Key::Up) if self.cursor > 0 => { self.cursor -= 1; + self.dirty = true; return true; }, UIEventType::Input(Key::Down) if self.cursor < height.saturating_sub(1) => { self.cursor += 1; + self.dirty = true; return true; }, _ => {} diff --git a/ui/src/components/utilities/widgets.rs b/ui/src/components/utilities/widgets.rs index 5cfac152d..971ae11d4 100644 --- a/ui/src/components/utilities/widgets.rs +++ b/ui/src/components/utilities/widgets.rs @@ -8,6 +8,13 @@ enum FormFocus { TextInput, } +/* +enum Field { + Text(String), + Choice(Vec), +} +*/ + impl Default for FormFocus { fn default() -> FormFocus { FormFocus::Fields @@ -195,7 +202,7 @@ impl Component for FormWidget { #[derive(Debug, Default)] -pub struct ButtonWidget where T: std::fmt::Debug + Default{ +pub struct ButtonWidget where T: std::fmt::Debug + Default + Send{ buttons: FnvHashMap, layout: Vec, @@ -203,13 +210,13 @@ pub struct ButtonWidget where T: std::fmt::Debug + Default{ cursor: usize, } -impl fmt::Display for ButtonWidget where T: std::fmt::Debug + Default { +impl fmt::Display for ButtonWidget where T: std::fmt::Debug + Default + Send { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt("", f) } } -impl ButtonWidget where T: std::fmt::Debug + Default { +impl ButtonWidget where T: std::fmt::Debug + Default + Send { pub fn new(init_val: (String, T)) -> ButtonWidget { ButtonWidget { layout: vec![init_val.0.clone()], @@ -230,7 +237,7 @@ impl ButtonWidget where T: std::fmt::Debug + Default { } -impl Component for ButtonWidget where T: std::fmt::Debug + Default { +impl Component for ButtonWidget where T: std::fmt::Debug + Default + Send { fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) { let upper_left = upper_left!(area); let bottom_right = bottom_right!(area); diff --git a/ui/src/execute/actions.rs b/ui/src/execute/actions.rs index bef27f3d2..cd80b0a3d 100644 --- a/ui/src/execute/actions.rs +++ b/ui/src/execute/actions.rs @@ -24,26 +24,28 @@ */ pub use melib::mailbox::{SortField, SortOrder}; +use components::Entity; extern crate uuid; use uuid::Uuid; -#[derive(Debug, Clone)] +#[derive(Debug, )] pub enum ListingAction { SetPlain, SetThreaded, SetCompact, } -#[derive(Debug, Clone)] +#[derive(Debug, )] pub enum TabAction { + EntityOpen(Entity), NewDraft, Reply((usize, usize, usize), usize), // thread coordinates (account, mailbox, root_set idx) and message idx Close, Kill(Uuid), } -#[derive(Debug, Clone)] +#[derive(Debug, )] pub enum Action { Listing(ListingAction), ViewMailbox(usize),