Open Contacts list from accounts tab
parent
00abea5bff
commit
e285d1006b
|
@ -24,7 +24,7 @@ use fnv::FnvHashMap;
|
|||
|
||||
use std::ops::Deref;
|
||||
|
||||
type CardId = Uuid;
|
||||
pub type CardId = Uuid;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||
pub struct AddressBook {
|
||||
|
|
|
@ -136,8 +136,8 @@ impl Entity {
|
|||
&self.id
|
||||
}
|
||||
/// Pass events to child component.
|
||||
pub fn rcv_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
self.component.process_event(&event, context)
|
||||
pub fn rcv_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
self.component.process_event(event, context)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,7 @@ impl Entity {
|
|||
/// fields (eg self.dirty = false) and act upon that in their `draw` implementation.
|
||||
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 process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool;
|
||||
fn is_dirty(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ impl Component for ContactManager {
|
|||
context.dirty_areas.push_back(area);
|
||||
}
|
||||
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
if self.form.process_event(event, context) {
|
||||
match self.form.buttons_result() {
|
||||
None => {},
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
use super::*;
|
||||
|
||||
use melib::CardId;
|
||||
|
||||
const MAX_COLS: usize = 500;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum ViewMode {
|
||||
List,
|
||||
View(EntityId),
|
||||
View(CardId),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -16,7 +18,7 @@ pub struct ContactList {
|
|||
length: usize,
|
||||
content: CellBuffer,
|
||||
|
||||
id_positions: Vec<EntityId>,
|
||||
id_positions: Vec<CardId>,
|
||||
|
||||
mode: ViewMode,
|
||||
dirty: bool,
|
||||
|
@ -51,6 +53,13 @@ impl ContactList {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn for_account(pos: usize) -> Self {
|
||||
ContactList {
|
||||
account_pos: pos,
|
||||
..Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
fn initialize(&mut self, context: &mut Context) {
|
||||
let account = &mut context.accounts[self.account_pos];
|
||||
let book = &mut account.address_book;
|
||||
|
@ -106,13 +115,23 @@ impl Component for ContactList {
|
|||
self.cursor_pos = self.new_cursor_pos;
|
||||
}
|
||||
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
if let Some(ref mut v) = self.view {
|
||||
if v.process_event(event, context) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
match event.event_type {
|
||||
UIEventType::Input(Key::Char('c')) => {
|
||||
let mut manager = ContactManager::default();
|
||||
manager.account_pos = self.account_pos;
|
||||
let entity = Entity::from(Box::new(manager));
|
||||
|
||||
self.mode = ViewMode::View(*entity.id());
|
||||
self.view = Some(entity);
|
||||
|
||||
return true;
|
||||
},
|
||||
UIEventType::Input(Key::Char('e')) if self.length > 0 => {
|
||||
let account = &mut context.accounts[self.account_pos];
|
||||
let book = &mut account.address_book;
|
||||
|
|
|
@ -91,7 +91,7 @@ impl Component for Indexer {
|
|||
context.dirty_areas.push_back(area);
|
||||
}
|
||||
|
||||
fn process_event(&mut self, event: &UIEvent, _context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, _context: &mut Context) -> bool {
|
||||
if !self.entries[self.cursor[0]]
|
||||
.index
|
||||
.process_event(event, _context)
|
||||
|
|
|
@ -123,7 +123,7 @@ impl Component for Index {
|
|||
return;
|
||||
}
|
||||
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
if self.content.process_event(event, context) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -257,7 +257,7 @@ impl Component for AccountMenu {
|
|||
|
||||
context.dirty_areas.push_back(area);
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, _context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, _context: &mut Context) -> bool {
|
||||
match event.event_type {
|
||||
UIEventType::RefreshMailbox(c) => {
|
||||
self.cursor = Some(c);
|
||||
|
|
|
@ -119,7 +119,7 @@ impl Component for AccountsPanel {
|
|||
copy_area(grid, &self.content, area, ((0, 0), (width - 1, height - 1)));
|
||||
context.dirty_areas.push_back(area);
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
match event.event_type {
|
||||
UIEventType::Input(Key::Up) => {
|
||||
self.cursor = self.cursor.saturating_sub(1);
|
||||
|
@ -133,6 +133,13 @@ impl Component for AccountsPanel {
|
|||
}
|
||||
return true;
|
||||
},
|
||||
UIEventType::Input(Key::Char('\n')) => {
|
||||
context.replies.push_back(UIEvent {
|
||||
id: 0,
|
||||
event_type: UIEventType::Action(Tab(TabOpen(Some(Box::new(ContactList::for_account(self.cursor)))
|
||||
)))});
|
||||
return true;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ impl Component for ContactsPanel {
|
|||
copy_area(grid, &self.content, area, ((0, 0), (width - 1, height - 1)));
|
||||
context.dirty_areas.push_back(area);
|
||||
}
|
||||
fn process_event(&mut self, _event: &UIEvent, _context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, _event: &mut UIEvent, _context: &mut Context) -> bool {
|
||||
false
|
||||
}
|
||||
fn is_dirty(&self) -> bool {
|
||||
|
|
|
@ -387,7 +387,7 @@ impl Component for Composer {
|
|||
context.dirty_areas.push_back(area);
|
||||
}
|
||||
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
match (&mut self.mode, &mut self.reply_context) {
|
||||
(ViewMode::Pager, _) => {
|
||||
/* Cannot mutably borrow in pattern guard, pah! */
|
||||
|
|
|
@ -61,7 +61,7 @@ impl Component for Listing {
|
|||
Listing::Threaded(l) => l.draw(grid, area, context),
|
||||
}
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
if match self {
|
||||
Listing::Plain(l) => l.process_event(event, context),
|
||||
Listing::Compact(l) => l.process_event(event, context),
|
||||
|
|
|
@ -381,7 +381,7 @@ impl Component for CompactListing {
|
|||
}
|
||||
self.dirty = false;
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
if let Some(ref mut v) = self.view {
|
||||
if v.process_event(event, context) {
|
||||
return true;
|
||||
|
|
|
@ -417,7 +417,7 @@ impl Component for PlainListing {
|
|||
self.dirty = false;
|
||||
}
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
if let Some(ref mut v) = self.view {
|
||||
if v.process_event(event, context) {
|
||||
return true;
|
||||
|
|
|
@ -550,7 +550,7 @@ impl Component for ThreadListing {
|
|||
self.dirty = false;
|
||||
}
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
if let Some(ref mut v) = self.view {
|
||||
if v.process_event(event, context) {
|
||||
return true;
|
||||
|
|
|
@ -360,7 +360,7 @@ impl Component for MailView {
|
|||
}
|
||||
}
|
||||
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
match self.mode {
|
||||
ViewMode::Subview => {
|
||||
if let Some(s) = self.subview.as_mut() {
|
||||
|
@ -414,7 +414,7 @@ impl Component for MailView {
|
|||
let envelope: &Envelope = &mailbox.collection[&self.coordinates.2];
|
||||
let mut entries = Vec::new();
|
||||
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 <foo@bar.de>")));
|
||||
entries.push((envelope.to()[0].get_email().into_bytes(), format!("{}", envelope.to()[0])));
|
||||
self.mode = ViewMode::ContactSelector(Selector::new(entries, true));
|
||||
self.dirty = true;
|
||||
//context.accounts.context(self.coordinates.0).address_book.add_card(new_card);
|
||||
|
|
|
@ -315,7 +315,7 @@ impl Component for EnvelopeView {
|
|||
}
|
||||
}
|
||||
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
if let Some(ref mut sub) = self.subview {
|
||||
if sub.process_event(event, context) {
|
||||
return true;
|
||||
|
|
|
@ -66,7 +66,7 @@ impl Component for HtmlView {
|
|||
fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
|
||||
self.pager.draw(grid, area, context);
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
if self.pager.process_event(event, context) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -540,7 +540,7 @@ impl Component for ThreadView {
|
|||
self.draw_horz(grid, area, context);
|
||||
}
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
if self.mailview.process_event(event, context) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ impl fmt::Display for XDGNotifications {
|
|||
|
||||
impl Component for XDGNotifications {
|
||||
fn draw(&mut self, _grid: &mut CellBuffer, _area: Area, _context: &mut Context) {}
|
||||
fn process_event(&mut self, event: &UIEvent, _context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, _context: &mut Context) -> bool {
|
||||
if let UIEventType::Notification(ref title, ref body) = event.event_type {
|
||||
notify_Notification::new()
|
||||
.appname("meli")
|
||||
|
|
|
@ -88,7 +88,7 @@ impl Component for HSplit {
|
|||
context,
|
||||
);
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
self.top.rcv_event(event, context) || self.bottom.rcv_event(event, context)
|
||||
}
|
||||
fn is_dirty(&self) -> bool {
|
||||
|
@ -175,7 +175,7 @@ impl Component for VSplit {
|
|||
.component
|
||||
.draw(grid, ((mid + 1, get_y(upper_left)), bottom_right), context);
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
(self.left.rcv_event(event, context) || self.right.rcv_event(event, context))
|
||||
}
|
||||
fn is_dirty(&self) -> bool {
|
||||
|
@ -380,7 +380,7 @@ impl Component for Pager {
|
|||
}
|
||||
context.dirty_areas.push_back(area);
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, _context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
match event.event_type {
|
||||
UIEventType::Input(Key::Char('k')) => {
|
||||
if self.cursor_pos > 0 {
|
||||
|
@ -547,7 +547,7 @@ impl Component for StatusBar {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
if self.container.rcv_event(event, context) {
|
||||
return true;
|
||||
}
|
||||
|
@ -655,7 +655,7 @@ impl fmt::Display for TextBox {
|
|||
|
||||
impl Component for TextBox {
|
||||
fn draw(&mut self, _grid: &mut CellBuffer, _area: Area, _context: &mut Context) {}
|
||||
fn process_event(&mut self, _event: &UIEvent, _context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, _event: &mut UIEvent, _context: &mut Context) -> bool {
|
||||
false
|
||||
}
|
||||
fn set_dirty(&mut self) {}
|
||||
|
@ -708,7 +708,7 @@ impl Component for Progress {
|
|||
fn draw(&mut self, _grid: &mut CellBuffer, _area: Area, _context: &mut Context) {
|
||||
unimplemented!()
|
||||
}
|
||||
fn process_event(&mut self, _event: &UIEvent, _context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, _event: &mut UIEvent, _context: &mut Context) -> bool {
|
||||
false
|
||||
}
|
||||
fn set_dirty(&mut self) {}
|
||||
|
@ -792,7 +792,7 @@ impl Component for Tabbed {
|
|||
self.children[self.cursor_pos].draw(grid, area, context);
|
||||
}
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
match event.event_type {
|
||||
UIEventType::Input(Key::Char('T')) => {
|
||||
self.cursor_pos = (self.cursor_pos + 1) % self.children.len();
|
||||
|
@ -811,6 +811,12 @@ impl Component for Tabbed {
|
|||
self.children[self.cursor_pos].set_dirty();
|
||||
return true;
|
||||
}
|
||||
UIEventType::Action(Tab(TabOpen(ref mut e))) if e.is_some() => {
|
||||
self.add_component(e.take().unwrap());
|
||||
self.cursor_pos = self.children.len() - 1;
|
||||
self.children[self.cursor_pos].set_dirty();
|
||||
return true;
|
||||
}
|
||||
UIEventType::Action(Tab(Close)) => {
|
||||
let id = *self.children[self.cursor_pos].id();
|
||||
self.children[self.cursor_pos].kill(id);
|
||||
|
@ -874,7 +880,7 @@ impl Component for Selector {
|
|||
);
|
||||
context.dirty_areas.push_back(area);
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
let (width, height) = self.content.size();
|
||||
match event.event_type {
|
||||
UIEventType::Input(Key::Char(' ')) => {
|
||||
|
|
|
@ -120,7 +120,7 @@ impl Component for FormWidget {
|
|||
self.dirty = false;
|
||||
context.dirty_areas.push_back(area);
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
if self.focus == FormFocus::Buttons {
|
||||
if self.buttons.process_event(event, context) {
|
||||
return true;
|
||||
|
@ -256,7 +256,7 @@ impl<T> Component for ButtonWidget<T> where T: std::fmt::Debug + Default + Send
|
|||
len += cur_len + 3;
|
||||
}
|
||||
}
|
||||
fn process_event(&mut self, event: &UIEvent, context: &mut Context) -> bool {
|
||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||
match event.event_type {
|
||||
UIEventType::Input(Key::Char('\n')) => {
|
||||
self.result = Some(self.buttons.remove(&self.layout[self.cursor]).unwrap_or_default());
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
*/
|
||||
|
||||
pub use melib::mailbox::{SortField, SortOrder};
|
||||
use components::Entity;
|
||||
use components::Component;
|
||||
|
||||
extern crate uuid;
|
||||
use uuid::Uuid;
|
||||
|
@ -38,7 +38,7 @@ pub enum ListingAction {
|
|||
|
||||
#[derive(Debug, )]
|
||||
pub enum TabAction {
|
||||
EntityOpen(Entity),
|
||||
TabOpen(Option<Box<Component>>),
|
||||
NewDraft,
|
||||
Reply((usize, usize, usize), usize), // thread coordinates (account, mailbox, root_set idx) and message idx
|
||||
Close,
|
||||
|
|
|
@ -453,7 +453,7 @@ impl State {
|
|||
}
|
||||
|
||||
/// The application's main loop sends `UIEvents` to state via this method.
|
||||
pub fn rcv_event(&mut self, event: UIEvent) {
|
||||
pub fn rcv_event(&mut self, mut event: UIEvent) {
|
||||
match event.event_type {
|
||||
// Command type is handled only by State.
|
||||
UIEventType::Command(cmd) => {
|
||||
|
@ -483,7 +483,7 @@ impl State {
|
|||
}
|
||||
/* inform each entity */
|
||||
for i in 0..self.entities.len() {
|
||||
self.entities[i].rcv_event(&event, &mut self.context);
|
||||
self.entities[i].rcv_event(&mut event, &mut self.context);
|
||||
}
|
||||
|
||||
if !self.context.replies.is_empty() {
|
||||
|
|
Loading…
Reference in New Issue