mirror of
https://github.com/ClementTsang/bottom.git
synced 2026-05-03 21:40:32 +00:00
feature: add a global bg_color option for widgets (#1979)
* feature: add global bg_color option * period * fmt * oops, format again * update default config + schema * rename field + apply it to dialogs * update dialog to just draw once * handle basic * add test + some small tweaks --------- Co-authored-by: Clement Tsang <34804052+ClementTsang@users.noreply.github.com>
This commit is contained in:
@@ -26,6 +26,7 @@ That said, these are more guidelines rather than hard rules, though the project
|
||||
|
||||
- [#1938](https://github.com/ClementTsang/bottom/pull/1938), [#1980](https://github.com/ClementTsang/bottom/pull/1980): Report average packet size and packet rate.
|
||||
- [#2003](https://github.com/ClementTsang/bottom/pull/2003): Configurable default sort column for temperature and disk table widgets.
|
||||
- [#1979](https://github.com/ClementTsang/bottom/pull/1979): Add global `bg_color` option to set widget background colour.
|
||||
|
||||
### Other
|
||||
|
||||
|
||||
@@ -162,6 +162,7 @@ These can be set under `[styles.widgets]`:
|
||||
| `border_color` | The colour of the widgets' borders | `border_color = "white"` |
|
||||
| `selected_border_color` | The colour of a widget's borders when the widget is selected | `selected_border_color = "white"` |
|
||||
| `widget_title` | Text styling for a widget's title | `widget_title = { color = "black", bg_color = "blue", bold = true }` |
|
||||
| `bg_color` | The background color of the widgets. | `bg_color = "black"` |
|
||||
| `text` | Text styling for text in general | `text = { color = "black", bg_color = "blue", bold = true }` |
|
||||
| `selected_text` | Text styling for text when representing something that is selected | `selected_text = { color = "black", bg_color = "blue", bold = true }` |
|
||||
| `disabled_text` | Text styling for text when representing something that is disabled | `disabled_text = { color = "black", bg_color = "blue", bold = true }` |
|
||||
|
||||
@@ -295,7 +295,8 @@
|
||||
#text = {color = "gray"}
|
||||
#selected_text = {color = "black", bg_color = "light blue"}
|
||||
#disabled_text = {color = "dark gray"}
|
||||
|
||||
# Disabled by default
|
||||
#bg_color = "black"
|
||||
# Only on Linux
|
||||
#thread_text = {color = "green"}
|
||||
|
||||
|
||||
@@ -19,3 +19,4 @@ theme = "gruvbox"
|
||||
|
||||
[processes]
|
||||
columns = ["PID", "Name", "CPU%", "Mem%", "Rps", "Wps", "TRead", "TWrite", "State", "Time", "Virt"]
|
||||
|
||||
|
||||
@@ -1113,6 +1113,17 @@
|
||||
"description": "General styling for generic widgets.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bg_color": {
|
||||
"description": "Background color for widgets.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/$defs/ColorStr"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"border_color": {
|
||||
"description": "The colour of the widgets' borders.",
|
||||
"anyOf": [
|
||||
|
||||
@@ -120,6 +120,10 @@ impl Painter {
|
||||
|
||||
// TODO: Make drawing dialog generic.
|
||||
if app_state.help_dialog_state.is_showing_help {
|
||||
let area = f.area();
|
||||
f.buffer_mut()
|
||||
.set_style(area, self.styles.general_widget_style);
|
||||
|
||||
let gen_help_len = GENERAL_HELP_TEXT.len() as u16 + 3;
|
||||
let border_len = terminal_height.saturating_sub(gen_help_len) / 2;
|
||||
let [_, vertical_dialog_chunk, _] = Layout::default()
|
||||
@@ -178,6 +182,10 @@ impl Painter {
|
||||
|
||||
self.draw_help_dialog(f, app_state, middle_dialog_chunk);
|
||||
} else if app_state.process_kill_dialog.is_open() {
|
||||
let area = f.area();
|
||||
f.buffer_mut()
|
||||
.set_style(area, self.styles.general_widget_style);
|
||||
|
||||
// FIXME: For width, just limit to a max size or full width. For height, not sure. Maybe pass max and let child handle?
|
||||
let horizontal_padding = if terminal_width < 100 { 0 } else { 5 };
|
||||
let vertical_padding = if terminal_height < 100 { 0 } else { 5 };
|
||||
|
||||
@@ -8,7 +8,7 @@ use tui::{
|
||||
Frame,
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
text::{Line, Span, Text},
|
||||
widgets::{Block, Cell, Row, Table},
|
||||
widgets::{Block, Cell, Padding, Row, Table},
|
||||
};
|
||||
|
||||
use super::{
|
||||
@@ -77,8 +77,13 @@ where
|
||||
self.styling.border_style
|
||||
};
|
||||
|
||||
let mut block = widget_block(self.props.is_basic, is_selected, self.styling.border_type)
|
||||
.border_style(border_style);
|
||||
let mut block = widget_block(
|
||||
self.props.is_basic,
|
||||
is_selected,
|
||||
self.styling.border_type,
|
||||
self.styling.general_widget_style,
|
||||
)
|
||||
.border_style(border_style);
|
||||
|
||||
if let Some((left_title, right_title)) = self.generate_title(draw_info, data_len) {
|
||||
if !self.props.is_basic {
|
||||
@@ -135,11 +140,13 @@ where
|
||||
let draw_loc = draw_info.loc;
|
||||
let margined_draw_loc = Layout::default()
|
||||
.constraints([Constraint::Percentage(100)])
|
||||
.horizontal_margin(u16::from(self.props.is_basic && !draw_info.is_on_widget()))
|
||||
.direction(Direction::Horizontal)
|
||||
.split(draw_loc)[0];
|
||||
|
||||
let block = self.block(draw_info, self.data.len());
|
||||
let mut block = self.block(draw_info, self.data.len());
|
||||
if self.props.is_basic && !draw_info.is_on_widget() {
|
||||
block = block.padding(Padding::horizontal(1))
|
||||
}
|
||||
|
||||
let (inner_width, inner_height) = {
|
||||
let inner_rect = block.inner(margined_draw_loc);
|
||||
|
||||
@@ -11,6 +11,7 @@ pub struct DataTableStyling {
|
||||
pub text_style: Style,
|
||||
pub highlighted_text_style: Style,
|
||||
pub title_style: Style,
|
||||
pub general_widget_style: Style,
|
||||
}
|
||||
|
||||
impl DataTableStyling {
|
||||
@@ -23,6 +24,7 @@ impl DataTableStyling {
|
||||
text_style: styles.text_style,
|
||||
highlighted_text_style: styles.selected_text_style,
|
||||
title_style: styles.widget_title_style,
|
||||
general_widget_style: styles.general_widget_style,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,9 @@ pub struct TimeGraph<'a> {
|
||||
/// The graph style.
|
||||
pub graph_style: Style,
|
||||
|
||||
/// The background color
|
||||
pub general_widget_style: Style,
|
||||
|
||||
/// The border style.
|
||||
pub border_style: Style,
|
||||
|
||||
@@ -150,9 +153,14 @@ impl TimeGraph<'_> {
|
||||
let data = graph_data.into_iter().map(create_dataset).collect();
|
||||
|
||||
let block = {
|
||||
let mut b = widget_block(false, self.is_selected, self.border_type)
|
||||
.border_style(self.border_style)
|
||||
.title_top(Line::styled(self.title.as_ref(), self.title_style));
|
||||
let mut b = widget_block(
|
||||
false,
|
||||
self.is_selected,
|
||||
self.border_type,
|
||||
self.general_widget_style,
|
||||
)
|
||||
.border_style(self.border_style)
|
||||
.title_top(Line::styled(self.title.as_ref(), self.title_style));
|
||||
|
||||
if self.is_expanded {
|
||||
b = b.title_top(Line::styled(" Esc to go back ", self.title_style).right_aligned())
|
||||
@@ -167,6 +175,7 @@ impl TimeGraph<'_> {
|
||||
.x_axis(x_axis)
|
||||
.y_axis(y_axis)
|
||||
.marker(self.marker)
|
||||
.style(self.general_widget_style)
|
||||
.legend_style(self.graph_style)
|
||||
.legend_position(self.legend_position)
|
||||
.hidden_legend_constraints(
|
||||
@@ -232,6 +241,7 @@ mod test {
|
||||
y_bounds: AxisBound::Max(100.5),
|
||||
y_labels: &Y_LABELS,
|
||||
graph_style: Style::default().fg(Color::Red),
|
||||
general_widget_style: Style::default().bg(Color::Black),
|
||||
border_style: Style::default().fg(Color::Blue),
|
||||
border_type: BorderType::Plain,
|
||||
is_selected: false,
|
||||
|
||||
@@ -35,7 +35,7 @@ pub(crate) struct PercentTimeGraph<'a> {
|
||||
pub(crate) current_widget: u64,
|
||||
|
||||
/// Whether the current widget is expanded.
|
||||
///
|
||||
///
|
||||
/// This is mostly used as a shared mutability workaround due to [`App`]
|
||||
/// being a giant state struct.
|
||||
pub(crate) is_expanded: bool,
|
||||
@@ -71,6 +71,7 @@ impl<'a> PercentTimeGraph<'a> {
|
||||
};
|
||||
|
||||
let graph_style = self.styles.graph_style;
|
||||
let general_widget_style = self.styles.general_widget_style;
|
||||
let border_style = get_border_style(self.styles, self.widget_id, self.current_widget);
|
||||
let title_style = self.styles.widget_title_style;
|
||||
let border_type = self.styles.border_type;
|
||||
@@ -81,6 +82,7 @@ impl<'a> PercentTimeGraph<'a> {
|
||||
y_bounds: Y_BOUNDS,
|
||||
y_labels: &Y_LABELS,
|
||||
graph_style,
|
||||
general_widget_style,
|
||||
border_style,
|
||||
border_type,
|
||||
title: self.title,
|
||||
|
||||
@@ -115,6 +115,10 @@ impl Painter {
|
||||
.horizontal_margin(1)
|
||||
.split(draw_loc);
|
||||
|
||||
// Done like this for now since it's easier to just manually paint instead of dealing with blocks.
|
||||
f.buffer_mut()
|
||||
.set_style(draw_loc, self.styles.general_widget_style);
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new(left_arrow_text).block(Block::default()),
|
||||
margined_draw_loc[0],
|
||||
|
||||
@@ -41,8 +41,7 @@ impl Painter {
|
||||
pub fn draw_help_dialog(&self, f: &mut Frame<'_>, app_state: &mut App, draw_loc: Rect) {
|
||||
let styled_help_text = self.help_text_lines();
|
||||
|
||||
let block = dialog_block(self.styles.border_type)
|
||||
.border_style(self.styles.border_style)
|
||||
let block = dialog_block(self.styles.border_type, self.styles.border_style)
|
||||
.title_top(Line::styled(" Help ", self.styles.widget_title_style))
|
||||
.title_top(
|
||||
Line::styled(" Esc to close ", self.styles.widget_title_style).right_aligned(),
|
||||
|
||||
@@ -677,11 +677,9 @@ impl ProcessKillDialog {
|
||||
}
|
||||
};
|
||||
|
||||
let block = dialog_block(styles.border_type)
|
||||
let block = dialog_block(styles.border_type, styles.border_style)
|
||||
.title_top(title)
|
||||
.title_top(Line::styled(" Esc to close ", styles.widget_title_style).right_aligned())
|
||||
.style(styles.border_style)
|
||||
.border_style(styles.border_style);
|
||||
.title_top(Line::styled(" Esc to close ", styles.widget_title_style).right_aligned());
|
||||
|
||||
let num_lines = text.line_count(block.inner(draw_area).width) as u16;
|
||||
|
||||
@@ -811,11 +809,9 @@ impl ProcessKillDialog {
|
||||
.alignment(Alignment::Center)
|
||||
.wrap(Wrap { trim: true });
|
||||
|
||||
let block = dialog_block(styles.border_type)
|
||||
let block = dialog_block(styles.border_type, styles.border_style)
|
||||
.title_top(title)
|
||||
.title_top(Line::styled(" Esc to close ", styles.widget_title_style).right_aligned())
|
||||
.style(styles.border_style)
|
||||
.border_style(styles.border_style);
|
||||
.title_top(Line::styled(" Esc to close ", styles.widget_title_style).right_aligned());
|
||||
|
||||
let num_lines = text.line_count(block.inner(draw_area).width) as u16;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::time::Instant;
|
||||
|
||||
use tui::{
|
||||
layout::Rect,
|
||||
style::Style,
|
||||
widgets::{Block, BorderType, Borders},
|
||||
};
|
||||
|
||||
@@ -29,26 +30,31 @@ pub fn should_hide_x_label(
|
||||
}
|
||||
|
||||
/// Return a widget block.
|
||||
pub fn widget_block(is_basic: bool, is_selected: bool, border_type: BorderType) -> Block<'static> {
|
||||
let mut block = Block::default().border_type(border_type);
|
||||
|
||||
pub fn widget_block(
|
||||
is_basic: bool, is_selected: bool, border_type: BorderType, widget_style: Style,
|
||||
) -> Block<'static> {
|
||||
if is_basic {
|
||||
if is_selected {
|
||||
block = block.borders(SIDE_BORDERS);
|
||||
Block::default()
|
||||
.border_type(border_type)
|
||||
.style(widget_style)
|
||||
.borders(SIDE_BORDERS)
|
||||
} else {
|
||||
block = block.borders(Borders::empty());
|
||||
Block::default().style(widget_style)
|
||||
}
|
||||
} else {
|
||||
block = block.borders(Borders::all());
|
||||
Block::default()
|
||||
.border_type(border_type)
|
||||
.style(widget_style)
|
||||
.borders(Borders::all())
|
||||
}
|
||||
|
||||
block
|
||||
}
|
||||
|
||||
/// Return a dialog block.
|
||||
pub fn dialog_block(border_type: BorderType) -> Block<'static> {
|
||||
pub fn dialog_block(border_type: BorderType, border_style: Style) -> Block<'static> {
|
||||
Block::default()
|
||||
.border_type(border_type)
|
||||
.border_style(border_style)
|
||||
.borders(Borders::all())
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ impl Painter {
|
||||
app_state.app_config_fields.use_basic_mode,
|
||||
is_selected,
|
||||
self.styles.border_type,
|
||||
self.styles.general_widget_style,
|
||||
)
|
||||
.border_style(border_style)
|
||||
.title_top(Line::styled(" Battery ", self.styles.widget_title_style));
|
||||
|
||||
@@ -33,13 +33,16 @@ impl Painter {
|
||||
// If not, then add a new column. Then, from this, split the row space across ALL columns.
|
||||
// From there, generate the desired lengths.
|
||||
|
||||
if app_state.current_widget.widget_id == widget_id {
|
||||
f.render_widget(
|
||||
widget_block(true, true, self.styles.border_type)
|
||||
.border_style(self.styles.highlighted_border_style),
|
||||
draw_loc,
|
||||
);
|
||||
}
|
||||
f.render_widget(
|
||||
widget_block(
|
||||
true,
|
||||
app_state.current_widget.widget_id == widget_id,
|
||||
self.styles.border_type,
|
||||
self.styles.general_widget_style,
|
||||
)
|
||||
.border_style(self.styles.highlighted_border_style),
|
||||
draw_loc,
|
||||
);
|
||||
|
||||
// TODO: This is pretty ugly. Is there a better way of doing it?
|
||||
let mut avg_index = cpu_data.len() + 1;
|
||||
|
||||
@@ -46,13 +46,16 @@ impl Painter {
|
||||
) {
|
||||
let mut draw_widgets: Vec<PipeGauge<'_>> = Vec::new();
|
||||
|
||||
if app_state.current_widget.widget_id == widget_id {
|
||||
f.render_widget(
|
||||
widget_block(true, true, self.styles.border_type)
|
||||
.border_style(self.styles.highlighted_border_style),
|
||||
draw_loc,
|
||||
);
|
||||
}
|
||||
f.render_widget(
|
||||
widget_block(
|
||||
true,
|
||||
app_state.current_widget.widget_id == widget_id,
|
||||
self.styles.border_type,
|
||||
self.styles.general_widget_style,
|
||||
)
|
||||
.border_style(self.styles.highlighted_border_style),
|
||||
draw_loc,
|
||||
);
|
||||
|
||||
let data = app_state.data_store.get_data();
|
||||
|
||||
|
||||
@@ -21,13 +21,16 @@ impl Painter {
|
||||
) {
|
||||
let show_packets = app_state.app_config_fields.network_show_packets;
|
||||
|
||||
if app_state.current_widget.widget_id == widget_id {
|
||||
f.render_widget(
|
||||
widget_block(true, true, self.styles.border_type)
|
||||
.border_style(self.styles.highlighted_border_style),
|
||||
draw_loc,
|
||||
);
|
||||
}
|
||||
f.render_widget(
|
||||
widget_block(
|
||||
true,
|
||||
app_state.current_widget.widget_id == widget_id,
|
||||
self.styles.border_type,
|
||||
self.styles.general_widget_style,
|
||||
)
|
||||
.border_style(self.styles.highlighted_border_style),
|
||||
draw_loc,
|
||||
);
|
||||
|
||||
let use_binary_prefix = app_state.app_config_fields.network_use_binary_prefix;
|
||||
let network_data = &(app_state.data_store.get_data().network_harvest);
|
||||
|
||||
@@ -5,7 +5,7 @@ use tui::{
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
symbols::Marker,
|
||||
text::Text,
|
||||
widgets::{Block, Borders, Row, Table},
|
||||
widgets::{Row, Table},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -13,7 +13,7 @@ use crate::{
|
||||
canvas::{
|
||||
Painter,
|
||||
components::time_graph::{AxisBound, ChartScaling, GraphData, TimeGraph},
|
||||
drawing_utils::should_hide_x_label,
|
||||
drawing_utils::{should_hide_x_label, widget_block},
|
||||
widgets::{PacketInfo, calculate_packet_info},
|
||||
},
|
||||
utils::{
|
||||
@@ -267,6 +267,7 @@ impl Painter {
|
||||
y_bounds,
|
||||
y_labels: &(y_labels.into_iter().map(Into::into).collect::<Vec<_>>()),
|
||||
graph_style: self.styles.graph_style,
|
||||
general_widget_style: self.styles.general_widget_style,
|
||||
border_style,
|
||||
border_type: self.styles.border_type,
|
||||
title: " Network ".into(),
|
||||
@@ -348,6 +349,19 @@ impl Painter {
|
||||
let column_width = draw_loc.width.saturating_sub(2) / num_columns as u16;
|
||||
|
||||
// Draw
|
||||
let current_border_style = if app_state.current_widget.widget_id == widget_id {
|
||||
self.styles.highlighted_border_style
|
||||
} else {
|
||||
self.styles.border_style
|
||||
};
|
||||
let block = widget_block(
|
||||
app_state.app_config_fields.use_basic_mode,
|
||||
app_state.current_widget.widget_id == widget_id,
|
||||
self.styles.border_type,
|
||||
self.styles.general_widget_style,
|
||||
)
|
||||
.border_style(current_border_style);
|
||||
|
||||
f.render_widget(
|
||||
Table::new(
|
||||
total_network,
|
||||
@@ -356,13 +370,7 @@ impl Painter {
|
||||
.collect::<Vec<_>>()),
|
||||
)
|
||||
.header(Row::new(headers).style(self.styles.table_header_style))
|
||||
.block(Block::default().borders(Borders::ALL).border_style(
|
||||
if app_state.current_widget.widget_id == widget_id {
|
||||
self.styles.highlighted_border_style
|
||||
} else {
|
||||
self.styles.border_style
|
||||
},
|
||||
))
|
||||
.block(block)
|
||||
.style(self.styles.text_style),
|
||||
draw_loc,
|
||||
);
|
||||
|
||||
@@ -254,8 +254,13 @@ impl Painter {
|
||||
};
|
||||
|
||||
let process_search_block = {
|
||||
let mut block = widget_block(is_basic, is_selected, self.styles.border_type)
|
||||
.border_style(current_border_style);
|
||||
let mut block = widget_block(
|
||||
is_basic,
|
||||
is_selected,
|
||||
self.styles.border_type,
|
||||
self.styles.general_widget_style,
|
||||
)
|
||||
.border_style(current_border_style);
|
||||
|
||||
if !is_basic {
|
||||
block = block.title_top(
|
||||
|
||||
+2
-1
@@ -541,7 +541,8 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott
|
||||
#text = {color = "gray"}
|
||||
#selected_text = {color = "black", bg_color = "light blue"}
|
||||
#disabled_text = {color = "dark gray"}
|
||||
|
||||
# Disabled by default
|
||||
#bg_color = "black"
|
||||
# Only on Linux
|
||||
#thread_text = {color = "green"}
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@ use utils::{opt, set_colour, set_colour_list, set_style};
|
||||
use widgets::WidgetStyle;
|
||||
|
||||
use super::Config;
|
||||
use crate::options::{OptionError, OptionResult, args::BottomArgs};
|
||||
use crate::options::{
|
||||
OptionError, OptionResult, args::BottomArgs, config::style::utils::set_bg_colour,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
|
||||
@@ -117,6 +119,7 @@ pub struct Styles {
|
||||
pub(crate) selected_text_style: Style,
|
||||
pub(crate) table_header_style: Style,
|
||||
pub(crate) widget_title_style: Style,
|
||||
pub(crate) general_widget_style: Style,
|
||||
pub(crate) graph_style: Style,
|
||||
pub(crate) graph_legend_style: Style,
|
||||
pub(crate) high_battery: Style,
|
||||
@@ -207,6 +210,7 @@ impl Styles {
|
||||
set_style!(self.graph_legend_style, config.graphs, legend_text);
|
||||
|
||||
// General widget text.
|
||||
set_bg_colour!(self.general_widget_style, config.widgets, bg_color);
|
||||
set_style!(self.widget_title_style, config.widgets, widget_title);
|
||||
set_style!(self.text_style, config.widgets, text);
|
||||
set_style!(self.selected_text_style, config.widgets, selected_text);
|
||||
|
||||
@@ -59,6 +59,7 @@ impl Styles {
|
||||
selected_text_style: DEFAULT_SELECTED_TEXT_STYLE,
|
||||
table_header_style: color!(HIGHLIGHT_COLOUR).add_modifier(Modifier::BOLD),
|
||||
widget_title_style: color!(TEXT_COLOUR),
|
||||
general_widget_style: Style::default(),
|
||||
graph_style: color!(TEXT_COLOUR),
|
||||
graph_legend_style: color!(TEXT_COLOUR),
|
||||
high_battery: color!(Color::Green),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use tui::{
|
||||
style::{Color, Modifier},
|
||||
style::{Color, Modifier, Style},
|
||||
widgets::BorderType,
|
||||
};
|
||||
|
||||
@@ -58,6 +58,7 @@ impl Styles {
|
||||
text_style: hex!("#ebdbb2"),
|
||||
selected_text_style: hex!("#1d2021").bg(hex_colour!("#ebdbb2")),
|
||||
table_header_style: hex!("#83a598").add_modifier(Modifier::BOLD),
|
||||
general_widget_style: Style::default(),
|
||||
widget_title_style: hex!("#ebdbb2"),
|
||||
graph_style: hex!("#ebdbb2"),
|
||||
graph_legend_style: hex!("#ebdbb2"),
|
||||
@@ -123,6 +124,7 @@ impl Styles {
|
||||
text_style: hex!("#3c3836"),
|
||||
selected_text_style: hex!("#ebdbb2").bg(hex_colour!("#3c3836")),
|
||||
table_header_style: hex!("#076678").add_modifier(Modifier::BOLD),
|
||||
general_widget_style: Style::default(),
|
||||
widget_title_style: hex!("#3c3836"),
|
||||
graph_style: hex!("#3c3836"),
|
||||
graph_legend_style: hex!("#3c3836"),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use tui::{
|
||||
style::{Color, Modifier},
|
||||
style::{Color, Modifier, Style},
|
||||
widgets::BorderType,
|
||||
};
|
||||
|
||||
@@ -46,6 +46,7 @@ impl Styles {
|
||||
text_style: hex!("#e5e9f0"),
|
||||
selected_text_style: hex!("#2e3440").bg(hex_colour!("#88c0d0")),
|
||||
table_header_style: hex!("#81a1c1").add_modifier(Modifier::BOLD),
|
||||
general_widget_style: Style::default(),
|
||||
widget_title_style: hex!("#e5e9f0"),
|
||||
graph_style: hex!("#e5e9f0"),
|
||||
graph_legend_style: hex!("#e5e9f0"),
|
||||
@@ -99,6 +100,7 @@ impl Styles {
|
||||
text_style: hex!("#2e3440"),
|
||||
selected_text_style: hex!("#f5f5f5").bg(hex_colour!("#5e81ac")),
|
||||
table_header_style: hex!("#5e81ac").add_modifier(Modifier::BOLD),
|
||||
general_widget_style: Style::default(),
|
||||
widget_title_style: hex!("#2e3440"),
|
||||
graph_style: hex!("#2e3440"),
|
||||
graph_legend_style: hex!("#2e3440"),
|
||||
|
||||
@@ -96,8 +96,8 @@ fn convert_name_to_colour(color_name: &str) -> Result<Color, String> {
|
||||
"white" => Ok(Color::White),
|
||||
_ => Err(format!(
|
||||
"'{color_name}' is an invalid named color.
|
||||
|
||||
The following are supported named colors:
|
||||
|
||||
The following are supported named colors:
|
||||
+--------+-------------+---------------------+
|
||||
| Reset | Magenta | Light Yellow |
|
||||
+--------+-------------+---------------------+
|
||||
@@ -233,6 +233,27 @@ macro_rules! set_colour {
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! set_bg_colour {
|
||||
($palette_field:expr, $config_location:expr, $field:tt) => {
|
||||
if let Some(colour) = &(opt!($config_location.as_ref()?.$field.as_ref())) {
|
||||
$palette_field = $palette_field.bg(
|
||||
crate::options::config::style::utils::str_to_colour(&colour.0).map_err(|err| {
|
||||
match stringify!($config_location).split_once(".") {
|
||||
Some((_, loc)) => crate::options::OptionError::config(format!(
|
||||
"Please update 'styles.{loc}.{}' in your config file. {err}",
|
||||
stringify!($field)
|
||||
)),
|
||||
None => crate::options::OptionError::config(format!(
|
||||
"Please update 'styles.{}' in your config file. {err}",
|
||||
stringify!($field)
|
||||
)),
|
||||
}
|
||||
})?,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Set `palette_field` to the value in `config_location` for `field`.
|
||||
macro_rules! set_colour_list {
|
||||
($palette_field:expr, $config_location:expr, $field:tt) => {
|
||||
@@ -259,6 +280,7 @@ macro_rules! set_colour_list {
|
||||
}
|
||||
|
||||
pub(super) use opt;
|
||||
pub(super) use set_bg_colour;
|
||||
pub(super) use set_colour;
|
||||
pub(super) use set_colour_list;
|
||||
pub(super) use set_style;
|
||||
@@ -513,6 +535,32 @@ mod test {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_bg_colour() -> anyhow::Result<()> {
|
||||
let mut s = Style::default().bg(Color::Black);
|
||||
let dummy = DummyConfig {
|
||||
inner: Some(InnerDummyConfig::default()),
|
||||
};
|
||||
|
||||
set_bg_colour!(s, &dummy.inner, color_a);
|
||||
assert_eq!(s.fg, None);
|
||||
assert_eq!(s.bg.unwrap(), Color::Black);
|
||||
|
||||
set_bg_colour!(s, &dummy.inner, color_b);
|
||||
assert_eq!(s.fg, None);
|
||||
assert_eq!(s.bg.unwrap(), Color::Red);
|
||||
|
||||
set_bg_colour!(s, &dummy.inner, color_c);
|
||||
assert_eq!(s.fg, None);
|
||||
assert_eq!(s.bg.unwrap(), Color::Rgb(255, 255, 255));
|
||||
|
||||
set_bg_colour!(s, &dummy.inner, color_d);
|
||||
assert_eq!(s.fg, None);
|
||||
assert_eq!(s.bg.unwrap(), Color::Rgb(0, 0, 0));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bad_set_colour() {
|
||||
let mut _s = Style::default().fg(Color::Black);
|
||||
|
||||
@@ -33,4 +33,7 @@ pub(crate) struct WidgetStyle {
|
||||
|
||||
/// Widget borders type.
|
||||
pub(crate) widget_border_type: Option<WidgetBorderType>,
|
||||
|
||||
/// Background color for widgets.
|
||||
pub(crate) bg_color: Option<ColorStr>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user