meli/terminal: replace change_color uses with change_theme

change_color() predated addition of Cell Attributes (Bold, Underline,
etc) so it didn't accept an attribute argument.

This commit adds a change_theme() function that does the same thing as
change_color() but also sets the cell attributes. It also takes a
ThemeAttribute as an argument instead of {fg, bg, attrs} individually.

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/284/head
Manos Pitsidianakis 2023-08-21 12:45:15 +03:00
parent a1e7006186
commit f93adb683a
Signed by: Manos Pitsidianakis
GPG Key ID: 7729C7707F7E09D0
13 changed files with 133 additions and 114 deletions

View File

@ -220,13 +220,16 @@ impl ContactList {
fn highlight_line(&mut self, grid: &mut CellBuffer, area: Area, idx: usize) {
/* Reset previously highlighted line */
let fg_color = self.theme_default.fg;
let bg_color = if idx == self.new_cursor_pos {
self.highlight_theme.bg
let mut theme = if idx == self.new_cursor_pos {
self.highlight_theme
} else {
self.theme_default.bg
self.theme_default
};
change_colors(grid, area, fg_color, bg_color);
theme.fg = self.theme_default.fg;
if !grid.use_color {
theme.attrs |= Attr::REVERSE;
}
change_theme(grid, area, theme);
}
fn draw_menu(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
@ -533,14 +536,13 @@ impl ContactList {
}
}
change_colors(
change_theme(
grid,
(
upper_left!(area),
set_y(bottom_right, get_y(upper_left!(area))),
),
header_attrs.fg,
header_attrs.bg,
header_attrs,
);
if top_idx + rows > self.length {

View File

@ -925,14 +925,13 @@ impl Component for Composer {
None,
);
clear_area(grid, ((x, y), (set_y(bottom_right, y))), theme_default);
change_colors(
change_theme(
grid,
(
set_x(pos_dec(upper_left!(header_area), (0, 1)), x),
set_y(bottom_right!(header_area), y),
),
crate::conf::value(context, "highlight").fg,
crate::conf::value(context, "highlight").bg,
crate::conf::value(context, "highlight"),
);
clear_area(
grid,
@ -1054,7 +1053,7 @@ impl Component for Composer {
match self.cursor {
Cursor::Headers => {
change_colors(
change_theme(
grid,
(
pos_dec(upper_left!(body_area), (1, 0)),
@ -1063,12 +1062,11 @@ impl Component for Composer {
(1, 0),
),
),
theme_default.fg,
theme_default.bg,
theme_default,
);
}
Cursor::Body => {
change_colors(
change_theme(
grid,
(
pos_dec(upper_left!(body_area), (1, 0)),
@ -1077,8 +1075,15 @@ impl Component for Composer {
(1, 0),
),
),
theme_default.fg,
crate::conf::value(context, "highlight").bg,
ThemeAttribute {
fg: theme_default.fg,
bg: crate::conf::value(context, "highlight").bg,
attrs: if grid.use_color {
crate::conf::value(context, "highlight").attrs
} else {
crate::conf::value(context, "highlight").attrs | Attr::REVERSE
},
},
);
}
Cursor::Sign | Cursor::Encrypt | Cursor::Attachments => {}

View File

@ -757,9 +757,9 @@ impl ListingTrait for CompactListing {
.draw(grid, idx, self.cursor_pos.2, grid.bounds_iter(new_area));
if highlight {
let row_attr = row_attr!(self.color_cache, idx % 2 == 0, false, true, false);
change_colors(grid, new_area, row_attr.fg, row_attr.bg);
change_theme(grid, new_area, row_attr);
} else if let Some(row_attr) = self.rows.row_attr_cache.get(&idx) {
change_colors(grid, new_area, row_attr.fg, row_attr.bg);
change_theme(grid, new_area, *row_attr);
}
context.dirty_areas.push_back(new_area);
}
@ -785,7 +785,7 @@ impl ListingTrait for CompactListing {
/* apply each row colors separately */
for i in top_idx..(top_idx + height!(area)) {
if let Some(row_attr) = self.rows.row_attr_cache.get(&i) {
change_colors(grid, nth_row_area(area, i % rows), row_attr.fg, row_attr.bg);
change_theme(grid, nth_row_area(area, i % rows), *row_attr);
}
}
@ -797,12 +797,7 @@ impl ListingTrait for CompactListing {
true,
false
);
change_colors(
grid,
nth_row_area(area, self.cursor_pos.2 % rows),
row_attr.fg,
row_attr.bg,
);
change_theme(grid, nth_row_area(area, self.cursor_pos.2 % rows), row_attr);
/* clear gap if available height is more than count of entries */
if top_idx + rows > self.length {

View File

@ -474,9 +474,9 @@ impl ListingTrait for PlainListing {
.draw(grid, idx, self.cursor_pos.2, grid.bounds_iter(new_area));
if highlight {
let row_attr = row_attr!(self.color_cache, idx % 2 == 0, false, true, false);
change_colors(grid, new_area, row_attr.fg, row_attr.bg);
change_theme(grid, new_area, row_attr);
} else if let Some(row_attr) = self.rows.row_attr_cache.get(&idx) {
change_colors(grid, new_area, row_attr.fg, row_attr.bg);
change_theme(grid, new_area, *row_attr);
}
context.dirty_areas.push_back(new_area);
}
@ -502,7 +502,7 @@ impl ListingTrait for PlainListing {
/* apply each row colors separately */
for i in top_idx..(top_idx + height!(area)) {
if let Some(row_attr) = self.rows.row_attr_cache.get(&i) {
change_colors(grid, nth_row_area(area, i % rows), row_attr.fg, row_attr.bg);
change_theme(grid, nth_row_area(area, i % rows), *row_attr);
}
}
@ -514,12 +514,7 @@ impl ListingTrait for PlainListing {
true,
false
);
change_colors(
grid,
nth_row_area(area, self.cursor_pos.2 % rows),
row_attr.fg,
row_attr.bg,
);
change_theme(grid, nth_row_area(area, self.cursor_pos.2 % rows), row_attr);
/* clear gap if available height is more than count of entries */
if top_idx + rows > self.length {

View File

@ -541,9 +541,9 @@ impl ListingTrait for ThreadListing {
.draw(grid, idx, self.cursor_pos.2, grid.bounds_iter(new_area));
if highlight {
let row_attr = row_attr!(self.color_cache, idx % 2 == 0, false, true, false);
change_colors(grid, new_area, row_attr.fg, row_attr.bg);
change_theme(grid, new_area, row_attr);
} else if let Some(row_attr) = self.rows.row_attr_cache.get(&idx) {
change_colors(grid, new_area, row_attr.fg, row_attr.bg);
change_theme(grid, new_area, *row_attr);
}
context.dirty_areas.push_back(new_area);
}
@ -581,7 +581,7 @@ impl ListingTrait for ThreadListing {
/* apply each row colors separately */
for i in top_idx..(top_idx + height!(area)) {
if let Some(row_attr) = self.rows.row_attr_cache.get(&i) {
change_colors(grid, nth_row_area(area, i % rows), row_attr.fg, row_attr.bg);
change_theme(grid, nth_row_area(area, i % rows), *row_attr);
}
}
@ -593,12 +593,7 @@ impl ListingTrait for ThreadListing {
true,
false
);
change_colors(
grid,
nth_row_area(area, self.cursor_pos.2 % rows),
row_attr.fg,
row_attr.bg,
);
change_theme(grid, nth_row_area(area, self.cursor_pos.2 % rows), row_attr);
/* clear gap if available height is more than count of entries */
if top_idx + rows > self.length {

View File

@ -336,7 +336,7 @@ impl ThreadView {
if let Some(len) = highlight_reply_subjects[y] {
let index = e.index.0 * 4 + 1 + e.heading.grapheme_width() - len;
let area = ((index, 2 * y), (width - 2, 2 * y));
change_colors(&mut content, area, highlight_theme.fg, theme_default.bg);
change_theme(&mut content, area, highlight_theme);
}
set_and_join_box(&mut content, (e.index.0 * 4, 2 * y), BoxBoundary::Vertical);
set_and_join_box(
@ -357,12 +357,7 @@ impl ThreadView {
for i in 0..e.index.0 {
let att =
self.indentation_colors[(i).wrapping_rem(self.indentation_colors.len())];
change_colors(
&mut content,
((x, 2 * y), (x + 3, 2 * y + 1)),
att.fg,
att.bg,
);
change_theme(&mut content, ((x, 2 * y), (x + 3, 2 * y + 1)), att);
x += 4;
}
if y > 0 && content.get_mut(e.index.0 * 4, 2 * y - 1).is_some() {
@ -405,10 +400,10 @@ impl ThreadView {
),
None,
);
if let Some(_len) = highlight_reply_subjects[y] {
if highlight_reply_subjects[y].is_some() {
let index = e.index.0 * 4 + 1;
let area = ((index, 2 * y), (width - 2, 2 * y));
change_colors(&mut content, area, highlight_theme.fg, theme_default.bg);
change_theme(&mut content, area, highlight_theme);
}
set_and_join_box(&mut content, (e.index.0 * 4, 2 * y), BoxBoundary::Vertical);
set_and_join_box(
@ -448,15 +443,15 @@ impl ThreadView {
} else {
Attr::REVERSE
};
for row in grid.bounds_iter(dest_area) {
for c in row {
grid[c]
.set_fg(theme_default.fg)
.set_bg(bg_color)
.set_attrs(attrs);
}
}
change_colors(grid, dest_area, theme_default.fg, bg_color);
change_theme(
grid,
dest_area,
ThemeAttribute {
fg: theme_default.fg,
bg: bg_color,
attrs,
},
);
return;
}

View File

@ -286,7 +286,7 @@ impl MailboxManager {
} else {
self.theme_default
};
change_colors(grid, new_area, row_attr.fg, row_attr.bg);
change_theme(grid, new_area, row_attr);
context.dirty_areas.push_back(new_area);
}
return;
@ -307,11 +307,10 @@ impl MailboxManager {
.draw(grid, top_idx, self.cursor_pos, grid.bounds_iter(area));
/* highlight cursor */
change_colors(
change_theme(
grid,
nth_row_area(area, self.cursor_pos % rows),
self.highlight_theme.fg,
self.highlight_theme.bg,
self.highlight_theme,
);
/* clear gap if available height is more than count of entries */

View File

@ -67,6 +67,8 @@ pub struct CellBuffer {
pub default_cell: Cell,
/// ASCII-only flag.
pub ascii_drawing: bool,
/// Use color.
pub use_color: bool,
/// If printing to this buffer and we run out of space, expand it.
growable: bool,
tag_table: HashMap<u64, FormatTag>,
@ -81,6 +83,7 @@ impl std::fmt::Debug for CellBuffer {
.field("buf cells", &self.buf.len())
.field("default_cell", &self.default_cell)
.field("ascii_drawing", &self.ascii_drawing)
.field("use_color", &self.use_color)
.field("growable", &self.growable)
.field("tag_table", &self.tag_table)
.field("tag_associations", &self.tag_associations)
@ -110,6 +113,7 @@ impl CellBuffer {
default_cell,
growable: false,
ascii_drawing: false,
use_color: true,
tag_table: Default::default(),
tag_associations: SmallVec::new(),
}
@ -136,6 +140,7 @@ impl CellBuffer {
default_cell,
growable: false,
ascii_drawing: context.settings.terminal.ascii_drawing,
use_color: context.settings.terminal.use_color(),
tag_table: Default::default(),
tag_associations: SmallVec::new(),
}
@ -145,6 +150,10 @@ impl CellBuffer {
self.ascii_drawing = new_val;
}
pub fn set_use_color(&mut self, new_val: bool) {
self.use_color = new_val;
}
pub fn set_growable(&mut self, new_val: bool) {
self.growable = new_val;
}
@ -1093,6 +1102,36 @@ pub fn change_colors(grid: &mut CellBuffer, area: Area, fg_color: Color, bg_colo
}
}
/// Change [`ThemeAttribute`] in an `Area`
pub fn change_theme(grid: &mut CellBuffer, area: Area, theme: ThemeAttribute) {
if cfg!(feature = "debug-tracing") {
let bounds = grid.size();
let upper_left = upper_left!(area);
let bottom_right = bottom_right!(area);
let (x, y) = upper_left;
if y > (get_y(bottom_right))
|| x > get_x(bottom_right)
|| y >= get_y(bounds)
|| x >= get_x(bounds)
{
log::debug!("BUG: Invalid area in change_theme:\n area: {:?}", area);
return;
}
if !is_valid_area!(area) {
log::debug!("BUG: Invalid area in change_theme:\n area: {:?}", area);
return;
}
}
for row in grid.bounds_iter(area) {
for c in row {
grid[c]
.set_fg(theme.fg)
.set_bg(theme.bg)
.set_attrs(theme.attrs);
}
}
}
macro_rules! inspect_bounds {
($grid:ident, $area:ident, $x: ident, $y: ident, $line_break:ident) => {
let bounds = $grid.size();
@ -1227,7 +1266,7 @@ pub fn write_string_to_grid(
/// Completely clear an `Area` with an empty char and the terminal's default
/// colors.
pub fn clear_area(grid: &mut CellBuffer, area: Area, attributes: crate::conf::ThemeAttribute) {
pub fn clear_area(grid: &mut CellBuffer, area: Area, attributes: ThemeAttribute) {
if !is_valid_area!(area) {
return;
}

View File

@ -237,27 +237,23 @@ impl StatusBar {
fn draw_command_bar(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
clear_area(grid, area, crate::conf::value(context, "theme_default"));
let command_bar = crate::conf::value(context, "status.command_bar");
let (_, y) = write_string_to_grid(
self.ex_buffer.as_str(),
grid,
crate::conf::value(context, "status.command_bar").fg,
crate::conf::value(context, "status.command_bar").bg,
crate::conf::value(context, "status.command_bar").attrs,
command_bar.fg,
command_bar.bg,
command_bar.attrs,
area,
None,
);
change_theme(grid, area, command_bar);
if let Some(ref mut cell) = grid.get_mut(
pos_inc(upper_left!(area), (self.ex_buffer.cursor(), 0)).0,
y,
) {
cell.set_attrs(Attr::UNDERLINE);
cell.set_attrs(command_bar.attrs | Attr::UNDERLINE);
}
change_colors(
grid,
area,
crate::conf::value(context, "status.command_bar").fg,
crate::conf::value(context, "status.command_bar").bg,
);
context.dirty_areas.push_back(area);
}
}
@ -399,11 +395,10 @@ impl Component for StatusBar {
hist_height,
self.auto_complete.suggestions().len(),
);
change_colors(
change_theme(
grid,
hist_area,
crate::conf::value(context, "status.history").fg,
crate::conf::value(context, "status.history").bg,
crate::conf::value(context, "status.history"),
);
context.dirty_areas.push_back(hist_area);
hist_area
@ -431,13 +426,9 @@ impl Component for StatusBar {
hist_area,
crate::conf::value(context, "theme_default"),
);
let history_hints = crate::conf::value(context, "status.history.hints");
if hist_height > 0 {
change_colors(
grid,
hist_area,
crate::conf::value(context, "status.history.hints").fg,
crate::conf::value(context, "status.history.hints").bg,
);
change_theme(grid, hist_area, history_hints);
}
for (y_offset, s) in self
.auto_complete
@ -450,9 +441,9 @@ impl Component for StatusBar {
let (x, y) = write_string_to_grid(
s.as_str(),
grid,
crate::conf::value(context, "status.history.hints").fg,
crate::conf::value(context, "status.history.hints").bg,
crate::conf::value(context, "status.history.hints").attrs,
history_hints.fg,
history_hints.bg,
history_hints.attrs,
(
set_y(
upper_left!(hist_area),
@ -465,14 +456,14 @@ impl Component for StatusBar {
write_string_to_grid(
&s.description,
grid,
crate::conf::value(context, "status.history.hints").fg,
crate::conf::value(context, "status.history.hints").bg,
crate::conf::value(context, "status.history.hints").attrs,
history_hints.fg,
history_hints.bg,
history_hints.attrs,
((x + 2, y), bottom_right!(hist_area)),
None,
);
if y_offset + offset == self.auto_complete.cursor() {
change_colors(
change_theme(
grid,
(
set_y(
@ -484,15 +475,14 @@ impl Component for StatusBar {
get_y(bottom_right!(hist_area)) - hist_height + y_offset + 1,
),
),
crate::conf::value(context, "status.history.hints").fg,
crate::conf::value(context, "status.history.hints").bg,
history_hints,
);
write_string_to_grid(
&s.as_str()[self.ex_buffer.as_str().len()..],
grid,
crate::conf::value(context, "status.history.hints").fg,
crate::conf::value(context, "status.history.hints").bg,
crate::conf::value(context, "status.history.hints").attrs,
history_hints.fg,
history_hints.bg,
history_hints.attrs,
(
(
get_x(upper_left)

View File

@ -377,7 +377,7 @@ impl<T: 'static + PartialEq + std::fmt::Debug + Clone + Sync + Send> Component f
.set_bg(highlighted_attrs.bg)
.set_attrs(highlighted_attrs.attrs);
}
change_colors(
change_theme(
&mut self.content,
(
((width - OK_CANCEL.len()) / 2 + CANCEL_OFFSET, height - 1),
@ -386,8 +386,7 @@ impl<T: 'static + PartialEq + std::fmt::Debug + Clone + Sync + Send> Component f
height - 1,
),
),
self.theme_default.fg,
self.theme_default.bg,
self.theme_default,
);
self.dirty = true;
return true;
@ -703,7 +702,7 @@ impl Component for UIConfirmationDialog {
.set_bg(highlighted_attrs.bg)
.set_attrs(highlighted_attrs.attrs);
}
change_colors(
change_theme(
&mut self.content,
(
((width - OK_CANCEL.len()) / 2 + CANCEL_OFFSET, height - 1),
@ -712,8 +711,7 @@ impl Component for UIConfirmationDialog {
height - 1,
),
),
self.theme_default.fg,
self.theme_default.bg,
self.theme_default,
);
self.dirty = true;
return true;

View File

@ -282,14 +282,14 @@ impl<const N: usize> DataColumns<N> {
let gap_area = column_area.add_x(column_width);
match self.theme_config.theme {
TableTheme::Single(row_attr) => {
change_colors(grid, gap_area.area(), row_attr.fg, row_attr.bg);
change_theme(grid, gap_area.area(), row_attr);
}
TableTheme::EvenOdd { even, odd } => {
change_colors(grid, gap_area.area(), even.fg, even.bg);
change_theme(grid, gap_area.area(), even);
let mut top_idx = top_idx;
for row in gap_area {
if top_idx % 2 != 0 {
change_colors(grid, row.area(), odd.fg, odd.bg);
change_theme(grid, row.area(), odd);
}
top_idx += 1;
}
@ -306,14 +306,13 @@ impl<const N: usize> DataColumns<N> {
TableTheme::EvenOdd { even: _, odd } => odd,
};
change_colors(
change_theme(
grid,
(
pos_inc(upper_left!(total_area), (0, offset)),
pos_inc(upper_left!(total_area), (width, offset)),
),
row_attr.fg,
row_attr.bg,
row_attr,
);
}
}

View File

@ -801,7 +801,8 @@ impl Component for AutoComplete {
);
/* Highlight cursor */
if self.cursor > 0 {
change_colors(
let highlight = crate::conf::value(context, "highlight");
change_theme(
grid,
(
pos_inc(upper_left, (0, (self.cursor - 1) % rows)),
@ -814,8 +815,7 @@ impl Component for AutoComplete {
get_y(pos_inc(upper_left, (0, (self.cursor - 1) % rows))),
),
),
crate::conf::value(context, "highlight").fg,
crate::conf::value(context, "highlight").bg,
highlight,
);
}
if rows < self.entries.len() {

View File

@ -140,7 +140,14 @@ impl Component for EmbedContainer {
embed_area,
((0, 0), pos_dec(guard.grid.terminal_size, (1, 1))),
);
change_colors(grid, embed_area, Color::Byte(8), theme_default.bg);
change_theme(
grid,
embed_area,
ThemeAttribute {
fg: Color::Byte(8),
..theme_default
},
);
let stopped_message: String =
format!("Process with PID {} has stopped.", guard.child_pid);
let stopped_message_2: String = "-press 'e' to re-activate.".to_string();