From daee4e46de0cdfe220cff11fdf686ab2afac2c9c Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Tue, 24 Nov 2020 21:39:02 +0000 Subject: [PATCH] Allow configuration of the sidebar divider This adds the config option listing.sidebar_divider to set the character used to show the divider (defaults to ' ') along with the corresponding theme in mail.sidebar_divider which defaults to the default theme. --- docs/meli-themes.5 | 2 ++ docs/meli.conf.5 | 3 ++ src/components/contacts/contact_list.rs | 37 ++++++++++----------- src/components/mail/listing.rs | 44 ++++++++++++------------- src/conf.rs | 1 + src/conf/listing.rs | 10 ++++++ src/conf/overrides.rs | 4 +++ src/conf/themes.rs | 2 ++ 8 files changed, 62 insertions(+), 41 deletions(-) diff --git a/docs/meli-themes.5 b/docs/meli-themes.5 index 7545d0b4..7306ab0a 100644 --- a/docs/meli-themes.5 +++ b/docs/meli-themes.5 @@ -193,6 +193,8 @@ widgets.options.highlighted .It mail.sidebar .It +mail.sidebar_divider +.It mail.sidebar_unread_count .It mail.sidebar_index diff --git a/docs/meli.conf.5 b/docs/meli.conf.5 index 1d306287..c18d73c0 100644 --- a/docs/meli.conf.5 +++ b/docs/meli.conf.5 @@ -840,6 +840,9 @@ Sets the string to print in the mailbox tree for a leaf level where its root has .It Ic sidebar_mailbox_tree_no_sibling_leaf Ar String .Pq Em optional Sets the string to print in the mailbox tree for a leaf level where its root has no sibling. +.It Ic sidebar_divider Ar char +.Pq Em optional +Sets the character to print as the divider between the accounts list and the message list. .El .Ss Examples of sidebar mailbox tree customization The default values diff --git a/src/components/contacts/contact_list.rs b/src/components/contacts/contact_list.rs index e6e016a0..cdcb277d 100644 --- a/src/components/contacts/contact_list.rs +++ b/src/components/contacts/contact_list.rs @@ -54,7 +54,10 @@ pub struct ContactList { mode: ViewMode, dirty: bool, - show_divider: bool, + + sidebar_divider: char, + sidebar_divider_theme: ThemeAttribute, + menu_visibility: bool, movement: Option, cmd_buf: String, @@ -98,7 +101,8 @@ impl ContactList { cmd_buf: String::with_capacity(8), view: None, ratio: 90, - show_divider: false, + sidebar_divider: context.settings.listing.sidebar_divider, + sidebar_divider_theme: conf::value(context, "mail.sidebar_divider"), menu_visibility: true, id: ComponentId::new_v4(), } @@ -239,13 +243,11 @@ impl ContactList { change_colors(grid, area, fg_color, bg_color); } - fn draw_menu(&mut self, grid: &mut CellBuffer, mut area: Area, context: &mut Context) { + fn draw_menu(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) { if !self.is_dirty() { return; } clear_area(grid, area, self.theme_default); - /* visually divide menu and listing */ - area = (area.0, pos_dec(area.1, (1, 0))); let upper_left = upper_left!(area); let bottom_right = bottom_right!(area); self.dirty = false; @@ -580,19 +582,12 @@ impl Component for ContactList { }; let mid = get_x(bottom_right) - right_component_width; if self.dirty && mid != get_x(upper_left) { - if self.show_divider { - for i in get_y(upper_left)..=get_y(bottom_right) { - grid[(mid, i)] - .set_ch(VERT_BOUNDARY) - .set_fg(self.theme_default.fg) - .set_bg(self.theme_default.bg); - } - } else { - for i in get_y(upper_left)..=get_y(bottom_right) { - grid[(mid, i)] - .set_fg(self.theme_default.fg) - .set_bg(self.theme_default.bg); - } + for i in get_y(upper_left)..=get_y(bottom_right) { + grid[(mid, i)] + .set_ch(self.sidebar_divider) + .set_fg(self.sidebar_divider_theme.fg) + .set_bg(self.sidebar_divider_theme.bg) + .set_attrs(self.sidebar_divider_theme.attrs); } context .dirty_areas @@ -604,7 +599,11 @@ impl Component for ContactList { } else if right_component_width == 0 { self.draw_menu(grid, area, context); } else { - self.draw_menu(grid, (upper_left, (mid, get_y(bottom_right))), context); + self.draw_menu( + grid, + (upper_left, (mid.saturating_sub(1), get_y(bottom_right))), + context, + ); self.draw_list(grid, (set_x(upper_left, mid + 1), bottom_right), context); } self.dirty = false; diff --git a/src/components/mail/listing.rs b/src/components/mail/listing.rs index 2ed7d410..debcdf4b 100644 --- a/src/components/mail/listing.rs +++ b/src/components/mail/listing.rs @@ -481,7 +481,9 @@ pub struct Listing { id: ComponentId, theme_default: ThemeAttribute, - show_divider: bool, + sidebar_divider: char, + sidebar_divider_theme: ThemeAttribute, + menu_visibility: bool, cmd_buf: String, /// This is the width of the right container to the entire width. @@ -539,21 +541,12 @@ impl Component for Listing { }; let mid = get_x(bottom_right) - right_component_width; if self.dirty && mid != get_x(upper_left) { - if self.show_divider { - for i in get_y(upper_left)..=get_y(bottom_right) { - grid[(mid, i)] - .set_ch(VERT_BOUNDARY) - .set_fg(self.theme_default.fg) - .set_bg(self.theme_default.bg) - .set_attrs(self.theme_default.attrs); - } - } else { - for i in get_y(upper_left)..=get_y(bottom_right) { - grid[(mid, i)] - .set_fg(self.theme_default.fg) - .set_bg(self.theme_default.bg) - .set_attrs(self.theme_default.attrs); - } + for i in get_y(upper_left)..=get_y(bottom_right) { + grid[(mid, i)] + .set_ch(self.sidebar_divider) + .set_fg(self.sidebar_divider_theme.fg) + .set_bg(self.sidebar_divider_theme.bg) + .set_attrs(self.sidebar_divider_theme.attrs); } context .dirty_areas @@ -579,7 +572,11 @@ impl Component for Listing { } else if right_component_width == 0 { self.draw_menu(grid, area, context); } else { - self.draw_menu(grid, (upper_left, (mid, get_y(bottom_right))), context); + self.draw_menu( + grid, + (upper_left, (mid.saturating_sub(1), get_y(bottom_right))), + context, + ); if context.is_online(account_hash).is_err() { match self.component { ListingComponent::Offline(_) => {} @@ -1435,8 +1432,9 @@ impl Listing { } }) .collect(); + let first_account_hash = account_entries[0].hash; let mut ret = Listing { - component: Offline(OfflineListing::new((account_entries[0].hash, 0))), + component: Offline(OfflineListing::new((first_account_hash, 0))), accounts: account_entries, status: None, visible: true, @@ -1446,7 +1444,10 @@ impl Listing { startup_checks_rate: RateLimit::new(2, 1000, context.job_executor.clone()), theme_default: conf::value(context, "theme_default"), id: ComponentId::new_v4(), - show_divider: false, + sidebar_divider: *account_settings!( + context[first_account_hash].listing.sidebar_divider + ), + sidebar_divider_theme: conf::value(context, "mail.sidebar_divider"), menu_visibility: true, ratio: 90, menu_width: WidgetWidth::Unset, @@ -1457,13 +1458,11 @@ impl Listing { ret } - fn draw_menu(&mut self, grid: &mut CellBuffer, mut area: Area, context: &mut Context) { + fn draw_menu(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) { if !self.is_dirty() { return; } clear_area(grid, area, self.theme_default); - /* visually divide menu and listing */ - area = (area.0, pos_dec(area.1, (1, 0))); let upper_left = upper_left!(area); let bottom_right = bottom_right!(area); self.dirty = false; @@ -1770,6 +1769,7 @@ impl Listing { /* Set to dummy */ self.component = Offline(OfflineListing::new((account_hash, 0))); } + self.sidebar_divider = *account_settings!(context[account_hash].listing.sidebar_divider); self.status = None; self.set_dirty(true); context diff --git a/src/conf.rs b/src/conf.rs index 7cb50308..56042e82 100644 --- a/src/conf.rs +++ b/src/conf.rs @@ -836,6 +836,7 @@ mod dotaddressable { impl DotAddressable for bool {} impl DotAddressable for String {} + impl DotAddressable for char {} impl DotAddressable for IndexStyle {} impl DotAddressable for u64 {} impl DotAddressable for crate::terminal::Color {} diff --git a/src/conf/listing.rs b/src/conf/listing.rs index 05dd889f..1d55bda1 100644 --- a/src/conf/listing.rs +++ b/src/conf/listing.rs @@ -90,6 +90,14 @@ pub struct ListingSettings { ///Default: " " #[serde(default)] pub sidebar_mailbox_tree_no_sibling_leaf: Option, + + ///Default: ' ' + #[serde(default = "default_divider")] + pub sidebar_divider: char, +} + +const fn default_divider() -> char { + ' ' } impl Default for ListingSettings { @@ -104,6 +112,7 @@ impl Default for ListingSettings { sidebar_mailbox_tree_no_sibling: None, sidebar_mailbox_tree_has_sibling_leaf: None, sidebar_mailbox_tree_no_sibling_leaf: None, + sidebar_divider: default_divider(), } } } @@ -131,6 +140,7 @@ impl DotAddressable for ListingSettings { "sidebar_mailbox_tree_no_sibling_leaf" => self .sidebar_mailbox_tree_no_sibling_leaf .lookup(field, tail), + "sidebar_divider" => self.sidebar_divider.lookup(field, tail), other => Err(MeliError::new(format!( "{} has no field named {}", parent_field, other diff --git a/src/conf/overrides.rs b/src/conf/overrides.rs index 9acfabaf..e39a5500 100644 --- a/src/conf/overrides.rs +++ b/src/conf/overrides.rs @@ -131,6 +131,9 @@ pub struct ListingSettingsOverride { #[doc = "Default: \" \""] #[serde(default)] pub sidebar_mailbox_tree_no_sibling_leaf: Option>, + #[doc = "Default: ' '"] + #[serde(default)] + pub sidebar_divider: Option, } impl Default for ListingSettingsOverride { fn default() -> Self { @@ -144,6 +147,7 @@ impl Default for ListingSettingsOverride { sidebar_mailbox_tree_no_sibling: None, sidebar_mailbox_tree_has_sibling_leaf: None, sidebar_mailbox_tree_no_sibling_leaf: None, + sidebar_divider: None, } } } diff --git a/src/conf/themes.rs b/src/conf/themes.rs index 1568c587..5ac7c40a 100644 --- a/src/conf/themes.rs +++ b/src/conf/themes.rs @@ -255,6 +255,7 @@ const DEFAULT_KEYS: &[&str] = &[ "widgets.form.highlighted", "widgets.options.highlighted", "mail.sidebar", + "mail.sidebar_divider", "mail.sidebar_account_name", "mail.sidebar_unread_count", "mail.sidebar_index", @@ -1334,6 +1335,7 @@ impl Default for Themes { /* Mail Sidebar */ add!("mail.sidebar"); + add!("mail.sidebar_divider"); add!( "mail.sidebar_account_name", dark = {