rmux_core/screen/
style_overlay.rs1use crate::input::{GridAttr, COLOUR_DEFAULT, COLOUR_NONE, COLOUR_TERMINAL};
2use crate::style::{style_parse, Style, StyleCell};
3
4use super::Screen;
5
6impl Screen {
7 pub fn overlay_style_on_default_cells(&mut self, style_input: &str) {
9 let Some(style) = default_cell_overlay(style_input) else {
10 return;
11 };
12 self.overlay_default_style(&style);
13 }
14
15 pub fn overlay_default_style(&mut self, style: &Style) {
17 let background = effective_background(style);
18 let width = self.grid.sx();
19 for row in 0..self.grid.sy() {
20 let Some(line) = self.grid.visible_line_mut(row) else {
21 continue;
22 };
23 for x in 0..width {
24 let Some(cell) = line.cell_mut(x) else {
25 continue;
26 };
27 if cell.is_padding() {
28 continue;
29 }
30
31 if is_set(style.cell.fg) && is_unset(cell.fg()) {
32 cell.set_fg(style.cell.fg);
33 }
34 if is_set(background) && is_unset(cell.bg()) {
35 cell.set_bg(background);
36 }
37 if is_set(style.cell.us) && is_unset(cell.us()) {
38 cell.set_us(style.cell.us);
39 }
40 if style.cell.attr != 0 && cell.attr() == 0 {
41 cell.set_attr(style.cell.attr & !GridAttr::NOATTR);
42 }
43 }
44 }
45 }
46}
47
48fn default_cell_overlay(style_input: &str) -> Option<Style> {
49 if style_input.is_empty() {
50 return None;
51 }
52
53 let base = StyleCell::default();
54 let mut style = Style::default();
55 style_parse(&mut style, &base, style_input).ok()?;
56 (is_set(style.cell.fg)
57 || is_set(style.cell.bg)
58 || is_set(style.cell.us)
59 || is_set(style.fill)
60 || style.cell.attr != 0)
61 .then_some(style)
62}
63
64fn effective_background(style: &Style) -> i32 {
65 if is_set(style.cell.bg) {
66 style.cell.bg
67 } else {
68 style.fill
69 }
70}
71
72fn is_set(colour: i32) -> bool {
73 !is_unset(colour)
74}
75
76fn is_unset(colour: i32) -> bool {
77 matches!(colour, COLOUR_DEFAULT | COLOUR_TERMINAL | COLOUR_NONE)
78}