terminal_framework/terminal/screen/
mod.rs

1use std::io::{self, Write};
2
3use self::{clearing::Clearable, colors::Colorable, cursor::Cursor};
4
5pub mod clearing;
6pub mod colors;
7pub mod cursor;
8
9// Cursor movements:
10// ESC[H 	moves cursor to home position (0, 0)
11// ESC[{line};{column}H
12// ESC[{line};{column}f 	moves cursor to line #, column #
13// ESC[#A 	moves cursor up # lines
14// ESC[#B 	moves cursor down # lines
15// ESC[#C 	moves cursor right # columns
16// ESC[#D 	moves cursor left # columns
17
18// Colors table:
19// Color    FG  BG
20// Black    30  40
21// Red      31  41
22// Green    32  42
23// Yellow   33  43
24// Blue     34  43
25// Magenta  35  45
26// Cyan     36  46
27// White    37  47
28// Default  39  49
29// Reset    0   0
30
31// Screen Clearing:
32// ToEndOfScreen       0J
33// ToBeginingOfScreen  1J
34// EntrieScreen        2J
35// ToBeginingOfLine    0K
36// ToEndOfLine         1K
37// EntrieLine          2K
38
39const CSI: &str = "\x1b[";
40
41pub struct Point {
42    pub x: usize,
43    pub y: usize
44}
45
46pub struct AnsiDisplay {
47    origin: Point,
48    width: usize,
49    height: usize,
50    cursor: Point
51}
52
53impl AnsiDisplay {
54    pub fn new(width: usize, height: usize, origin: Option<Point>) ->Self {
55        let cursor = Point {
56            x: 0,
57            y: 0
58        };
59        let origin = match origin {
60            Some(o) => o,
61            None => Point {
62                x: 0,
63                y: 0
64            }
65        };
66        AnsiDisplay {
67            width,
68            height,
69            cursor,
70            origin
71        }
72    }
73    pub fn resize(&mut self, new_width: Option<usize>, new_height: Option<usize>) {
74        self.width = match new_width {
75            Some(w) => w,
76            None => self.width
77        };
78        self.height = match new_height {
79            Some(h) => h,
80            None => self.height
81        };
82    }
83    pub fn print(){}
84}
85
86impl Cursor for AnsiDisplay {
87    fn move_up(&mut self, lines: Option<usize>) {
88        let lines = match lines {
89            Some(l) => l,
90            None => 1
91        };
92
93        if lines + self.cursor.y >= self.height {
94            return;
95        }
96
97        self.cursor.y -= lines;
98        print!("{}{}A", CSI, lines);
99        io::stdout().flush().unwrap();
100    }
101    fn move_down(&mut self, lines: Option<usize>) {
102        let lines = match lines {
103            Some(l) => l,
104            None => 1
105        };
106
107        if lines + self.cursor.y >= self.height {
108            return;
109        }
110
111        self.cursor.y += lines;
112        print!("{}{}B", CSI, lines);
113        io::stdout().flush().unwrap();
114    }
115    fn move_right(&mut self, cols: Option<usize>) {
116        let cols = match cols {
117            Some(l) => l,
118            None => 1
119        };
120
121        if cols + self.cursor.x >= self.width {
122            return;
123        }
124
125        self.cursor.x += cols;
126        print!("{}{}C", CSI, cols);
127        io::stdout().flush().unwrap();
128    }
129    fn move_left(&mut self, cols: Option<usize>) {
130        let cols = match cols {
131            Some(l) => l,
132            None => 1
133        };
134
135        if cols + self.cursor.x >= self.width {
136            return;
137        }
138
139        print!("{}{}A", CSI, cols);
140        io::stdout().flush().unwrap();
141    }
142    fn position(&mut self, x: usize, y: usize) {
143
144        if x >= self.width || y >= self.height {
145            return;
146        }
147
148        print!("{}{};{}H", CSI, y, x);
149        io::stdout().flush().unwrap();
150    }
151}
152
153impl Colorable for AnsiDisplay {
154    fn set_bg_color(&mut self, color: Option<colors::Color>) {
155        let color: &str = match color {
156            Some(c) => {
157                match c {
158                    colors::Color::Black => "40",
159                    colors::Color::Red => "41",
160                    colors::Color::Green => "42",
161                    colors::Color::Yellow => "43",
162                    colors::Color::Blue => "44",
163                    colors::Color::Magenta => "45",
164                    colors::Color::Cyan => "46",
165                    colors::Color::White => "47",
166                    colors::Color::Default => "49",
167                    colors::Color::Reset => "0"
168                }
169            },
170            None => "49"
171        };
172        print!("{}{}m", CSI, color);
173        io::stdout().flush().unwrap();
174    }
175    fn set_fg_color(&mut self, color: Option<colors::Color>) {
176        let color: &str = match color {
177            Some(c) => {
178                match c {
179                    colors::Color::Black => "30",
180                    colors::Color::Red => "31",
181                    colors::Color::Green => "32",
182                    colors::Color::Yellow => "33",
183                    colors::Color::Blue => "34",
184                    colors::Color::Magenta => "35",
185                    colors::Color::Cyan => "36",
186                    colors::Color::White => "37",
187                    colors::Color::Default => "39",
188                    colors::Color::Reset => "0"
189                }
190            },
191            None => "49"
192        };
193        print!("{}{}m", CSI, color);
194        io::stdout().flush().unwrap();
195    }
196}
197
198impl Clearable for AnsiDisplay {
199    fn clear_line(&self) {
200        print!("{}2K", CSI);
201        io::stdout().flush().unwrap();
202    }
203    fn clear_screen(&self) {
204        print!("{}2J", CSI);
205        io::stdout().flush().unwrap();
206    }
207    fn clear_to_end_of_screen(&self) {
208        print!("{}0J", CSI);
209        io::stdout().flush().unwrap();
210    }
211    fn clear_to_begin_of_screen(&self) {
212        print!("{}1J", CSI);
213        io::stdout().flush().unwrap();
214    }
215    fn clear_to_end_of_line(&self) {
216        print!("{}0K", CSI);
217        io::stdout().flush().unwrap();
218    }
219    fn clear_to_begin_of_line(&self) {
220        print!("{}1K", CSI);
221        io::stdout().flush().unwrap();
222    }
223}
224
225
226