oxedyne/fe2o3/fe2o3_tui/src/lib_tui/style.rs
7.5 KiB, 5 runs
created by r1870400018:1203, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | use crate::lib_tui::{ |
| 2 | render::{ |
| 3 | Drawable, |
| 4 | Drawer, |
| 5 | Renderer, |
| 6 | Sink, |
| 7 | When, |
| 8 | }, |
| 9 | }; |
| 10 | |
| 11 | use oxedyne_fe2o3_core::prelude::*; |
| 12 | |
| 13 | use std::fmt; |
| 14 | |
| 15 | |
| 16 | #[derive(Clone, Debug, Default)] |
| 17 | pub struct Style { |
| 18 | pub cols: Colours, |
| 19 | pub attr: Vec<Attribute>, |
| 20 | } |
| 21 | |
| 22 | impl Style { |
| 23 | pub fn new( |
| 24 | fore: Option<Colour>, |
| 25 | back: Option<Colour>, |
| 26 | attr: Option<Vec<Attribute>>, |
| 27 | ) |
| 28 | -> Self |
| 29 | { |
| 30 | Self { |
| 31 | cols: Colours::new(fore, back), |
| 32 | attr: match attr { |
| 33 | Some(list) => list, |
| 34 | None => Vec::new(), |
| 35 | }, |
| 36 | } |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | impl Drawable for Style { |
| 41 | fn render<S: Sink, R: Renderer<S>>( |
| 42 | &mut self, |
| 43 | drawer: &mut Drawer<S, R>, |
| 44 | when: When, |
| 45 | ) |
| 46 | -> Outcome<()> |
| 47 | { |
| 48 | res!(drawer.rend.set_style(self, when)); |
| 49 | Ok(()) |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | #[derive(Clone, Debug, Default)] |
| 54 | pub struct Colours { |
| 55 | pub fore: Option<Colour>, |
| 56 | pub back: Option<Colour>, |
| 57 | } |
| 58 | |
| 59 | impl Drawable for Colours { |
| 60 | fn render<S: Sink, R: Renderer<S>>( |
| 61 | &mut self, |
| 62 | drawer: &mut Drawer<S, R>, |
| 63 | when: When, |
| 64 | ) |
| 65 | -> Outcome<()> |
| 66 | { |
| 67 | if let Some(col) = self.back { |
| 68 | res!(drawer.rend.set_back_colour(&col, when)); |
| 69 | } |
| 70 | if let Some(col) = self.fore { |
| 71 | res!(drawer.rend.set_fore_colour(&col, when)); |
| 72 | } |
| 73 | Ok(()) |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | impl Colours { |
| 78 | pub fn new(fore: Option<Colour>, back: Option<Colour>) -> Self { |
| 79 | Self { |
| 80 | fore, |
| 81 | back, |
| 82 | } |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | #[derive(Clone, Copy, Debug)] |
| 87 | pub enum Colour { |
| 88 | Reset, |
| 89 | Black, |
| 90 | Red, |
| 91 | Green, |
| 92 | Yellow, |
| 93 | Blue, |
| 94 | Magenta, |
| 95 | Cyan, |
| 96 | Gray, |
| 97 | DarkGray, |
| 98 | LightRed, |
| 99 | LightGreen, |
| 100 | LightBlue, |
| 101 | LightYellow, |
| 102 | LightMagenta, |
| 103 | LightCyan, |
| 104 | White, |
| 105 | Indexed(u8), |
| 106 | Rgb(u8, u8, u8), |
| 107 | } |
| 108 | |
| 109 | impl From<Colour> for crossterm::style::Color { |
| 110 | fn from(colour: Colour) -> Self { |
| 111 | match colour { |
| 112 | Colour::Reset => crossterm::style::Color::Reset, |
| 113 | Colour::Black => crossterm::style::Color::Black, |
| 114 | Colour::Red => crossterm::style::Color::DarkRed, |
| 115 | Colour::Green => crossterm::style::Color::DarkGreen, |
| 116 | Colour::Yellow => crossterm::style::Color::DarkYellow, |
| 117 | Colour::Blue => crossterm::style::Color::DarkBlue, |
| 118 | Colour::Magenta => crossterm::style::Color::DarkMagenta, |
| 119 | Colour::Cyan => crossterm::style::Color::DarkCyan, |
| 120 | Colour::Gray => crossterm::style::Color::Grey, |
| 121 | Colour::DarkGray => crossterm::style::Color::DarkGrey, |
| 122 | Colour::LightRed => crossterm::style::Color::Red, |
| 123 | Colour::LightGreen => crossterm::style::Color::Green, |
| 124 | Colour::LightBlue => crossterm::style::Color::Blue, |
| 125 | Colour::LightYellow => crossterm::style::Color::Yellow, |
| 126 | Colour::LightMagenta => crossterm::style::Color::Magenta, |
| 127 | Colour::LightCyan => crossterm::style::Color::Cyan, |
| 128 | Colour::White => crossterm::style::Color::White, |
| 129 | Colour::Indexed(i) => crossterm::style::Color::AnsiValue(i), |
| 130 | Colour::Rgb(r, g, b) => crossterm::style::Color::Rgb { r, g, b }, |
| 131 | } |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | #[derive(Clone, Copy, Debug)] |
| 136 | pub enum Attribute { |
| 137 | Reset, |
| 138 | Bold, |
| 139 | Dim, |
| 140 | Italic, |
| 141 | Underlined, |
| 142 | DoubleUnderlined, |
| 143 | Undercurled, |
| 144 | Underdotted, |
| 145 | Underdashed, |
| 146 | SlowBlink, |
| 147 | RapidBlink, |
| 148 | Reverse, |
| 149 | Hidden, |
| 150 | CrossedOut, |
| 151 | Fraktur, |
| 152 | NoBold, |
| 153 | NormalIntensity, |
| 154 | NoItalic, |
| 155 | NoUnderline, |
| 156 | NoBlink, |
| 157 | NoReverse, |
| 158 | NoHidden, |
| 159 | NotCrossedOut, |
| 160 | Framed, |
| 161 | Encircled, |
| 162 | OverLined, |
| 163 | NotFramedOrEncircled, |
| 164 | NotOverLined, |
| 165 | } |
| 166 | |
| 167 | impl From<Attribute> for crossterm::style::Attribute { |
| 168 | fn from(attr: Attribute) -> Self { |
| 169 | match attr { |
| 170 | Attribute::Reset => crossterm::style::Attribute::Reset, |
| 171 | Attribute::Bold => crossterm::style::Attribute::Bold, |
| 172 | Attribute::Dim => crossterm::style::Attribute::Dim, |
| 173 | Attribute::Italic => crossterm::style::Attribute::Italic, |
| 174 | Attribute::Underlined => crossterm::style::Attribute::Underlined, |
| 175 | Attribute::DoubleUnderlined => crossterm::style::Attribute::DoubleUnderlined, |
| 176 | Attribute::Undercurled => crossterm::style::Attribute::Undercurled, |
| 177 | Attribute::Underdotted => crossterm::style::Attribute::Underdotted, |
| 178 | Attribute::Underdashed => crossterm::style::Attribute::Underdashed, |
| 179 | Attribute::SlowBlink => crossterm::style::Attribute::SlowBlink, |
| 180 | Attribute::RapidBlink => crossterm::style::Attribute::RapidBlink, |
| 181 | Attribute::Reverse => crossterm::style::Attribute::Reverse, |
| 182 | Attribute::Hidden => crossterm::style::Attribute::Hidden, |
| 183 | Attribute::CrossedOut => crossterm::style::Attribute::CrossedOut, |
| 184 | Attribute::Fraktur => crossterm::style::Attribute::Fraktur, |
| 185 | Attribute::NoBold => crossterm::style::Attribute::NoBold, |
| 186 | Attribute::NormalIntensity => crossterm::style::Attribute::NormalIntensity, |
| 187 | Attribute::NoItalic => crossterm::style::Attribute::NoItalic, |
| 188 | Attribute::NoUnderline => crossterm::style::Attribute::NoUnderline, |
| 189 | Attribute::NoBlink => crossterm::style::Attribute::NoBlink, |
| 190 | Attribute::NoReverse => crossterm::style::Attribute::NoReverse, |
| 191 | Attribute::NoHidden => crossterm::style::Attribute::NoHidden, |
| 192 | Attribute::NotCrossedOut => crossterm::style::Attribute::NotCrossedOut, |
| 193 | Attribute::Framed => crossterm::style::Attribute::Framed, |
| 194 | Attribute::Encircled => crossterm::style::Attribute::Encircled, |
| 195 | Attribute::OverLined => crossterm::style::Attribute::OverLined, |
| 196 | Attribute::NotFramedOrEncircled => crossterm::style::Attribute::NotFramedOrEncircled, |
| 197 | Attribute::NotOverLined => crossterm::style::Attribute::NotOverLined, |
| 198 | } |
| 199 | } |
| 200 | } |
| 201 | |
| 202 | #[derive(Clone, Debug)] |
| 203 | pub enum Symbol { |
| 204 | Buffer, |
| 205 | Database, |
| 206 | File, |
| 207 | FileTree, |
| 208 | Info, |
| 209 | Keyboard, |
| 210 | Menu, |
| 211 | Shell, |
| 212 | Text, |
| 213 | Windows, |
| 214 | } |
| 215 | |
| 216 | /// Note that width calculation seems to be defective when multiple emoji characters are used with |
| 217 | /// the GNOME terminal, hence sticking to only a single character. |
| 218 | impl fmt::Display for Symbol { |
| 219 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 220 | match self { |
| 221 | Self::Buffer => write!(f, "\u{2700}"), |
| 222 | Self::Database => write!(f, "\u{1f5ae}"), |
| 223 | Self::File => write!(f, "\u{1f4c2}"), |
| 224 | Self::FileTree => write!(f, "\u{1f332}"), |
| 225 | Self::Info => write!(f, "\u{02139}"), |
| 226 | Self::Keyboard => write!(f, "\u{1f5ae}"), |
| 227 | Self::Menu => write!(f, "\u{2630}"), |
| 228 | Self::Shell => write!(f, "\u{2630}"), |
| 229 | Self::Text => write!(f, "\u{1f4c2}"), |
| 230 | Self::Windows => write!(f, "\u{1fa9f}"), |
| 231 | } |
| 232 | } |
| 233 | } |