ui: reassign listing shortcuts

after `312011c ui: move account menu functions to Listing`, shortcuts like prev_folder etc should be generic over all listing types.
embed
Manos Pitsidianakis 2019-04-29 10:54:40 +03:00
parent 69031e66f9
commit 4ae8cbadbf
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
6 changed files with 130 additions and 236 deletions

View File

@ -20,7 +20,6 @@
*/
use super::*;
use std::ops::{Deref, DerefMut};
mod compact;
pub use self::compact::*;
@ -74,7 +73,7 @@ pub struct Listing {
accounts: Vec<AccountMenuEntry>,
dirty: bool,
visible: bool,
cursor: (usize, usize),
cursor_pos: (usize, usize),
id: ComponentId,
show_divider: bool,
@ -152,26 +151,34 @@ impl Component for Listing {
return true;
}
let shortcuts = self.get_shortcuts(context);
match *event {
UIEvent::Input(Key::Char(k @ 'J')) | UIEvent::Input(Key::Char(k @ 'K')) => {
let folder_length = context.accounts[self.cursor.0].len();
UIEvent::Input(ref k)
if k == shortcuts["next_folder"] || k == shortcuts["prev_folder"] =>
{
let folder_length = context.accounts[self.cursor_pos.0].len();
match k {
'J' if folder_length > 0 => {
if self.cursor.1 < folder_length - 1 {
self.cursor.1 += 1;
self.component
.set_coordinates((self.cursor.0, self.cursor.1, None));
k if k == shortcuts["next_folder"] && folder_length > 0 => {
if self.cursor_pos.1 < folder_length - 1 {
self.cursor_pos.1 += 1;
self.component.set_coordinates((
self.cursor_pos.0,
self.cursor_pos.1,
None,
));
self.set_dirty();
} else {
return true;
}
}
'K' => {
if self.cursor.1 > 0 {
self.cursor.1 -= 1;
let coors = self.component.coordinates();
self.component
.set_coordinates((self.cursor.0, self.cursor.1, None));
k if k == shortcuts["prev_folder"] => {
if self.cursor_pos.1 > 0 {
self.cursor_pos.1 -= 1;
self.component.set_coordinates((
self.cursor_pos.0,
self.cursor_pos.1,
None,
));
self.set_dirty();
} else {
return true;
@ -179,28 +186,31 @@ impl Component for Listing {
}
_ => return false,
}
let folder_hash = context.accounts[self.cursor.0].folders_order[self.cursor.1];
let folder_hash =
context.accounts[self.cursor_pos.0].folders_order[self.cursor_pos.1];
// Inform State that we changed the current folder view.
context
.replies
.push_back(UIEvent::RefreshMailbox((self.cursor.0, folder_hash)));
.push_back(UIEvent::RefreshMailbox((self.cursor_pos.0, folder_hash)));
return true;
}
UIEvent::Input(Key::Char(k @ 'h')) | UIEvent::Input(Key::Char(k @ 'l')) => {
UIEvent::Input(ref k)
if k == shortcuts["next_account"] || k == shortcuts["prev_account"] =>
{
match k {
'h' => {
if self.cursor.0 < self.accounts.len() - 1 {
self.cursor = (self.cursor.0 + 1, 0);
self.component.set_coordinates((self.cursor.0, 0, None));
k if k == shortcuts["next_account"] => {
if self.cursor_pos.0 < self.accounts.len() - 1 {
self.cursor_pos = (self.cursor_pos.0 + 1, 0);
self.component.set_coordinates((self.cursor_pos.0, 0, None));
self.set_dirty();
} else {
return true;
}
}
'l' => {
if self.cursor.0 > 0 {
self.cursor = (self.cursor.0 - 1, 0);
self.component.set_coordinates((self.cursor.0, 0, None));
k if k == shortcuts["prev_account"] => {
if self.cursor_pos.0 > 0 {
self.cursor_pos = (self.cursor_pos.0 - 1, 0);
self.component.set_coordinates((self.cursor_pos.0, 0, None));
self.set_dirty();
} else {
return true;
@ -208,12 +218,12 @@ impl Component for Listing {
}
_ => return false,
}
let folder_hash = context.accounts[self.cursor.0].folders_order[self.cursor.1];
let folder_hash =
context.accounts[self.cursor_pos.0].folders_order[self.cursor_pos.1];
// Inform State that we changed the current folder view.
context.replies.push_back(UIEvent::RefreshMailbox((
self.cursor.0,
std::dbg!(folder_hash),
)));
context
.replies
.push_back(UIEvent::RefreshMailbox((self.cursor_pos.0, folder_hash)));
return true;
}
UIEvent::Action(ref action) => match action {
@ -277,7 +287,7 @@ impl Component for Listing {
_ => {}
},
UIEvent::RefreshMailbox((idxa, folder_hash)) => {
self.cursor = (
self.cursor_pos = (
idxa,
context.accounts[idxa]
.folders_order
@ -293,10 +303,16 @@ impl Component for Listing {
UIEvent::Resize => {
self.dirty = true;
}
UIEvent::Input(Key::Char('`')) => {
UIEvent::Input(ref k) if k == shortcuts["toggle-menu-visibility"] => {
self.menu_visibility = !self.menu_visibility;
self.set_dirty();
}
UIEvent::Input(ref k) if k == shortcuts["new_mail"] => {
context
.replies
.push_back(UIEvent::Action(Tab(NewDraft(self.cursor_pos.0))));
return true;
}
UIEvent::StartupCheck(_) => {
self.dirty = true;
}
@ -330,9 +346,48 @@ impl Component for Listing {
Plain(ref l) => l.get_shortcuts(context),
Threaded(ref l) => l.get_shortcuts(context),
};
map.insert("Toggle account menu visibility", Key::Char('`'));
map.insert("prev_account", Key::Char('h'));
map.insert("next_account", Key::Char('l'));
let config_map = context.settings.shortcuts.listing.key_values();
map.insert(
"new_mail",
if let Some(key) = config_map.get("new_mail") {
(*key).clone()
} else {
Key::Char('m')
},
);
map.insert(
"prev_folder",
if let Some(key) = config_map.get("prev_folder") {
(*key).clone()
} else {
Key::Char('J')
},
);
map.insert(
"next_folder",
if let Some(key) = config_map.get("next_folder") {
(*key).clone()
} else {
Key::Char('K')
},
);
map.insert(
"prev_account",
if let Some(key) = config_map.get("prev_account") {
(*key).clone()
} else {
Key::Char('h')
},
);
map.insert(
"next_account",
if let Some(key) = config_map.get("next_account") {
(*key).clone()
} else {
Key::Char('l')
},
);
map.insert("toggle-menu-visibility", Key::Char('`'));
map
}
@ -378,7 +433,7 @@ impl Listing {
accounts,
visible: true,
dirty: true,
cursor: (0, 0),
cursor_pos: (0, 0),
id: ComponentId::new_v4(),
show_divider: false,
menu_visibility: true,
@ -435,7 +490,7 @@ impl Listing {
let upper_left = upper_left!(area);
let bottom_right = bottom_right!(area);
let highlight = self.cursor.0 == a.index;
let highlight = self.cursor_pos.0 == a.index;
let mut inc = 0;
let mut depth = String::from("");
@ -530,7 +585,7 @@ impl Listing {
}
let s = lines[idx].to_string();
let (color_fg, color_bg) = if highlight {
if self.cursor.1 + 1 == idx {
if self.cursor_pos.1 + 1 == idx {
(Color::Byte(233), Color::Byte(15))
} else {
(Color::Byte(15), Color::Byte(233))
@ -570,7 +625,7 @@ impl Listing {
}
}
if highlight && idx > 1 && self.cursor.1 == idx - 1 {
if highlight && idx > 1 && self.cursor_pos.1 == idx - 1 {
change_colors(grid, ((x, y), (get_x(bottom_right), y)), color_fg, color_bg);
} else {
change_colors(grid, ((x, y), set_y(bottom_right, y)), color_fg, color_bg);

View File

@ -481,12 +481,6 @@ impl Component for MailboxView {
}
_ => {}
},
UIEvent::Input(Key::Char('m')) if !self.unfocused => {
context
.replies
.push_back(UIEvent::Action(Tab(NewDraft(self.cursor_pos.0))));
return true;
}
_ => {}
}
false
@ -546,46 +540,6 @@ impl Component for MailboxView {
Key::Char('i')
},
);
map.insert(
"prev_folder",
if let Some(key) = config_map.get("prev_folder") {
(*key).clone()
} else {
Key::Char('J')
},
);
map.insert(
"next_folder",
if let Some(key) = config_map.get("next_folder") {
(*key).clone()
} else {
Key::Char('K')
},
);
map.insert(
"prev_account",
if let Some(key) = config_map.get("prev_account") {
(*key).clone()
} else {
Key::Char('h')
},
);
map.insert(
"next_account",
if let Some(key) = config_map.get("next_account") {
(*key).clone()
} else {
Key::Char('l')
},
);
map.insert(
"new_mail",
if let Some(key) = config_map.get("new_mail") {
(*key).clone()
} else {
Key::Char('m')
},
);
map
}
@ -703,27 +657,7 @@ impl Component for CompactListing {
if self.views.is_empty() {
return Default::default();
}
let mut map = self.views[self.cursor].get_shortcuts(context);
let config_map = context.settings.shortcuts.compact_listing.key_values();
map.insert(
"prev_account",
if let Some(key) = config_map.get("prev_account") {
(*key).clone()
} else {
Key::Char('h')
},
);
map.insert(
"next_account",
if let Some(key) = config_map.get("next_account") {
(*key).clone()
} else {
Key::Char('l')
},
);
map
self.views[self.cursor].get_shortcuts(context)
}
fn id(&self) -> ComponentId {

View File

@ -434,70 +434,12 @@ impl Component for PlainListing {
self.dirty = true;
return true;
}
UIEvent::Input(Key::Char('m')) if !self.unfocused => {
context
.replies
.push_back(UIEvent::Action(Tab(NewDraft(self.cursor_pos.0))));
return true;
}
UIEvent::Input(Key::Char('i')) if self.unfocused => {
self.unfocused = false;
self.dirty = true;
self.view = None;
return true;
}
UIEvent::Input(Key::Char(k @ 'J')) | UIEvent::Input(Key::Char(k @ 'K')) => {
let folder_length = context.accounts[self.cursor_pos.0].len();
let accounts_length = context.accounts.len();
match k {
'J' if folder_length > 0 => {
if self.new_cursor_pos.1 < folder_length - 1 {
self.new_cursor_pos.1 = self.cursor_pos.1 + 1;
self.dirty = true;
self.refresh_mailbox(context);
} else if accounts_length > 0 && self.new_cursor_pos.0 < accounts_length - 1
{
self.new_cursor_pos.0 = self.cursor_pos.0 + 1;
self.new_cursor_pos.1 = 0;
self.dirty = true;
self.refresh_mailbox(context);
}
}
'K' => {
if self.cursor_pos.1 > 0 {
self.new_cursor_pos.1 = self.cursor_pos.1 - 1;
self.dirty = true;
self.refresh_mailbox(context);
} else if self.cursor_pos.0 > 0 {
self.new_cursor_pos.0 = self.cursor_pos.0 - 1;
self.new_cursor_pos.1 = 0;
self.dirty = true;
self.refresh_mailbox(context);
}
}
_ => {}
}
return true;
}
UIEvent::Input(Key::Char(k @ 'h')) | UIEvent::Input(Key::Char(k @ 'l')) => {
let accounts_length = context.accounts.len();
match k {
'h' if accounts_length > 0 && self.new_cursor_pos.0 < accounts_length - 1 => {
self.new_cursor_pos.0 = self.cursor_pos.0 + 1;
self.new_cursor_pos.1 = 0;
self.dirty = true;
self.refresh_mailbox(context);
}
'l' if self.cursor_pos.0 > 0 => {
self.new_cursor_pos.0 = self.cursor_pos.0 - 1;
self.new_cursor_pos.1 = 0;
self.dirty = true;
self.refresh_mailbox(context);
}
_ => {}
}
return true;
}
UIEvent::RefreshMailbox(_) => {
self.dirty = true;
self.view = None;

View File

@ -599,70 +599,12 @@ impl Component for ThreadListing {
self.dirty = true;
return true;
}
UIEvent::Input(Key::Char('m')) if !self.unfocused => {
context
.replies
.push_back(UIEvent::Action(Tab(NewDraft(self.cursor_pos.0))));
return true;
}
UIEvent::Input(Key::Char('i')) if self.unfocused => {
self.unfocused = false;
self.dirty = true;
self.view = None;
return true;
}
UIEvent::Input(Key::Char(k @ 'J')) | UIEvent::Input(Key::Char(k @ 'K')) => {
let folder_length = context.accounts[self.cursor_pos.0].len();
let accounts_length = context.accounts.len();
match k {
'J' if folder_length > 0 => {
if self.new_cursor_pos.1 < folder_length - 1 {
self.new_cursor_pos.1 = self.cursor_pos.1 + 1;
self.dirty = true;
self.refresh_mailbox(context);
} else if accounts_length > 0 && self.new_cursor_pos.0 < accounts_length - 1
{
self.new_cursor_pos.0 = self.cursor_pos.0 + 1;
self.new_cursor_pos.1 = 0;
self.dirty = true;
self.refresh_mailbox(context);
}
}
'K' => {
if self.cursor_pos.1 > 0 {
self.new_cursor_pos.1 = self.cursor_pos.1 - 1;
self.dirty = true;
self.refresh_mailbox(context);
} else if self.cursor_pos.0 > 0 {
self.new_cursor_pos.0 = self.cursor_pos.0 - 1;
self.new_cursor_pos.1 = 0;
self.dirty = true;
self.refresh_mailbox(context);
}
}
_ => {}
}
return true;
}
UIEvent::Input(Key::Char(k @ 'h')) | UIEvent::Input(Key::Char(k @ 'l')) => {
let accounts_length = context.accounts.len();
match k {
'h' if accounts_length > 0 && self.new_cursor_pos.0 < accounts_length - 1 => {
self.new_cursor_pos.0 = self.cursor_pos.0 + 1;
self.new_cursor_pos.1 = 0;
self.dirty = true;
self.refresh_mailbox(context);
}
'l' if self.cursor_pos.0 > 0 => {
self.new_cursor_pos.0 = self.cursor_pos.0 - 1;
self.new_cursor_pos.1 = 0;
self.dirty = true;
self.refresh_mailbox(context);
}
_ => {}
}
return true;
}
UIEvent::RefreshMailbox(_) => {
self.dirty = true;
self.view = None;

View File

@ -4,6 +4,8 @@ use fnv::FnvHashMap;
#[derive(Debug, Clone, Default, Deserialize)]
pub struct Shortcuts {
#[serde(flatten)]
pub listing: ListingShortcuts,
#[serde(flatten)]
pub compact_listing: CompactListingShortcuts,
#[serde(flatten)]
@ -45,19 +47,12 @@ macro_rules! shortcut_key_values {
}
}
shortcut_key_values! { "compact-listing",
/// Shortcut listing for a mail listing in compact mode.
pub struct CompactListingShortcuts {
open_thread: Key |> "Open thread.",
exit_thread: Key |> "Exit thread view.",
prev_page: Key |> "Go to previous page.",
next_page: Key |> "Go to next page.",
prev_folder: Key |> "Go to previous folder.",
next_folder: Key |> "Go to next folder.",
prev_account: Key |> "Go to previous account.",
next_account: Key |> "Go to next account.",
new_mail: Key |> "Start new mail draft in new tab."
}
shortcut_key_values! { "compact_listing",
/// Shortcut listing for a mail listing in compact mode.
pub struct CompactListingShortcuts {
open_thread: Key |> "Open thread.",
exit_thread: Key |> "Exit thread view."
}
}
impl Default for CompactListingShortcuts {
@ -65,6 +60,26 @@ impl Default for CompactListingShortcuts {
CompactListingShortcuts {
open_thread: Key::Char('\n'),
exit_thread: Key::Char('i'),
}
}
}
shortcut_key_values! { "listing",
/// Shortcut listing for a mail listing.
pub struct ListingShortcuts {
prev_page: Key |> "Go to previous page.",
next_page: Key |> "Go to next page.",
prev_folder: Key |> "Go to previous folder.",
next_folder: Key |> "Go to next folder.",
prev_account: Key |> "Go to previous account.",
next_account: Key |> "Go to next account.",
new_mail: Key |> "Start new mail draft in new tab."
}
}
impl Default for ListingShortcuts {
fn default() -> Self {
ListingShortcuts {
prev_page: Key::PageUp,
next_page: Key::PageDown,
prev_folder: Key::Char('J'),

View File

@ -129,6 +129,12 @@ impl From<TermionKey> for Key {
}
}
impl PartialEq<Key> for &Key {
fn eq(&self, other: &Key) -> bool {
**self == *other
}
}
#[derive(PartialEq)]
enum InputMode {
Normal,