Skip to main content

sericom_core/screen_buffer/
cursor.rs

1use std::fmt::Display;
2
3use super::{Line, ScreenBuffer};
4
5/// Represent's the cursor's position within the [`ScreenBuffer`].
6#[derive(Clone, Copy, Debug)]
7pub struct Position {
8    /// The column within [`ScreenBuffer`]'s scrollback buffer.
9    /// This translates to the [`Cell`][`super::Cell`] within a line (`Vec`).
10    pub(crate) x: u16,
11    /// The line number within [`ScreenBuffer`]'s scrollback buffer.
12    pub(crate) y: usize,
13}
14
15impl Position {
16    /// Sets [`Position`] to (0,0)
17    pub(super) const fn home() -> Self {
18        Self { x: 0, y: 0 }
19    }
20}
21
22impl From<(u16, usize)> for Position {
23    fn from((x, y): (u16, usize)) -> Self {
24        Self { x, y }
25    }
26}
27
28impl From<(u16, u16)> for Position {
29    fn from((x, y): (u16, u16)) -> Self {
30        Self { x, y: y as usize }
31    }
32}
33
34impl From<Position> for (u16, usize) {
35    fn from(position: Position) -> Self {
36        (position.x, position.y)
37    }
38}
39
40impl From<Position> for (u16, u16) {
41    fn from(position: Position) -> Self {
42        (position.x, position.y as u16)
43    }
44}
45
46impl Display for Position {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        write!(f, "({}, {})", self.x, self.y)
49    }
50}
51
52pub trait Cursor {
53    fn set_cursor_pos<P: Into<Position>>(&mut self, position: P);
54    fn move_cursor_left(&mut self, cells: u16);
55    fn move_cursor_up(&mut self, lines: u16);
56    fn move_cursor_down(&mut self, lines: u16);
57    fn move_cursor_right(&mut self, cells: u16);
58    fn set_cursor_col(&mut self, col: u16);
59}
60
61impl Cursor for ScreenBuffer {
62    /// Sets the cursor position.
63    fn set_cursor_pos<P: Into<Position>>(&mut self, position: P) {
64        self.cursor_pos = position.into();
65    }
66
67    /// Moves the cursor left by `cells`.
68    fn move_cursor_left(&mut self, cells: u16) {
69        self.cursor_pos.x = self.cursor_pos.x.saturating_sub(cells);
70    }
71
72    /// Moves the cursor up by `lines`.
73    fn move_cursor_up(&mut self, lines: u16) {
74        self.cursor_pos.y = self.cursor_pos.y.saturating_sub(lines as usize);
75    }
76
77    /// Moves the cursor down by `lines`.
78    fn move_cursor_down(&mut self, lines: u16) {
79        self.cursor_pos.y = self.cursor_pos.y.saturating_add(lines as usize);
80        while self.cursor_pos.y > self.lines.len() {
81            self.lines.push_back(Line::new(self.width as usize));
82        }
83    }
84
85    /// Moves the cursor right by `cells`.
86    fn move_cursor_right(&mut self, cells: u16) {
87        self.cursor_pos.x = self.cursor_pos.x.saturating_add(cells);
88    }
89
90    /// Sets the column of the cursor
91    fn set_cursor_col(&mut self, col: u16) {
92        self.cursor_pos.x = col;
93    }
94}