Add buffer display in statusbar

embed
Manos Pitsidianakis 2018-08-26 19:29:12 +03:00
parent 6f994feb13
commit 5f24515145
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
6 changed files with 111 additions and 36 deletions

View File

@ -326,8 +326,12 @@ impl Component for EnvelopeView {
} }
} }
match event.event_type { match event.event_type {
UIEventType::Input(Key::Esc) => { UIEventType::Input(Key::Esc) | UIEventType::Input(Key::Alt('')) => {
self.cmd_buf.clear(); self.cmd_buf.clear();
context.replies.push_back(UIEvent {
id: 0,
event_type: UIEventType::StatusEvent(StatusEvent::BufClear),
});
return true; return true;
} }
UIEventType::Input(Key::Char(c)) if c >= '0' && c <= '9' => { UIEventType::Input(Key::Char(c)) if c >= '0' && c <= '9' => {
@ -358,6 +362,10 @@ impl Component for EnvelopeView {
{ {
let lidx = self.cmd_buf.parse::<usize>().unwrap(); let lidx = self.cmd_buf.parse::<usize>().unwrap();
self.cmd_buf.clear(); self.cmd_buf.clear();
context.replies.push_back(UIEvent {
id: 0,
event_type: UIEventType::StatusEvent(StatusEvent::BufClear),
});
{ {
let envelope: &Envelope = self.wrapper.envelope(); let envelope: &Envelope = self.wrapper.envelope();
@ -382,8 +390,11 @@ impl Component for EnvelopeView {
ContentType::Multipart { .. } => { ContentType::Multipart { .. } => {
context.replies.push_back(UIEvent { context.replies.push_back(UIEvent {
id: 0, id: 0,
event_type: UIEventType::StatusNotification( event_type: UIEventType::StatusEvent(
"Multipart attachments are not supported yet.".to_string(), StatusEvent::DisplayMessage(
"Multipart attachments are not supported yet."
.to_string(),
),
), ),
}); });
return true; return true;
@ -405,10 +416,12 @@ impl Component for EnvelopeView {
} else { } else {
context.replies.push_back(UIEvent { context.replies.push_back(UIEvent {
id: 0, id: 0,
event_type: UIEventType::StatusNotification(format!( event_type: UIEventType::StatusEvent(
"Couldn't find a default application for type {}", StatusEvent::DisplayMessage(format!(
attachment_type "Couldn't find a default application for type {}",
)), attachment_type
)),
),
}); });
return true; return true;
} }
@ -417,9 +430,8 @@ impl Component for EnvelopeView {
} else { } else {
context.replies.push_back(UIEvent { context.replies.push_back(UIEvent {
id: 0, id: 0,
event_type: UIEventType::StatusNotification(format!( event_type: UIEventType::StatusEvent(StatusEvent::DisplayMessage(
"Attachment `{}` not found.", format!("Attachment `{}` not found.", lidx),
lidx
)), )),
}); });
return true; return true;
@ -432,6 +444,10 @@ impl Component for EnvelopeView {
{ {
let lidx = self.cmd_buf.parse::<usize>().unwrap(); let lidx = self.cmd_buf.parse::<usize>().unwrap();
self.cmd_buf.clear(); self.cmd_buf.clear();
context.replies.push_back(UIEvent {
id: 0,
event_type: UIEventType::StatusEvent(StatusEvent::BufClear),
});
let url = { let url = {
let envelope: &Envelope = self.wrapper.envelope(); let envelope: &Envelope = self.wrapper.envelope();
let finder = LinkFinder::new(); let finder = LinkFinder::new();
@ -445,9 +461,8 @@ impl Component for EnvelopeView {
} else { } else {
context.replies.push_back(UIEvent { context.replies.push_back(UIEvent {
id: 0, id: 0,
event_type: UIEventType::StatusNotification(format!( event_type: UIEventType::StatusEvent(StatusEvent::DisplayMessage(
"Link `{}` not found.", format!("Link `{}` not found.", lidx),
lidx
)), )),
}); });
return true; return true;

View File

@ -86,9 +86,9 @@ impl Component for HtmlView {
} else { } else {
context.replies.push_back(UIEvent { context.replies.push_back(UIEvent {
id: 0, id: 0,
event_type: UIEventType::StatusNotification( event_type: UIEventType::StatusEvent(StatusEvent::DisplayMessage(
"Couldn't find a default application for html files.".to_string(), "Couldn't find a default application for html files.".to_string(),
), )),
}); });
} }
return true; return true;

View File

@ -352,11 +352,19 @@ impl Component for MailView {
} }
} }
match event.event_type { match event.event_type {
UIEventType::Input(Key::Esc) => { UIEventType::Input(Key::Esc) | UIEventType::Input(Key::Alt('')) => {
self.cmd_buf.clear(); self.cmd_buf.clear();
context.replies.push_back(UIEvent {
id: 0,
event_type: UIEventType::StatusEvent(StatusEvent::BufClear),
});
} }
UIEventType::Input(Key::Char(c)) if c >= '0' && c <= '9' => { UIEventType::Input(Key::Char(c)) if c >= '0' && c <= '9' => {
self.cmd_buf.push(c); self.cmd_buf.push(c);
context.replies.push_back(UIEvent {
id: 0,
event_type: UIEventType::StatusEvent(StatusEvent::BufSet(self.cmd_buf.clone())),
});
} }
UIEventType::Input(Key::Char('r')) UIEventType::Input(Key::Char('r'))
if self.mode == ViewMode::Normal || self.mode == ViewMode::Raw => if self.mode == ViewMode::Normal || self.mode == ViewMode::Raw =>
@ -380,6 +388,10 @@ impl Component for MailView {
{ {
let lidx = self.cmd_buf.parse::<usize>().unwrap(); let lidx = self.cmd_buf.parse::<usize>().unwrap();
self.cmd_buf.clear(); self.cmd_buf.clear();
context.replies.push_back(UIEvent {
id: 0,
event_type: UIEventType::StatusEvent(StatusEvent::BufClear),
});
{ {
let accounts = &context.accounts; let accounts = &context.accounts;
@ -403,10 +415,9 @@ impl Component for MailView {
Err(e) => { Err(e) => {
context.replies.push_back(UIEvent { context.replies.push_back(UIEvent {
id: 0, id: 0,
event_type: UIEventType::StatusNotification(format!( event_type: UIEventType::StatusEvent(
"{}", StatusEvent::DisplayMessage(format!("{}", e)),
e ),
)),
}); });
} }
} }
@ -420,8 +431,11 @@ impl Component for MailView {
ContentType::Multipart { .. } => { ContentType::Multipart { .. } => {
context.replies.push_back(UIEvent { context.replies.push_back(UIEvent {
id: 0, id: 0,
event_type: UIEventType::StatusNotification( event_type: UIEventType::StatusEvent(
"Multipart attachments are not supported yet.".to_string(), StatusEvent::DisplayMessage(
"Multipart attachments are not supported yet."
.to_string(),
),
), ),
}); });
return true; return true;
@ -443,10 +457,12 @@ impl Component for MailView {
} else { } else {
context.replies.push_back(UIEvent { context.replies.push_back(UIEvent {
id: 0, id: 0,
event_type: UIEventType::StatusNotification(format!( event_type: UIEventType::StatusEvent(
"Couldn't find a default application for type {}", StatusEvent::DisplayMessage(format!(
attachment_type "Couldn't find a default application for type {}",
)), attachment_type
)),
),
}); });
return true; return true;
} }
@ -455,9 +471,8 @@ impl Component for MailView {
} else { } else {
context.replies.push_back(UIEvent { context.replies.push_back(UIEvent {
id: 0, id: 0,
event_type: UIEventType::StatusNotification(format!( event_type: UIEventType::StatusEvent(StatusEvent::DisplayMessage(
"Attachment `{}` not found.", format!("Attachment `{}` not found.", lidx),
lidx
)), )),
}); });
return true; return true;
@ -469,6 +484,10 @@ impl Component for MailView {
{ {
let lidx = self.cmd_buf.parse::<usize>().unwrap(); let lidx = self.cmd_buf.parse::<usize>().unwrap();
self.cmd_buf.clear(); self.cmd_buf.clear();
context.replies.push_back(UIEvent {
id: 0,
event_type: UIEventType::StatusEvent(StatusEvent::BufClear),
});
let url = { let url = {
let accounts = &context.accounts; let accounts = &context.accounts;
let mailbox = &accounts[self.coordinates.0][self.coordinates.1] let mailbox = &accounts[self.coordinates.0][self.coordinates.1]
@ -487,9 +506,8 @@ impl Component for MailView {
} else { } else {
context.replies.push_back(UIEvent { context.replies.push_back(UIEvent {
id: 0, id: 0,
event_type: UIEventType::StatusNotification(format!( event_type: UIEventType::StatusEvent(StatusEvent::DisplayMessage(
"Link `{}` not found.", format!("Link `{}` not found.", lidx),
lidx
)), )),
}); });
return true; return true;

View File

@ -39,7 +39,7 @@ use std::fmt;
use std::fmt::{Debug, Display}; use std::fmt::{Debug, Display};
use std::ops::Deref; use std::ops::Deref;
use super::{Key, UIEvent, UIEventType}; use super::{Key, StatusEvent, UIEvent, UIEventType};
/// The upper and lower boundary char. /// The upper and lower boundary char.
const HORZ_BOUNDARY: char = '─'; const HORZ_BOUNDARY: char = '─';
/// The left and right boundary char. /// The left and right boundary char.
@ -113,6 +113,22 @@ fn new_draft(_context: &mut Context) -> Vec<u8> {
v.into_bytes() v.into_bytes()
} }
pub(crate) fn is_box_char(ch: char) -> bool {
match ch {
HORZ_BOUNDARY | VERT_BOUNDARY => true,
_ => false,
}
}
/*
* pub(crate) fn is_box_char(ch: char) -> bool {
* match ch {
* '└' | '─' | '┘' | '┴' | '┌' | '│' | '├' | '┐' | '┬' | '┤' | '┼' | '╷' | '╵' | '╴' | '╶' => true,
* _ => false,
* }
* }
*/
fn bin_to_ch(b: u32) -> char { fn bin_to_ch(b: u32) -> char {
match b { match b {
0b0001 => '╶', 0b0001 => '╶',
@ -345,7 +361,7 @@ fn set_and_join_horz(grid: &mut CellBuffer, idx: Pos) -> u32 {
bin_set bin_set
} }
fn set_and_join_box(grid: &mut CellBuffer, idx: Pos, ch: char) { pub(crate) fn set_and_join_box(grid: &mut CellBuffer, idx: Pos, ch: char) {
/* Connected sides: /* Connected sides:
* *
* 1 * 1

View File

@ -428,6 +428,7 @@ pub struct StatusBar {
status: String, status: String,
notifications: VecDeque<String>, notifications: VecDeque<String>,
ex_buffer: String, ex_buffer: String,
display_buffer: String,
mode: UIMode, mode: UIMode,
height: usize, height: usize,
dirty: bool, dirty: bool,
@ -447,6 +448,7 @@ impl StatusBar {
status: String::with_capacity(256), status: String::with_capacity(256),
notifications: VecDeque::new(), notifications: VecDeque::new(),
ex_buffer: String::with_capacity(256), ex_buffer: String::with_capacity(256),
display_buffer: String::with_capacity(8),
dirty: true, dirty: true,
mode: UIMode::Normal, mode: UIMode::Normal,
height: 1, height: 1,
@ -467,6 +469,15 @@ impl StatusBar {
false, false,
); );
} }
let (x, y) = bottom_right!(area);
for (idx, c) in self.display_buffer.chars().rev().enumerate() {
if let Some(cell) = grid.get_mut(x.saturating_sub(idx).saturating_sub(1), y) {
cell.set_ch(c);
} else {
break;
}
}
change_colors(grid, area, Color::Byte(123), Color::Byte(26)); change_colors(grid, area, Color::Byte(123), Color::Byte(26));
context.dirty_areas.push_back(area); context.dirty_areas.push_back(area);
} }
@ -595,10 +606,18 @@ impl Component for StatusBar {
UIEventType::Resize => { UIEventType::Resize => {
self.dirty = true; self.dirty = true;
} }
UIEventType::StatusNotification(s) => { UIEventType::StatusEvent(StatusEvent::DisplayMessage(s)) => {
self.notifications.push_back(s.clone()); self.notifications.push_back(s.clone());
self.dirty = true; self.dirty = true;
} }
UIEventType::StatusEvent(StatusEvent::BufClear) => {
self.display_buffer.clear();
self.dirty = true;
}
UIEventType::StatusEvent(StatusEvent::BufSet(s)) => {
self.display_buffer = s.clone();
self.dirty = true;
}
_ => {} _ => {}
} }
false false

View File

@ -41,6 +41,13 @@ use std;
use std::fmt; use std::fmt;
use std::thread; use std::thread;
#[derive(Debug)]
pub enum StatusEvent {
DisplayMessage(String),
BufClear,
BufSet(String),
}
/// `ThreadEvent` encapsulates all of the possible values we need to transfer between our threads /// `ThreadEvent` encapsulates all of the possible values we need to transfer between our threads
/// to the main process. /// to the main process.
#[derive(Debug)] #[derive(Debug)]
@ -83,7 +90,7 @@ pub enum UIEventType {
Notification(String), Notification(String),
EditDraft(File), EditDraft(File),
Action(Action), Action(Action),
StatusNotification(String), StatusEvent(StatusEvent),
MailboxUpdate((usize, usize)), MailboxUpdate((usize, usize)),
StartupCheck, StartupCheck,