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.jmap-eventsource
parent
92c12d3526
commit
daee4e46de
|
@ -193,6 +193,8 @@ widgets.options.highlighted
|
||||||
.It
|
.It
|
||||||
mail.sidebar
|
mail.sidebar
|
||||||
.It
|
.It
|
||||||
|
mail.sidebar_divider
|
||||||
|
.It
|
||||||
mail.sidebar_unread_count
|
mail.sidebar_unread_count
|
||||||
.It
|
.It
|
||||||
mail.sidebar_index
|
mail.sidebar_index
|
||||||
|
|
|
@ -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
|
.It Ic sidebar_mailbox_tree_no_sibling_leaf Ar String
|
||||||
.Pq Em optional
|
.Pq Em optional
|
||||||
Sets the string to print in the mailbox tree for a leaf level where its root has no sibling.
|
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
|
.El
|
||||||
.Ss Examples of sidebar mailbox tree customization
|
.Ss Examples of sidebar mailbox tree customization
|
||||||
The default values
|
The default values
|
||||||
|
|
|
@ -54,7 +54,10 @@ pub struct ContactList {
|
||||||
|
|
||||||
mode: ViewMode,
|
mode: ViewMode,
|
||||||
dirty: bool,
|
dirty: bool,
|
||||||
show_divider: bool,
|
|
||||||
|
sidebar_divider: char,
|
||||||
|
sidebar_divider_theme: ThemeAttribute,
|
||||||
|
|
||||||
menu_visibility: bool,
|
menu_visibility: bool,
|
||||||
movement: Option<PageMovement>,
|
movement: Option<PageMovement>,
|
||||||
cmd_buf: String,
|
cmd_buf: String,
|
||||||
|
@ -98,7 +101,8 @@ impl ContactList {
|
||||||
cmd_buf: String::with_capacity(8),
|
cmd_buf: String::with_capacity(8),
|
||||||
view: None,
|
view: None,
|
||||||
ratio: 90,
|
ratio: 90,
|
||||||
show_divider: false,
|
sidebar_divider: context.settings.listing.sidebar_divider,
|
||||||
|
sidebar_divider_theme: conf::value(context, "mail.sidebar_divider"),
|
||||||
menu_visibility: true,
|
menu_visibility: true,
|
||||||
id: ComponentId::new_v4(),
|
id: ComponentId::new_v4(),
|
||||||
}
|
}
|
||||||
|
@ -239,13 +243,11 @@ impl ContactList {
|
||||||
change_colors(grid, area, fg_color, bg_color);
|
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() {
|
if !self.is_dirty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clear_area(grid, area, self.theme_default);
|
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 upper_left = upper_left!(area);
|
||||||
let bottom_right = bottom_right!(area);
|
let bottom_right = bottom_right!(area);
|
||||||
self.dirty = false;
|
self.dirty = false;
|
||||||
|
@ -580,19 +582,12 @@ impl Component for ContactList {
|
||||||
};
|
};
|
||||||
let mid = get_x(bottom_right) - right_component_width;
|
let mid = get_x(bottom_right) - right_component_width;
|
||||||
if self.dirty && mid != get_x(upper_left) {
|
if self.dirty && mid != get_x(upper_left) {
|
||||||
if self.show_divider {
|
for i in get_y(upper_left)..=get_y(bottom_right) {
|
||||||
for i in get_y(upper_left)..=get_y(bottom_right) {
|
grid[(mid, i)]
|
||||||
grid[(mid, i)]
|
.set_ch(self.sidebar_divider)
|
||||||
.set_ch(VERT_BOUNDARY)
|
.set_fg(self.sidebar_divider_theme.fg)
|
||||||
.set_fg(self.theme_default.fg)
|
.set_bg(self.sidebar_divider_theme.bg)
|
||||||
.set_bg(self.theme_default.bg);
|
.set_attrs(self.sidebar_divider_theme.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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
context
|
context
|
||||||
.dirty_areas
|
.dirty_areas
|
||||||
|
@ -604,7 +599,11 @@ impl Component for ContactList {
|
||||||
} else if right_component_width == 0 {
|
} else if right_component_width == 0 {
|
||||||
self.draw_menu(grid, area, context);
|
self.draw_menu(grid, area, context);
|
||||||
} else {
|
} 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.draw_list(grid, (set_x(upper_left, mid + 1), bottom_right), context);
|
||||||
}
|
}
|
||||||
self.dirty = false;
|
self.dirty = false;
|
||||||
|
|
|
@ -481,7 +481,9 @@ pub struct Listing {
|
||||||
id: ComponentId,
|
id: ComponentId,
|
||||||
theme_default: ThemeAttribute,
|
theme_default: ThemeAttribute,
|
||||||
|
|
||||||
show_divider: bool,
|
sidebar_divider: char,
|
||||||
|
sidebar_divider_theme: ThemeAttribute,
|
||||||
|
|
||||||
menu_visibility: bool,
|
menu_visibility: bool,
|
||||||
cmd_buf: String,
|
cmd_buf: String,
|
||||||
/// This is the width of the right container to the entire width.
|
/// 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;
|
let mid = get_x(bottom_right) - right_component_width;
|
||||||
if self.dirty && mid != get_x(upper_left) {
|
if self.dirty && mid != get_x(upper_left) {
|
||||||
if self.show_divider {
|
for i in get_y(upper_left)..=get_y(bottom_right) {
|
||||||
for i in get_y(upper_left)..=get_y(bottom_right) {
|
grid[(mid, i)]
|
||||||
grid[(mid, i)]
|
.set_ch(self.sidebar_divider)
|
||||||
.set_ch(VERT_BOUNDARY)
|
.set_fg(self.sidebar_divider_theme.fg)
|
||||||
.set_fg(self.theme_default.fg)
|
.set_bg(self.sidebar_divider_theme.bg)
|
||||||
.set_bg(self.theme_default.bg)
|
.set_attrs(self.sidebar_divider_theme.attrs);
|
||||||
.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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
context
|
context
|
||||||
.dirty_areas
|
.dirty_areas
|
||||||
|
@ -579,7 +572,11 @@ impl Component for Listing {
|
||||||
} else if right_component_width == 0 {
|
} else if right_component_width == 0 {
|
||||||
self.draw_menu(grid, area, context);
|
self.draw_menu(grid, area, context);
|
||||||
} else {
|
} 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() {
|
if context.is_online(account_hash).is_err() {
|
||||||
match self.component {
|
match self.component {
|
||||||
ListingComponent::Offline(_) => {}
|
ListingComponent::Offline(_) => {}
|
||||||
|
@ -1435,8 +1432,9 @@ impl Listing {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
let first_account_hash = account_entries[0].hash;
|
||||||
let mut ret = Listing {
|
let mut ret = Listing {
|
||||||
component: Offline(OfflineListing::new((account_entries[0].hash, 0))),
|
component: Offline(OfflineListing::new((first_account_hash, 0))),
|
||||||
accounts: account_entries,
|
accounts: account_entries,
|
||||||
status: None,
|
status: None,
|
||||||
visible: true,
|
visible: true,
|
||||||
|
@ -1446,7 +1444,10 @@ impl Listing {
|
||||||
startup_checks_rate: RateLimit::new(2, 1000, context.job_executor.clone()),
|
startup_checks_rate: RateLimit::new(2, 1000, context.job_executor.clone()),
|
||||||
theme_default: conf::value(context, "theme_default"),
|
theme_default: conf::value(context, "theme_default"),
|
||||||
id: ComponentId::new_v4(),
|
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,
|
menu_visibility: true,
|
||||||
ratio: 90,
|
ratio: 90,
|
||||||
menu_width: WidgetWidth::Unset,
|
menu_width: WidgetWidth::Unset,
|
||||||
|
@ -1457,13 +1458,11 @@ impl Listing {
|
||||||
ret
|
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() {
|
if !self.is_dirty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clear_area(grid, area, self.theme_default);
|
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 upper_left = upper_left!(area);
|
||||||
let bottom_right = bottom_right!(area);
|
let bottom_right = bottom_right!(area);
|
||||||
self.dirty = false;
|
self.dirty = false;
|
||||||
|
@ -1770,6 +1769,7 @@ impl Listing {
|
||||||
/* Set to dummy */
|
/* Set to dummy */
|
||||||
self.component = Offline(OfflineListing::new((account_hash, 0)));
|
self.component = Offline(OfflineListing::new((account_hash, 0)));
|
||||||
}
|
}
|
||||||
|
self.sidebar_divider = *account_settings!(context[account_hash].listing.sidebar_divider);
|
||||||
self.status = None;
|
self.status = None;
|
||||||
self.set_dirty(true);
|
self.set_dirty(true);
|
||||||
context
|
context
|
||||||
|
|
|
@ -836,6 +836,7 @@ mod dotaddressable {
|
||||||
impl DotAddressable for bool {}
|
impl DotAddressable for bool {}
|
||||||
|
|
||||||
impl DotAddressable for String {}
|
impl DotAddressable for String {}
|
||||||
|
impl DotAddressable for char {}
|
||||||
impl DotAddressable for IndexStyle {}
|
impl DotAddressable for IndexStyle {}
|
||||||
impl DotAddressable for u64 {}
|
impl DotAddressable for u64 {}
|
||||||
impl DotAddressable for crate::terminal::Color {}
|
impl DotAddressable for crate::terminal::Color {}
|
||||||
|
|
|
@ -90,6 +90,14 @@ pub struct ListingSettings {
|
||||||
///Default: " "
|
///Default: " "
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub sidebar_mailbox_tree_no_sibling_leaf: Option<String>,
|
pub sidebar_mailbox_tree_no_sibling_leaf: Option<String>,
|
||||||
|
|
||||||
|
///Default: ' '
|
||||||
|
#[serde(default = "default_divider")]
|
||||||
|
pub sidebar_divider: char,
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn default_divider() -> char {
|
||||||
|
' '
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ListingSettings {
|
impl Default for ListingSettings {
|
||||||
|
@ -104,6 +112,7 @@ impl Default for ListingSettings {
|
||||||
sidebar_mailbox_tree_no_sibling: None,
|
sidebar_mailbox_tree_no_sibling: None,
|
||||||
sidebar_mailbox_tree_has_sibling_leaf: None,
|
sidebar_mailbox_tree_has_sibling_leaf: None,
|
||||||
sidebar_mailbox_tree_no_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" => self
|
||||||
.sidebar_mailbox_tree_no_sibling_leaf
|
.sidebar_mailbox_tree_no_sibling_leaf
|
||||||
.lookup(field, tail),
|
.lookup(field, tail),
|
||||||
|
"sidebar_divider" => self.sidebar_divider.lookup(field, tail),
|
||||||
other => Err(MeliError::new(format!(
|
other => Err(MeliError::new(format!(
|
||||||
"{} has no field named {}",
|
"{} has no field named {}",
|
||||||
parent_field, other
|
parent_field, other
|
||||||
|
|
|
@ -131,6 +131,9 @@ pub struct ListingSettingsOverride {
|
||||||
#[doc = "Default: \" \""]
|
#[doc = "Default: \" \""]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub sidebar_mailbox_tree_no_sibling_leaf: Option<Option<String>>,
|
pub sidebar_mailbox_tree_no_sibling_leaf: Option<Option<String>>,
|
||||||
|
#[doc = "Default: ' '"]
|
||||||
|
#[serde(default)]
|
||||||
|
pub sidebar_divider: Option<char>,
|
||||||
}
|
}
|
||||||
impl Default for ListingSettingsOverride {
|
impl Default for ListingSettingsOverride {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
@ -144,6 +147,7 @@ impl Default for ListingSettingsOverride {
|
||||||
sidebar_mailbox_tree_no_sibling: None,
|
sidebar_mailbox_tree_no_sibling: None,
|
||||||
sidebar_mailbox_tree_has_sibling_leaf: None,
|
sidebar_mailbox_tree_has_sibling_leaf: None,
|
||||||
sidebar_mailbox_tree_no_sibling_leaf: None,
|
sidebar_mailbox_tree_no_sibling_leaf: None,
|
||||||
|
sidebar_divider: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,6 +255,7 @@ const DEFAULT_KEYS: &[&str] = &[
|
||||||
"widgets.form.highlighted",
|
"widgets.form.highlighted",
|
||||||
"widgets.options.highlighted",
|
"widgets.options.highlighted",
|
||||||
"mail.sidebar",
|
"mail.sidebar",
|
||||||
|
"mail.sidebar_divider",
|
||||||
"mail.sidebar_account_name",
|
"mail.sidebar_account_name",
|
||||||
"mail.sidebar_unread_count",
|
"mail.sidebar_unread_count",
|
||||||
"mail.sidebar_index",
|
"mail.sidebar_index",
|
||||||
|
@ -1334,6 +1335,7 @@ impl Default for Themes {
|
||||||
/* Mail Sidebar */
|
/* Mail Sidebar */
|
||||||
|
|
||||||
add!("mail.sidebar");
|
add!("mail.sidebar");
|
||||||
|
add!("mail.sidebar_divider");
|
||||||
add!(
|
add!(
|
||||||
"mail.sidebar_account_name",
|
"mail.sidebar_account_name",
|
||||||
dark = {
|
dark = {
|
||||||
|
|
Loading…
Reference in New Issue