pub struct Page { /* private fields */ }Expand description
A whole page of text
This is a local copy of the entire terminal screen where the
required display can be built up before sending to the terminal
with an update TermShare::update.
This allows drawing text locally with clipping via the Region
struct. Coordinates are all i32 to allow for display objects to
be partially off the page edges. Each row stores cells with a
width in bytes according to the largest glyph in that row. So
storage adapts to the data.
Cloning a Page is efficient as the cloned page shares the same
row data as the original, and does copy-on-write.
Implementations§
Source§impl Page
impl Page
Sourcepub fn new(sy: i32, sx: i32, hfb: u16, sizer: Sizer) -> Self
pub fn new(sy: i32, sx: i32, hfb: u16, sizer: Sizer) -> Self
Create a new page with sy rows and width of sx cells,
filled with spaces with the given attribute hfb, and with
sizer to determine glyph boundaries and widths.
In general it’s easier to create a new page using
TermShare::page.
Sourcepub fn empty() -> Self
pub fn empty() -> Self
Create a dummy empty page, of zero size
Examples found in repository?
46 fn init(cx: CX![]) -> Option<Self> {
47 let _terminal = actor!(
48 cx,
49 Terminal::init(
50 SimpleSizer::new(),
51 fwd_to!([cx], resize() as (Option<TermShare>)),
52 fwd_to!([cx], input() as (Key))
53 ),
54 ret_some_to!([cx], |_, cx, cause: StopCause| {
55 println!("Terminal actor failed: {cause}");
56 stop!(cx);
57 })
58 );
59 Some(Self {
60 _terminal,
61 tshare: None,
62 page: Page::empty(),
63 spacing: 0,
64 spacing_on: false,
65 })
66 }Sourcepub fn sx(&self) -> i32
pub fn sx(&self) -> i32
Width of page in cells
Examples found in repository?
97 fn redraw(&mut self, cx: CX![], full: bool) {
98 let pg = &mut self.page;
99 let sx = pg.sx();
100 let sy = pg.sy();
101
102 if sy < 24 || sx < 80 {
103 let mut r = pg.full();
104 r.clear_all_99();
105 r.at(sy >> 1, (sx - 30) >> 1).hfb(162);
106 write!(r, " Terminal too small: {sy} x {sx} ").unwrap();
107 return;
108 }
109
110 const TEXT: &str = "This is a test. ";
111 const TEXTLEN: usize = TEXT.len();
112 let mid = sx >> 1;
113 for y in 0..sy {
114 let mut r = pg.region(y, 0, 1, sx + TEXTLEN as i32 * 2);
115 r.at(0, y % TEXTLEN as i32 - TEXTLEN as i32).hfb(99);
116 while r.get_x() < sx {
117 r.text(TEXT);
118 }
119 if self.spacing_on {
120 let mut x = (sx + sy) / 2 - y;
121 while x > 0 {
122 x -= self.spacing
123 }
124 r.at(0, x);
125 while r.get_x() < sx {
126 r.text("/");
127 r.skip(self.spacing - 1);
128 }
129 }
130 let shift = y * 6 / sy;
131 for x in 0..sx {
132 r.set_hfb(0, x, (((x - mid) >> shift) & 3) as u16 + 70);
133 }
134 }
135 pg.full()
136 .at(sy - 2, (sx - 40) >> 1)
137 .hfb(6)
138 .text(" PRESS ANY KEY TO CONTINUE, Ctrl-C TO END ");
139
140 self.update(cx, full);
141 }Sourcepub fn sy(&self) -> i32
pub fn sy(&self) -> i32
Height of page in lines
Examples found in repository?
97 fn redraw(&mut self, cx: CX![], full: bool) {
98 let pg = &mut self.page;
99 let sx = pg.sx();
100 let sy = pg.sy();
101
102 if sy < 24 || sx < 80 {
103 let mut r = pg.full();
104 r.clear_all_99();
105 r.at(sy >> 1, (sx - 30) >> 1).hfb(162);
106 write!(r, " Terminal too small: {sy} x {sx} ").unwrap();
107 return;
108 }
109
110 const TEXT: &str = "This is a test. ";
111 const TEXTLEN: usize = TEXT.len();
112 let mid = sx >> 1;
113 for y in 0..sy {
114 let mut r = pg.region(y, 0, 1, sx + TEXTLEN as i32 * 2);
115 r.at(0, y % TEXTLEN as i32 - TEXTLEN as i32).hfb(99);
116 while r.get_x() < sx {
117 r.text(TEXT);
118 }
119 if self.spacing_on {
120 let mut x = (sx + sy) / 2 - y;
121 while x > 0 {
122 x -= self.spacing
123 }
124 r.at(0, x);
125 while r.get_x() < sx {
126 r.text("/");
127 r.skip(self.spacing - 1);
128 }
129 }
130 let shift = y * 6 / sy;
131 for x in 0..sx {
132 r.set_hfb(0, x, (((x - mid) >> shift) & 3) as u16 + 70);
133 }
134 }
135 pg.full()
136 .at(sy - 2, (sx - 40) >> 1)
137 .hfb(6)
138 .text(" PRESS ANY KEY TO CONTINUE, Ctrl-C TO END ");
139
140 self.update(cx, full);
141 }Sourcepub fn full(&mut self) -> Region<'_> ⓘ
pub fn full(&mut self) -> Region<'_> ⓘ
Return a Region representing the full area of the page for
drawing on.
Examples found in repository?
97 fn redraw(&mut self, cx: CX![], full: bool) {
98 let pg = &mut self.page;
99 let sx = pg.sx();
100 let sy = pg.sy();
101
102 if sy < 24 || sx < 80 {
103 let mut r = pg.full();
104 r.clear_all_99();
105 r.at(sy >> 1, (sx - 30) >> 1).hfb(162);
106 write!(r, " Terminal too small: {sy} x {sx} ").unwrap();
107 return;
108 }
109
110 const TEXT: &str = "This is a test. ";
111 const TEXTLEN: usize = TEXT.len();
112 let mid = sx >> 1;
113 for y in 0..sy {
114 let mut r = pg.region(y, 0, 1, sx + TEXTLEN as i32 * 2);
115 r.at(0, y % TEXTLEN as i32 - TEXTLEN as i32).hfb(99);
116 while r.get_x() < sx {
117 r.text(TEXT);
118 }
119 if self.spacing_on {
120 let mut x = (sx + sy) / 2 - y;
121 while x > 0 {
122 x -= self.spacing
123 }
124 r.at(0, x);
125 while r.get_x() < sx {
126 r.text("/");
127 r.skip(self.spacing - 1);
128 }
129 }
130 let shift = y * 6 / sy;
131 for x in 0..sx {
132 r.set_hfb(0, x, (((x - mid) >> shift) & 3) as u16 + 70);
133 }
134 }
135 pg.full()
136 .at(sy - 2, (sx - 40) >> 1)
137 .hfb(6)
138 .text(" PRESS ANY KEY TO CONTINUE, Ctrl-C TO END ");
139
140 self.update(cx, full);
141 }Sourcepub fn region(&mut self, y: i32, x: i32, sy: i32, sx: i32) -> Region<'_> ⓘ
pub fn region(&mut self, y: i32, x: i32, sy: i32, sx: i32) -> Region<'_> ⓘ
Generate a Region that may be any size, inside or outside
the actual page. When drawn to, only the part of the region
that overlaps the actual page will be affected.
Examples found in repository?
97 fn redraw(&mut self, cx: CX![], full: bool) {
98 let pg = &mut self.page;
99 let sx = pg.sx();
100 let sy = pg.sy();
101
102 if sy < 24 || sx < 80 {
103 let mut r = pg.full();
104 r.clear_all_99();
105 r.at(sy >> 1, (sx - 30) >> 1).hfb(162);
106 write!(r, " Terminal too small: {sy} x {sx} ").unwrap();
107 return;
108 }
109
110 const TEXT: &str = "This is a test. ";
111 const TEXTLEN: usize = TEXT.len();
112 let mid = sx >> 1;
113 for y in 0..sy {
114 let mut r = pg.region(y, 0, 1, sx + TEXTLEN as i32 * 2);
115 r.at(0, y % TEXTLEN as i32 - TEXTLEN as i32).hfb(99);
116 while r.get_x() < sx {
117 r.text(TEXT);
118 }
119 if self.spacing_on {
120 let mut x = (sx + sy) / 2 - y;
121 while x > 0 {
122 x -= self.spacing
123 }
124 r.at(0, x);
125 while r.get_x() < sx {
126 r.text("/");
127 r.skip(self.spacing - 1);
128 }
129 }
130 let shift = y * 6 / sy;
131 for x in 0..sx {
132 r.set_hfb(0, x, (((x - mid) >> shift) & 3) as u16 + 70);
133 }
134 }
135 pg.full()
136 .at(sy - 2, (sx - 40) >> 1)
137 .hfb(6)
138 .text(" PRESS ANY KEY TO CONTINUE, Ctrl-C TO END ");
139
140 self.update(cx, full);
141 }Sourcepub fn measure(&mut self, text: &str) -> i32
pub fn measure(&mut self, text: &str) -> i32
Measures some text to see how many cells it will take up
horizontally. Skips HFB sequences of the form \0ZZZ
Sourcepub fn set_cursor(&mut self, cursor: Option<(i32, i32)>)
pub fn set_cursor(&mut self, cursor: Option<(i32, i32)>)
Set the cursor position, or hide the cursor if None is
passed. If the cursor position is provided but is off the
page, then the cursor is hidden instead.
Sourcepub fn scroll_up(&mut self, y0: i32, y1: i32, count: i32, hfb: u16)
pub fn scroll_up(&mut self, y0: i32, y1: i32, count: i32, hfb: u16)
Scroll the given region y0..y1 up the given number of lines.
Empty lines are filled with spaces of the given hfb colour.
This is very efficient as it manipulates whole rows.
Sourcepub fn scroll_down(&mut self, y0: i32, y1: i32, count: i32, hfb: u16)
pub fn scroll_down(&mut self, y0: i32, y1: i32, count: i32, hfb: u16)
Scroll the given region y0..y1 down by the given number of
lines. Empty lines are filled with spaces of the given hfb
colour. This is very efficient as it manipulates whole rows.
Sourcepub fn copy_lines(&mut self, ya: i32, yb: i32, sy: i32)
pub fn copy_lines(&mut self, ya: i32, yb: i32, sy: i32)
Copy lines from one part of a page to another, from line
ya..ya+sy to yb..yb+sy. Handles overlapping copies
correctly. Clips to page size before copying. Since this
copies whole rows using CoW it is very efficient.