diff options
author | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2020-02-04 15:52:12 +0200 |
---|---|---|
committer | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2020-02-04 17:29:55 +0200 |
commit | 8b6ea8de9a89b3ad42276eb7835992f7b875128b (patch) | |
tree | 864a7136b4c23d76761ee3e7d034307f8c302838 /ui/src/components | |
parent | 6fcc792b83f715644c041f728049de65f7da2e38 (diff) |
Remove ui crate
Merge ui crate with root crate.
In preparation for uploading `meli` as a separate crate on crates.io.
Workspace crates will need to be published as well and having a separate
`ui` crate and binary perhaps doesn't make sense anymore.
Diffstat (limited to 'ui/src/components')
-rw-r--r-- | ui/src/components/contacts.rs | 307 | ||||
-rw-r--r-- | ui/src/components/contacts/contact_list.rs | 897 | ||||
-rw-r--r-- | ui/src/components/indexer.rs | 134 | ||||
-rw-r--r-- | ui/src/components/indexer/index.rs | 185 | ||||
-rw-r--r-- | ui/src/components/mail.rs | 48 | ||||
-rw-r--r-- | ui/src/components/mail/compose.rs | 1219 | ||||
-rw-r--r-- | ui/src/components/mail/listing.rs | 1192 | ||||
-rw-r--r-- | ui/src/components/mail/listing/compact.rs | 1381 | ||||
-rw-r--r-- | ui/src/components/mail/listing/conversations.rs | 1339 | ||||
-rw-r--r-- | ui/src/components/mail/listing/plain.rs | 1243 | ||||
-rw-r--r-- | ui/src/components/mail/listing/thread.rs | 689 | ||||
-rw-r--r-- | ui/src/components/mail/pgp.rs | 130 | ||||
-rw-r--r-- | ui/src/components/mail/status.rs | 670 | ||||
-rw-r--r-- | ui/src/components/mail/view.rs | 1464 | ||||
-rw-r--r-- | ui/src/components/mail/view/envelope.rs | 571 | ||||
-rw-r--r-- | ui/src/components/mail/view/html.rs | 174 | ||||
-rw-r--r-- | ui/src/components/mail/view/thread.rs | 1152 | ||||
-rw-r--r-- | ui/src/components/notifications.rs | 209 | ||||
-rw-r--r-- | ui/src/components/utilities.rs | 2451 | ||||
-rw-r--r-- | ui/src/components/utilities/widgets.rs | 979 |
20 files changed, 0 insertions, 16434 deletions
diff --git a/ui/src/components/contacts.rs b/ui/src/components/contacts.rs deleted file mode 100644 index 91907a58..00000000 --- a/ui/src/components/contacts.rs +++ /dev/null @@ -1,307 +0,0 @@ -/* - * meli - contacts module - * - * Copyright 2019 Manos Pitsidianakis - * - * This file is part of meli. - * - * meli is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * meli is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with meli. If not, see <http://www.gnu.org/licenses/>. - */ - -use super::*; -use fnv::FnvHashMap; - -mod contact_list; - -pub use self::contact_list::*; - -#[derive(Debug)] -enum ViewMode { - ReadOnly, - Discard(Selector<char>), - Edit, - //New, -} - -#[derive(Debug)] -pub struct ContactManager { - id: ComponentId, - parent_id: ComponentId, - pub card: Card, - mode: ViewMode, - form: FormWidget, - account_pos: usize, - content: CellBuffer, - dirty: bool, - has_changes: bool, - - initialized: bool, -} - -impl Default for ContactManager { - fn default() -> Self { - ContactManager { - id: Uuid::nil(), - parent_id: Uuid::nil(), - card: Card::new(), - mode: ViewMode::Edit, - form: FormWidget::default(), - account_pos: 0, - content: CellBuffer::new(100, 1, Cell::with_char(' ')), - dirty: true, - has_changes: false, - initialized: false, - } - } -} - -impl fmt::Display for ContactManager { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "contacts") - } -} - -impl ContactManager { - fn initialize(&mut self) { - let (width, _) = self.content.size(); - - let (x, _) = write_string_to_grid( - "Last edited: ", - &mut self.content, - Color::Byte(250), - Color::Default, - Attr::Default, - ((0, 0), (width - 1, 0)), - None, - ); - let (x, y) = write_string_to_grid( - &self.card.last_edited(), - &mut self.content, - Color::Byte(250), - Color::Default, - Attr::Default, - ((x, 0), (width - 1, 0)), - None, - ); - - if self.card.external_resource() { - self.mode = ViewMode::ReadOnly; - self.content - .resize(self.content.size().0, 2, Cell::default()); - write_string_to_grid( - "This contact's origin is external and cannot be edited within meli.", - &mut self.content, - Color::Byte(250), - Color::Default, - Attr::Default, - ((x, y), (width - 1, y)), - None, - ); - } - - self.form = FormWidget::new("Save".into()); - self.form.add_button(("Cancel(Esc)".into(), false)); - self.form - .push(("NAME".into(), self.card.name().to_string())); - self.form.push(( - "ADDITIONAL NAME".into(), - self.card.additionalname().to_string(), - )); - self.form - .push(("NAME PREFIX".into(), self.card.name_prefix().to_string())); - self.form - .push(("NAME SUFFIX".into(), self.card.name_suffix().to_string())); - self.form - .push(("E-MAIL".into(), self.card.email().to_string())); - self.form.push(("URL".into(), self.card.url().to_string())); - self.form.push(("KEY".into(), self.card.key().to_string())); - for (k, v) in self.card.extra_properties() { - self.form.push((k.to_string(), v.to_string())); - } - } - - pub fn set_parent_id(&mut self, new_val: ComponentId) { - self.parent_id = new_val; - } -} - -impl Component for ContactManager { - fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) { - if !self.initialized { - self.initialize(); - self.initialized = true; - } - - let upper_left = upper_left!(area); - let bottom_right = bottom_right!(area); - - if self.dirty { - let (width, _height) = self.content.size(); - clear_area( - grid, - (upper_left, set_y(bottom_right, get_y(upper_left) + 1)), - ); - copy_area_with_break(grid, &self.content, area, ((0, 0), (width - 1, 0))); - self.dirty = false; - } - - self.form.draw( - grid, - (set_y(upper_left, get_y(upper_left) + 2), bottom_right), - context, - ); - match self.mode { - ViewMode::Discard(ref mut selector) => { - /* Let user choose whether to quit with/without saving or cancel */ - selector.draw(grid, center_area(area, selector.content.size()), context); - } - _ => {} - } - - context.dirty_areas.push_back(area); - } - - fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool { - match self.mode { - ViewMode::Discard(ref mut selector) => { - if selector.process_event(event, context) { - if selector.is_done() { - let s = match std::mem::replace(&mut self.mode, ViewMode::Edit) { - ViewMode::Discard(s) => s, - _ => unreachable!(), - }; - let key = s.collect()[0] as char; - match key { - 'x' => { - context - .replies - .push_back(UIEvent::Action(Tab(Kill(self.parent_id)))); - return true; - } - 'n' => {} - 'y' => {} - _ => {} - } - } - self.set_dirty(true); - return true; - } - } - ViewMode::Edit => { - if let &mut UIEvent::Input(Key::Esc) = event { - if self.can_quit_cleanly(context) { - context - .replies - .push_back(UIEvent::Action(Tab(Kill(self.parent_id)))); - } - return true; - } - if self.form.process_event(event, context) { - match self.form.buttons_result() { - None => {} - Some(true) => { - let fields = std::mem::replace(&mut self.form, FormWidget::default()) - .collect() - .unwrap(); - let fields: FnvHashMap<String, String> = fields - .into_iter() - .map(|(s, v)| { - ( - s, - match v { - Field::Text(v, _) => v.as_str().to_string(), - Field::Choice(mut v, c) => v.remove(c), - }, - ) - }) - .collect(); - let mut new_card = Card::from(fields); - new_card.set_id(*self.card.id()); - context.accounts[self.account_pos] - .address_book - .add_card(new_card); - context.replies.push_back(UIEvent::StatusEvent( - StatusEvent::DisplayMessage("Saved.".into()), - )); - context.replies.push_back(UIEvent::ComponentKill(self.id)); - } - Some(false) => { - context.replies.push_back(UIEvent::ComponentKill(self.id)); - } - } - self.set_dirty(true); - if let UIEvent::InsertInput(_) = event { - self.has_changes = true; - } - return true; - } - } - ViewMode::ReadOnly => { - if let &mut UIEvent::Input(Key::Esc) = event { - if self.can_quit_cleanly(context) { - context.replies.push_back(UIEvent::ComponentKill(self.id)); - } - return true; - } - } - } - false - } - - fn is_dirty(&self) -> bool { - self.dirty - || self.form.is_dirty() - || if let ViewMode::Discard(ref selector) = self.mode { - selector.is_dirty() - } else { - false - } - } - - fn set_dirty(&mut self, value: bool) { - self.dirty = value; - self.form.set_dirty(value); - if let ViewMode::Discard(ref mut selector) = self.mode { - selector.set_dirty(value); - } - } - - fn id(&self) -> ComponentId { - self.id - } - - fn set_id(&mut self, id: ComponentId) { - self.id = id; - } - - fn can_quit_cleanly(&mut self, context: &Context) -> bool { - if !self.has_changes { - return true; - } - - /* Play it safe and ask user for confirmation */ - self.mode = ViewMode::Discard(Selector::new( - "this contact has unsaved changes", - vec![ - ('x', "quit without saving".to_string()), - ('y', "save draft and quit".to_string()), - ('n', "cancel".to_string()), - ], - true, - context, - )); - self.set_dirty(true); - false - } -} diff --git a/ui/src/components/contacts/contact_list.rs b/ui/src/components/contacts/contact_list.rs deleted file mode 100644 index a79d4cfd..00000000 --- a/ui/src/components/contacts/contact_list.rs +++ /dev/null @@ -1,897 +0,0 @@ -/* - * meli - * - * Copyright 2019 Manos Pitsidianakis - * - * This file is part of meli. - * - * meli is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * meli is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with meli. If not, see <http://www.gnu.org/licenses/>. - */ -use super::*; - -use melib::CardId; -use std::cmp; - -const MAX_COLS: usize = 500; - -#[derive(Debug, PartialEq)] -enum ViewMode { - List, - View(ComponentId), -} - -#[derive(Debug)] -struct AccountMenuEntry { - name: String, - // Index in the config account vector. - index: usize, -} - -#[derive(Debug)] -pub struct ContactList { - accounts: Vec<AccountMenuEntry>, - cursor_pos: usize, - new_cursor_pos: usize, - account_pos: usize, - length: usize, - data_columns: DataColumns, - initialized: bool, - - id_positions: Vec<CardId>, - - mode: ViewMode, - dirty: bool, - show_divider: bool, - menu_visibility: bool, - movement: Option<PageMovement>, - cmd_buf: String, - view: Option<ContactManager>, - ratio: usize, // right/(container width) * 100 - id: ComponentId, -} - -impl fmt::Display for ContactList { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", ContactList::DESCRIPTION) - } -} - -impl ContactList { - const DESCRIPTION: &'static str = "contact list"; - pub fn new(context: &Context) -> Self { - let accounts = context - .accounts - .iter() - .enumerate() - .map(|(i, a)| AccountMenuEntry { - name: a.name().to_string(), - index: i, - }) - .collect(); - ContactList { - accounts, - cursor_pos: 0, - new_cursor_pos: 0, - length: 0, - account_pos: 0, - id_positions: Vec::new(), - mode: ViewMode::List, - data_columns: DataColumns::default(), - initialized: false, - dirty: true, - movement: None, - cmd_buf: String::with_capacity(8), - view: None, - ratio: 90, - show_divider: false, - menu_visibility: true, - id: ComponentId::new_v4(), - } - } - - pub fn for_account(pos: usize, context: &Context) -> Self { - ContactList { - account_pos: pos, - ..Self::new(context) - } - } - - fn initialize(&mut self, context: &mut Context) { - let account = &context.accounts[self.account_pos]; - let book = &account.address_book; - self.length = book.len(); - - self.id_positions.clear(); - if self.id_positions.capacity() < book.len() { - self.id_positions.reserve(book.len()); - } - self.dirty = true; - let mut min_width = ("Name".len(), "E-mail".len(), 0, "external".len(), 0, 0); - - for c in book.values() { - /* name */ - min_width.0 = cmp::max(min_width.0, c.name().split_graphemes().len()); - /* email */ - min_width.1 = cmp::max(min_width.1, c.email().split_graphemes().len()); - /* url */ - min_width.2 = cmp::max(min_width.2, c.url().split_graphemes().len()); - } - - /* name column */ - self.data_columns.columns[0] = - CellBuffer::new_with_context(min_width.0, self.length, Cell::with_char(' '), context); - /* email column */ - self.data_columns.columns[1] = - CellBuffer::new_with_context(min_width.1, self.length, Cell::with_char(' '), context); - /* url column */ - self.data_columns.columns[2] = - CellBuffer::new_with_context(min_width.2, self.length, Cell::with_char(' '), context); - /* source column */ - self.data_columns.columns[3] = CellBuffer::new_with_context( - "external".len(), - self.length, - Cell::with_char(' '), - context, - ); - - let account = &context.accounts[self.account_pos]; - let book = &account.address_book; - let mut book_values = book.values().collect::<Vec<&Card>>(); - book_values.sort_unstable_by_key(|c| c.name()); - for (idx, c) in book_values.iter().enumerate() { - self.id_positions.push(*c.id()); - - write_string_to_grid( - c.name(), - &mut self.data_columns.columns[0], - Color::Default, - Color::Default, - Attr::Default, - ((0, idx), (min_width.0, idx)), - None, - ); - - write_string_to_grid( - c.email(), - &mut self.data_columns.columns[1], - Color::Default, - Color::Default, - Attr::Default, - ((0, idx), (min_width.1, idx)), - None, - ); - - write_string_to_grid( - c.url(), - &mut self.data_columns.columns[2], - Color::Default, - Color::Default, - Attr::Default, - ((0, idx), (min_width.2, idx)), - None, - ); - - write_string_to_grid( - if c.external_resource() { - "external" - } else { - "local" - }, - &mut self.data_columns.columns[3], - Color::Default, - Color::Default, - Attr::Default, - ((0, idx), (min_width.3, idx)), - None, - ); - } - - if self.length == 0 { - let message = "Address book is empty.".to_string(); - self.data_columns.columns[0] = CellBuffer::new_with_context( - message.len(), - self.length, - Cell::with_char(' '), - context, - ); - write_string_to_grid( - &message, - &mut self.data_columns.columns[0], - Color::Default, - Color::Default, - Attr::Default, - ((0, 0), (MAX_COLS - 1, 0)), - None, - ); - return; - } - } - - fn highlight_line(&mut self, grid: &mut CellBuffer, area: Area, idx: usize) { - /* Reset previously highlighted line */ - let fg_color = Color::Default; - let bg_color = if idx == self.new_cursor_pos { - Color::Byte(246) - } else { - Color::Default - }; - change_colors(grid, area, fg_color, bg_color); - } - - fn draw_menu(&mut self, grid: &mut CellBuffer, mut area: Area, context: &mut Context) { - if !self.is_dirty() { - return; - } - clear_area(grid, area); - /* 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; - let mut y = get_y(upper_left); - for a in &self.accounts { - self.print_account(grid, (set_y(upper_left, y), bottom_right), &a, context); - y += 1; - } - - context.dirty_areas.push_back(area); - } - /* - * Print a single account in the menu area. - */ - fn print_account( - &self, - grid: &mut CellBuffer, - area: Area, - a: &AccountMenuEntry, - context: &mut Context, - ) { - if !is_valid_area!(area) { - debug!("BUG: invalid area in print_account"); - } - - let width = width!(area); - let must_highlight_account: bool = self.account_pos == a.index; - let (fg_color, bg_color) = if must_highlight_account { - if self.account_pos == a.index { - (Color::Byte(233), Color::Byte(15)) - } else { - (Color::Byte(15), Color::Byte(233)) - } - } else { - (Color::Default, Color::Default) - }; - - let s = format!(" [{}]", context.accounts[a.index].address_book.len()); - - if a.name.grapheme_len() + s.len() > width + 1 { - /* Print account name */ - let (x, y) = - write_string_to_grid(&a.name, grid, fg_color, bg_color, Attr::Bold, area, None); - write_string_to_grid( - &s, - grid, - fg_color, - bg_color, - Attr::Bold, - ( - pos_dec( - (get_x(bottom_right!(area)), get_y(upper_left!(area))), - (s.len() - 1, 0), - ), - bottom_right!(area), - ), - None, - ); - write_string_to_grid( - "…", - grid, - fg_color, - bg_color, - Attr::Bold, - ( - pos_dec( - (get_x(bottom_right!(area)), get_y(upper_left!(area))), - (s.len() - 1, 0), - ), - bottom_right!(area), - ), - None, - ); - - for x in x..=get_x(bottom_right!(area)) { - grid[(x, y)].set_fg(fg_color); - grid[(x, y)].set_bg(bg_color); - } - } else { - /* Print account name */ - - let (x, y) = - write_string_to_grid(&a.name, grid, fg_color, bg_color, Attr::Bold, area, None); - write_string_to_grid( - &s, - grid, - fg_color, - bg_color, - Attr::Bold, - ( - pos_dec( - (get_x(bottom_right!(area)), get_y(upper_left!(area))), - (s.len() - 1, 0), - ), - bottom_right!(area), - ), - None, - ); - for x in x..=get_x(bottom_right!(area)) { - grid[(x, y)].set_fg(fg_color); - grid[(x, y)].set_bg(bg_color); - } - } - } - - fn draw_list(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) { - /* reserve top row for column headers */ - let upper_left = pos_inc(upper_left!(area), (0, 1)); - let bottom_right = bottom_right!(area); - - if self.length == 0 { - clear_area(grid, area); - copy_area( - grid, - &self.data_columns.columns[0], - area, - ((0, 0), pos_dec(self.data_columns.columns[0].size(), (1, 1))), - ); - context.dirty_areas.push_back(area); - return; - } - let rows = get_y(bottom_right) - get_y(upper_left) + 1; - - if let Some(mvm) = self.movement.take() { - match mvm { - PageMovement::Up(amount) => { - self.new_cursor_pos = self.new_cursor_pos.saturating_sub(amount); - } - PageMovement::PageUp(multiplier) => { - self.new_cursor_pos = self.new_cursor_pos.saturating_sub(rows * multiplier); - } - PageMovement::Down(amount) => { - if self.new_cursor_pos + amount < self.length { - self.new_cursor_pos += amount; - } else { - self.new_cursor_pos = self.length - 1; - } - } - PageMovement::PageDown(multiplier) => { - if self.new_cursor_pos + rows * multiplier < self.length { - self.new_cursor_pos += rows * multiplier; - } else if self.new_cursor_pos + rows * multiplier > self.length { - self.new_cursor_pos = self.length - 1; - } else { - self.new_cursor_pos = (self.length / rows) * rows; - } - } - PageMovement::Right(_) | PageMovement::Left(_) => {} - PageMovement::Home => { - self.new_cursor_pos = 0; - } - PageMovement::End => { - self.new_cursor_pos = self.length - 1; - } - } - } - - let prev_page_no = (self.cursor_pos).wrapping_div(rows); - let page_no = (self.new_cursor_pos).wrapping_div(rows); - - let top_idx = page_no * rows; - - /* If cursor position has changed, remove the highlight from the previous position and - * apply it in the new one. */ - if self.cursor_pos != self.new_cursor_pos && prev_page_no == page_no { - let old_cursor_pos = self.cursor_pos; - self.cursor_pos = self.new_cursor_pos; - for idx in &[old_cursor_pos, self.new_cursor_pos] { - if *idx >= self.length { - continue; //bounds check - } - let new_area = ( - set_y(upper_left, get_y(upper_left) + (*idx % rows)), - set_y(bottom_right, get_y(upper_left) + (*idx % rows)), - ); - self.highlight_line(grid, new_area, *idx); - context.dirty_areas.push_back(new_area); - } - return; - } else if self.cursor_pos != self.new_cursor_pos { - self.cursor_pos = self.new_cursor_pos; - } - if self.new_cursor_pos >= self.length { - self.new_cursor_pos = self.length - 1; - self.cursor_pos = self.new_cursor_pos; - } - - let width = width!(area); - self.data_columns.widths = Default::default(); - self.data_columns.widths[0] = self.data_columns.columns[0].size().0; /* name */ - self.data_columns.widths[1] = self.data_columns.columns[1].size().0; /* email*/ - self.data_columns.widths[2] = self.data_columns.columns[2].size().0; /* url */ - self.data_columns.widths[3] = self.data_columns.columns[3].size().0; /* source */ - - let min_col_width = std::cmp::min( - 15, - std::cmp::min(self.data_columns.widths[0], self.data_columns.widths[1]), - ); - if self.data_columns.widths[0] + self.data_columns.widths[1] + 3 * min_col_width + 8 > width - { - let remainder = - width.saturating_sub(self.data_columns.widths[0] + self.data_columns.widths[1] + 4); - self.data_columns.widths[2] = remainder / 6; - } - clear_area(grid, area); - /* Page_no has changed, so draw new page */ - let mut x = get_x(upper_left); - for i in 0..self.data_columns.columns.len() { - if self.data_columns.widths[i] == 0 { - continue; - } - let (column_width, column_height) = self.data_columns.columns[i].size(); - write_string_to_grid( - match i { - 0 => "NAME", - 1 => "E-MAIL", - 2 => "URL", - 3 => "SOURCE", - _ => "", - }, - grid, - Color::Black, - Color::White, - Attr::Bold, - ( - set_x(upper_left!(area), x), - ( - std::cmp::min(get_x(bottom_right), x + (self.data_columns.widths[i])), - get_y(upper_left!(area)), - ), - ), - None, - ); - copy_area( - grid, - &self.data_columns.columns[i], - ( - set_x(upper_left, x), - set_x( - bottom_right, - std::cmp::min(get_x(bottom_right), x + (self.data_columns.widths[i])), - ), - ), - ( - (0, top_idx), - ( - column_width.saturating_sub(1), - column_height.saturating_sub(1), - ), - ), - ); - x += self.data_columns.widths[i] + 2; // + SEPARATOR - if x > get_x(bottom_right) { - break; - } - } - - change_colors( - grid, - ( - upper_left!(area), - set_y(bottom_right, get_y(upper_left!(area))), - ), - Color::Black, - Color::White, - ); - - if top_idx + rows > self.length { - clear_area( - grid, - ( - pos_inc(upper_left, (0, self.length - top_idx + 2)), - bottom_right, - ), - ); - } - self.highlight_line( - grid, - ( - set_y(upper_left, get_y(upper_left) + (self.cursor_pos % rows)), - set_y(bottom_right, get_y(upper_left) + (self.cursor_pos % rows)), - ), - self.cursor_pos, - ); - context.dirty_areas.push_back(area); - } -} - -impl Component for ContactList { - fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) { - if let Some(mgr) = self.view.as_mut() { - mgr.draw(grid, area, context); - return; - } - - if !self.dirty { - return; - } - if !self.initialized { - self.initialize(context); - } - - let upper_left = upper_left!(area); - let bottom_right = bottom_right!(area); - let total_cols = get_x(bottom_right) - get_x(upper_left); - - let right_component_width = if self.menu_visibility { - (self.ratio * total_cols) / 100 - } else { - total_cols - }; - 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); - grid[(mid, i)].set_fg(Color::Default); - grid[(mid, i)].set_bg(Color::Default); - } - } else { - for i in get_y(upper_left)..=get_y(bottom_right) { - grid[(mid, i)].set_fg(Color::Default); - grid[(mid, i)].set_bg(Color::Default); - } - } - context - .dirty_areas - .push_back(((mid, get_y(upper_left)), (mid, get_y(bottom_right)))); - } - - if right_component_width == total_cols { - self.draw_list(grid, area, co |