Skip to main content

Output

Struct Output 

Source
pub struct Output { /* private fields */ }
Expand description

Output buffer for the terminal

This just buffers byte data on the way to the terminal. It allows batching up a whole screen update into a single write, to try to avoid tearing. This is shared between the Terminal actor and the actor(s) that will be writing data to the terminal whilst output is enabled via TermShare shared references.

Note that coordinates and sizes are passed as i32 here, because that is more convenient when relative offsets might be negative.

Calls that add to the buffer return the same self value, allowing the calls to be chained. This implements Write so macro calls in the form of write!(termout, ...) may be used to do formatted output. Nothing will be send to the output until the flush() call is made.

Not all ANSI sequences are covered here, just the basic ones required to implement a full-screen application and that are commonly supported everywhere, i.e. the lowest common denominator. If you need another ANSI sequence, it is easy to create, for example termout.csi().num(5).asc(';').num(10).asc('r') to set the scroll region to lines 5-10.

Implementations§

Source§

impl Output

Source

pub const BOX: &'static [char; 256]

Unicode box-drawing characters. There are four options for each direction: 0 nothing, 1 normal line, 2 thick line, 3 double line. The array index combines the four directions using (up << 6) + (down << 4) + (left << 2) + right, giving 256 combinations. Where a combination doesn’t exist in unicode (e.g. combined thick and double lines, or some double-line combinations) a replacement is made by converting double lines to thick lines.

See also Output::box_from_ascii_art

Source

pub fn features(&self) -> &Features

Get the features supported by the terminal

Examples found in repository?
examples/teeclub/main.rs (line 97)
89    fn resize(&mut self, cx: CX![], tsh: Option<TermShare>) {
90        self.tsh = tsh;
91
92        if let Some(ref tsh) = self.tsh {
93            let out = tsh.output(cx);
94            out.attr_99().cursor_show().scroll_up().save_cleanup();
95            out.cursor_hide().clear_all_99();
96
97            if self.logo_hfb.is_none() && out.features().colour_256 {
98                const LOGO_RGB: [(f64, u32); 7] = [
99                    (0.0, 0xFFFF00),
100                    (1.0, 0x00FF00),
101                    (2.0, 0x22FFFF),
102                    (3.0, 0x4444FF),
103                    (4.0, 0xFF22FF),
104                    (5.0, 0xFF0000),
105                    (6.0, 0xFFFF00),
106                ];
107                self.logo_hfb = Some(
108                    (0..30)
109                        .map(|i| {
110                            let rgb = out.rgb_interpolate(&LOGO_RGB, i as f64 * 0.2);
111                            out.hfb_alloc(false, false, rgb, 0x000000)
112                        })
113                        .collect(),
114                );
115            }
116
117            self.layout(cx);
118        }
119    }
More examples
Hide additional examples
examples/test0.rs (line 100)
86    fn draw(o: &mut Output) {
87        o.clear_all_99();
88        if o.sy() < 24 || o.sx() < 80 {
89            o.hfb(162);
90            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
91            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
92            o.hfb(99);
93            o.flush();
94            return;
95        }
96
97        let x0 = (o.sx() - 80) >> 1;
98        let y0 = (o.sy() - 24) >> 1;
99        let mut yy = y0;
100        let c256 = o.features().colour_256;
101        o.at(yy, x0).hfb(99).text("Colour mode:");
102        o.at(yy, x0 + 15)
103            .hfb(199)
104            .text(if c256 { "256-colour" } else { "8-colour" });
105        yy += 2;
106
107        o.at(yy, x0).hfb(99).text("Attributes:");
108        yy += 1;
109        const TEXT: [&str; 4] = ["White:", "Brown:", "Blue:", "Black:"];
110        const BASE_HFB: [u16; 4] = [70, 60, 10, 3];
111        for i in 0..4 {
112            let hfb = BASE_HFB[i];
113            o.at(yy, x0 + 2).hfb(99).text(TEXT[i]);
114            o.at(yy, x0 + 16).hfb(hfb).text(" norm ");
115            o.at(yy, x0 + 22).hfb(100 + hfb).text("bold ");
116            o.at(yy, x0 + 27).hfb(200 + hfb).text("undl ");
117            o.at(yy, x0 + 32).hfb(300 + hfb).text("both ");
118            yy += 1;
119        }
120        o.at(yy + 1, x0)
121            .hfb(60)
122            .text(" (On 8-colour expect bold/ul to");
123        o.at(yy + 2, x0)
124            .hfb(60)
125            .text("  be emulated as colour changes.)");
126        let y1a = yy + 3;
127
128        yy = y0;
129        o.at(yy, x0 + 40)
130            .hfb(99)
131            .text("Base, bold and background colours:");
132        o.at(yy + 1, x0 + 42).hfb(7).text("  black   ");
133        o.at(yy + 2, x0 + 42).hfb(10).text("  blue    ");
134        o.at(yy + 3, x0 + 42).hfb(20).text("  red     ");
135        o.at(yy + 4, x0 + 42).hfb(30).text("  magenta ");
136        o.at(yy + 5, x0 + 42).hfb(40).text("  green   ");
137        o.at(yy + 6, x0 + 42).hfb(50).text("  cyan    ");
138        o.at(yy + 7, x0 + 42).hfb(60).text("  yellow  ");
139        o.at(yy + 8, x0 + 42).hfb(70).text("  white   ");
140        o.at(yy + 1, x0 + 54).hfb(100).text("  black   ");
141        o.at(yy + 2, x0 + 54).hfb(110).text("  blue    ");
142        o.at(yy + 3, x0 + 54).hfb(120).text("  red     ");
143        o.at(yy + 4, x0 + 54).hfb(130).text("  magenta ");
144        o.at(yy + 5, x0 + 54).hfb(140).text("  green   ");
145        o.at(yy + 6, x0 + 54).hfb(150).text("  cyan    ");
146        o.at(yy + 7, x0 + 54).hfb(160).text("  yellow  ");
147        o.at(yy + 8, x0 + 54).hfb(170).text("  white   ");
148        o.at(yy + 1, x0 + 66).hfb(70).text("  black   ");
149        o.at(yy + 2, x0 + 66).hfb(71).text("  blue    ");
150        o.at(yy + 3, x0 + 66).hfb(72).text("  red     ");
151        o.at(yy + 4, x0 + 66).hfb(73).text("  magenta ");
152        o.at(yy + 5, x0 + 66).hfb(4).text("  green   ");
153        o.at(yy + 6, x0 + 66).hfb(5).text("  cyan    ");
154        o.at(yy + 7, x0 + 66).hfb(6).text("  yellow  ");
155        o.at(yy + 8, x0 + 66).hfb(7).text("  white   ");
156        o.at(yy + 10, x0 + 40)
157            .hfb(60)
158            .text(" (Expect all 16 colours to be");
159        o.at(yy + 11, x0 + 40)
160            .hfb(60)
161            .text("  visible in all cases.)");
162        let y1b = yy + 12;
163        let end = y1a.max(y1b);
164
165        yy = end + 10;
166        o.at(yy - 1, x0).hfb(99).text("Hue wheel");
167        o.at(yy, x0);
168        if o.features().colour_256 {
169            const RED: [i32; 7] = [255, 255, 0, 0, 0, 255, 255];
170            const GREEN: [i32; 7] = [0, 255, 255, 255, 0, 0, 0];
171            const BLUE: [i32; 7] = [0, 0, 0, 255, 255, 255, 0];
172            for x in 0..78 {
173                let i = x / 13;
174                let off = (x - i * 13) as i32;
175                let r = RED[i] + (RED[i + 1] - RED[i]) * off / 13;
176                let g = GREEN[i] + (GREEN[i + 1] - GREEN[i]) * off / 13;
177                let b = BLUE[i] + (BLUE[i + 1] - BLUE[i]) * off / 13;
178                let rgb = (r << 16) + (g << 8) + b;
179                let hfb = o.hfb_alloc(false, false, 0xFFFFFF, rgb as u32);
180                o.hfb(hfb).spaces(1);
181            }
182        } else {
183            o.hfb(2).spaces(13);
184            o.hfb(6).spaces(13);
185            o.hfb(4).spaces(13);
186            o.hfb(5).spaces(13);
187            o.hfb(1).spaces(13);
188            o.hfb(3).spaces(13);
189        }
190
191        yy = end + 1;
192        let mut xx = x0 + 40;
193
194        o.at(yy, xx).hfb(99).text("ASCII");
195        for a in 0..96 {
196            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
197                .char(char::from_u32((a + 32) as u32).unwrap());
198        }
199
200        xx += 20;
201        o.at(yy, xx).hfb(99).text("Latin-1");
202        for a in 0..96 {
203            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
204                .char(char::from_u32((a + 160) as u32).unwrap());
205        }
206
207        const BOXTITLE1: &str = "\
208Single  Single  Double  Thick";
209        const BOXTITLE2: &str = "\
210+Double +Thick  +Single +Single";
211
212        const BOXTEST: &str = "\
213+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
214| | H | | | $ | H H | H $ $ | $
215+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
216| | H | | | $ | H H | H $ $ | $
217+=+=+=+ +*+*+*+ +-+-+-+ +-+-+-+
218| | H | | | $ | H H | H $ $ | $
219+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+";
220
221        let boxtest = Output::box_from_ascii_art(BOXTEST);
222        yy = end + 1;
223        xx = x0 + 2;
224        o.at(yy - 2, xx).text(BOXTITLE1);
225        o.at(yy - 1, xx).text(BOXTITLE2);
226        for line in boxtest.split('\n') {
227            o.at(yy, xx).text(line);
228            yy += 1;
229        }
230
231        o.flush();
232    }
Source

pub fn sizer(&self) -> Sizer

Get the active Sizer

Source

pub fn size(&self) -> (i32, i32)

Get current terminal size: (rows, columns)

Source

pub fn sy(&self) -> i32

Get current terminal size-Y, i.e. rows

Examples found in repository?
examples/test1.rs (line 111)
108    fn draw(o: &mut Output) {
109        o.clear_all_99();
110        let sx = o.sx();
111        let sy = o.sy();
112        if sy < 24 || sx < 80 {
113            o.hfb(162);
114            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
115            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
116            o.hfb(99);
117            o.flush();
118            return;
119        }
120
121        const TEXT: [char; 17] = [
122            'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', '.', ' ', ' ',
123        ];
124        let mut last_hfb = 99;
125        for y in 0..sy {
126            o.at(y, 0);
127            for x in 0..sx {
128                let hfb = ((x * 8) / sx + (y & 7) * 10 + ((y >> 3) & 1) * 100) as u16;
129                if hfb != last_hfb {
130                    o.hfb(hfb);
131                    last_hfb = hfb;
132                }
133                o.char(TEXT[(1000 + x - y) as usize % TEXT.len()]);
134            }
135        }
136        o.at(sy - 2, (sx - 60) / 2)
137            .hfb(162)
138            .text("[ Type to show decoding, Ctrl-C to exit, Ctrl-L to redraw ]")
139            .hfb(99);
140        o.at(0, 0);
141        o.flush();
142    }
More examples
Hide additional examples
examples/test0.rs (line 88)
86    fn draw(o: &mut Output) {
87        o.clear_all_99();
88        if o.sy() < 24 || o.sx() < 80 {
89            o.hfb(162);
90            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
91            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
92            o.hfb(99);
93            o.flush();
94            return;
95        }
96
97        let x0 = (o.sx() - 80) >> 1;
98        let y0 = (o.sy() - 24) >> 1;
99        let mut yy = y0;
100        let c256 = o.features().colour_256;
101        o.at(yy, x0).hfb(99).text("Colour mode:");
102        o.at(yy, x0 + 15)
103            .hfb(199)
104            .text(if c256 { "256-colour" } else { "8-colour" });
105        yy += 2;
106
107        o.at(yy, x0).hfb(99).text("Attributes:");
108        yy += 1;
109        const TEXT: [&str; 4] = ["White:", "Brown:", "Blue:", "Black:"];
110        const BASE_HFB: [u16; 4] = [70, 60, 10, 3];
111        for i in 0..4 {
112            let hfb = BASE_HFB[i];
113            o.at(yy, x0 + 2).hfb(99).text(TEXT[i]);
114            o.at(yy, x0 + 16).hfb(hfb).text(" norm ");
115            o.at(yy, x0 + 22).hfb(100 + hfb).text("bold ");
116            o.at(yy, x0 + 27).hfb(200 + hfb).text("undl ");
117            o.at(yy, x0 + 32).hfb(300 + hfb).text("both ");
118            yy += 1;
119        }
120        o.at(yy + 1, x0)
121            .hfb(60)
122            .text(" (On 8-colour expect bold/ul to");
123        o.at(yy + 2, x0)
124            .hfb(60)
125            .text("  be emulated as colour changes.)");
126        let y1a = yy + 3;
127
128        yy = y0;
129        o.at(yy, x0 + 40)
130            .hfb(99)
131            .text("Base, bold and background colours:");
132        o.at(yy + 1, x0 + 42).hfb(7).text("  black   ");
133        o.at(yy + 2, x0 + 42).hfb(10).text("  blue    ");
134        o.at(yy + 3, x0 + 42).hfb(20).text("  red     ");
135        o.at(yy + 4, x0 + 42).hfb(30).text("  magenta ");
136        o.at(yy + 5, x0 + 42).hfb(40).text("  green   ");
137        o.at(yy + 6, x0 + 42).hfb(50).text("  cyan    ");
138        o.at(yy + 7, x0 + 42).hfb(60).text("  yellow  ");
139        o.at(yy + 8, x0 + 42).hfb(70).text("  white   ");
140        o.at(yy + 1, x0 + 54).hfb(100).text("  black   ");
141        o.at(yy + 2, x0 + 54).hfb(110).text("  blue    ");
142        o.at(yy + 3, x0 + 54).hfb(120).text("  red     ");
143        o.at(yy + 4, x0 + 54).hfb(130).text("  magenta ");
144        o.at(yy + 5, x0 + 54).hfb(140).text("  green   ");
145        o.at(yy + 6, x0 + 54).hfb(150).text("  cyan    ");
146        o.at(yy + 7, x0 + 54).hfb(160).text("  yellow  ");
147        o.at(yy + 8, x0 + 54).hfb(170).text("  white   ");
148        o.at(yy + 1, x0 + 66).hfb(70).text("  black   ");
149        o.at(yy + 2, x0 + 66).hfb(71).text("  blue    ");
150        o.at(yy + 3, x0 + 66).hfb(72).text("  red     ");
151        o.at(yy + 4, x0 + 66).hfb(73).text("  magenta ");
152        o.at(yy + 5, x0 + 66).hfb(4).text("  green   ");
153        o.at(yy + 6, x0 + 66).hfb(5).text("  cyan    ");
154        o.at(yy + 7, x0 + 66).hfb(6).text("  yellow  ");
155        o.at(yy + 8, x0 + 66).hfb(7).text("  white   ");
156        o.at(yy + 10, x0 + 40)
157            .hfb(60)
158            .text(" (Expect all 16 colours to be");
159        o.at(yy + 11, x0 + 40)
160            .hfb(60)
161            .text("  visible in all cases.)");
162        let y1b = yy + 12;
163        let end = y1a.max(y1b);
164
165        yy = end + 10;
166        o.at(yy - 1, x0).hfb(99).text("Hue wheel");
167        o.at(yy, x0);
168        if o.features().colour_256 {
169            const RED: [i32; 7] = [255, 255, 0, 0, 0, 255, 255];
170            const GREEN: [i32; 7] = [0, 255, 255, 255, 0, 0, 0];
171            const BLUE: [i32; 7] = [0, 0, 0, 255, 255, 255, 0];
172            for x in 0..78 {
173                let i = x / 13;
174                let off = (x - i * 13) as i32;
175                let r = RED[i] + (RED[i + 1] - RED[i]) * off / 13;
176                let g = GREEN[i] + (GREEN[i + 1] - GREEN[i]) * off / 13;
177                let b = BLUE[i] + (BLUE[i + 1] - BLUE[i]) * off / 13;
178                let rgb = (r << 16) + (g << 8) + b;
179                let hfb = o.hfb_alloc(false, false, 0xFFFFFF, rgb as u32);
180                o.hfb(hfb).spaces(1);
181            }
182        } else {
183            o.hfb(2).spaces(13);
184            o.hfb(6).spaces(13);
185            o.hfb(4).spaces(13);
186            o.hfb(5).spaces(13);
187            o.hfb(1).spaces(13);
188            o.hfb(3).spaces(13);
189        }
190
191        yy = end + 1;
192        let mut xx = x0 + 40;
193
194        o.at(yy, xx).hfb(99).text("ASCII");
195        for a in 0..96 {
196            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
197                .char(char::from_u32((a + 32) as u32).unwrap());
198        }
199
200        xx += 20;
201        o.at(yy, xx).hfb(99).text("Latin-1");
202        for a in 0..96 {
203            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
204                .char(char::from_u32((a + 160) as u32).unwrap());
205        }
206
207        const BOXTITLE1: &str = "\
208Single  Single  Double  Thick";
209        const BOXTITLE2: &str = "\
210+Double +Thick  +Single +Single";
211
212        const BOXTEST: &str = "\
213+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
214| | H | | | $ | H H | H $ $ | $
215+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
216| | H | | | $ | H H | H $ $ | $
217+=+=+=+ +*+*+*+ +-+-+-+ +-+-+-+
218| | H | | | $ | H H | H $ $ | $
219+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+";
220
221        let boxtest = Output::box_from_ascii_art(BOXTEST);
222        yy = end + 1;
223        xx = x0 + 2;
224        o.at(yy - 2, xx).text(BOXTITLE1);
225        o.at(yy - 1, xx).text(BOXTITLE2);
226        for line in boxtest.split('\n') {
227            o.at(yy, xx).text(line);
228            yy += 1;
229        }
230
231        o.flush();
232    }
Source

pub fn sx(&self) -> i32

Get current terminal size-X, i.e. columns

Examples found in repository?
examples/test1.rs (line 110)
108    fn draw(o: &mut Output) {
109        o.clear_all_99();
110        let sx = o.sx();
111        let sy = o.sy();
112        if sy < 24 || sx < 80 {
113            o.hfb(162);
114            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
115            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
116            o.hfb(99);
117            o.flush();
118            return;
119        }
120
121        const TEXT: [char; 17] = [
122            'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', '.', ' ', ' ',
123        ];
124        let mut last_hfb = 99;
125        for y in 0..sy {
126            o.at(y, 0);
127            for x in 0..sx {
128                let hfb = ((x * 8) / sx + (y & 7) * 10 + ((y >> 3) & 1) * 100) as u16;
129                if hfb != last_hfb {
130                    o.hfb(hfb);
131                    last_hfb = hfb;
132                }
133                o.char(TEXT[(1000 + x - y) as usize % TEXT.len()]);
134            }
135        }
136        o.at(sy - 2, (sx - 60) / 2)
137            .hfb(162)
138            .text("[ Type to show decoding, Ctrl-C to exit, Ctrl-L to redraw ]")
139            .hfb(99);
140        o.at(0, 0);
141        o.flush();
142    }
More examples
Hide additional examples
examples/test0.rs (line 88)
86    fn draw(o: &mut Output) {
87        o.clear_all_99();
88        if o.sy() < 24 || o.sx() < 80 {
89            o.hfb(162);
90            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
91            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
92            o.hfb(99);
93            o.flush();
94            return;
95        }
96
97        let x0 = (o.sx() - 80) >> 1;
98        let y0 = (o.sy() - 24) >> 1;
99        let mut yy = y0;
100        let c256 = o.features().colour_256;
101        o.at(yy, x0).hfb(99).text("Colour mode:");
102        o.at(yy, x0 + 15)
103            .hfb(199)
104            .text(if c256 { "256-colour" } else { "8-colour" });
105        yy += 2;
106
107        o.at(yy, x0).hfb(99).text("Attributes:");
108        yy += 1;
109        const TEXT: [&str; 4] = ["White:", "Brown:", "Blue:", "Black:"];
110        const BASE_HFB: [u16; 4] = [70, 60, 10, 3];
111        for i in 0..4 {
112            let hfb = BASE_HFB[i];
113            o.at(yy, x0 + 2).hfb(99).text(TEXT[i]);
114            o.at(yy, x0 + 16).hfb(hfb).text(" norm ");
115            o.at(yy, x0 + 22).hfb(100 + hfb).text("bold ");
116            o.at(yy, x0 + 27).hfb(200 + hfb).text("undl ");
117            o.at(yy, x0 + 32).hfb(300 + hfb).text("both ");
118            yy += 1;
119        }
120        o.at(yy + 1, x0)
121            .hfb(60)
122            .text(" (On 8-colour expect bold/ul to");
123        o.at(yy + 2, x0)
124            .hfb(60)
125            .text("  be emulated as colour changes.)");
126        let y1a = yy + 3;
127
128        yy = y0;
129        o.at(yy, x0 + 40)
130            .hfb(99)
131            .text("Base, bold and background colours:");
132        o.at(yy + 1, x0 + 42).hfb(7).text("  black   ");
133        o.at(yy + 2, x0 + 42).hfb(10).text("  blue    ");
134        o.at(yy + 3, x0 + 42).hfb(20).text("  red     ");
135        o.at(yy + 4, x0 + 42).hfb(30).text("  magenta ");
136        o.at(yy + 5, x0 + 42).hfb(40).text("  green   ");
137        o.at(yy + 6, x0 + 42).hfb(50).text("  cyan    ");
138        o.at(yy + 7, x0 + 42).hfb(60).text("  yellow  ");
139        o.at(yy + 8, x0 + 42).hfb(70).text("  white   ");
140        o.at(yy + 1, x0 + 54).hfb(100).text("  black   ");
141        o.at(yy + 2, x0 + 54).hfb(110).text("  blue    ");
142        o.at(yy + 3, x0 + 54).hfb(120).text("  red     ");
143        o.at(yy + 4, x0 + 54).hfb(130).text("  magenta ");
144        o.at(yy + 5, x0 + 54).hfb(140).text("  green   ");
145        o.at(yy + 6, x0 + 54).hfb(150).text("  cyan    ");
146        o.at(yy + 7, x0 + 54).hfb(160).text("  yellow  ");
147        o.at(yy + 8, x0 + 54).hfb(170).text("  white   ");
148        o.at(yy + 1, x0 + 66).hfb(70).text("  black   ");
149        o.at(yy + 2, x0 + 66).hfb(71).text("  blue    ");
150        o.at(yy + 3, x0 + 66).hfb(72).text("  red     ");
151        o.at(yy + 4, x0 + 66).hfb(73).text("  magenta ");
152        o.at(yy + 5, x0 + 66).hfb(4).text("  green   ");
153        o.at(yy + 6, x0 + 66).hfb(5).text("  cyan    ");
154        o.at(yy + 7, x0 + 66).hfb(6).text("  yellow  ");
155        o.at(yy + 8, x0 + 66).hfb(7).text("  white   ");
156        o.at(yy + 10, x0 + 40)
157            .hfb(60)
158            .text(" (Expect all 16 colours to be");
159        o.at(yy + 11, x0 + 40)
160            .hfb(60)
161            .text("  visible in all cases.)");
162        let y1b = yy + 12;
163        let end = y1a.max(y1b);
164
165        yy = end + 10;
166        o.at(yy - 1, x0).hfb(99).text("Hue wheel");
167        o.at(yy, x0);
168        if o.features().colour_256 {
169            const RED: [i32; 7] = [255, 255, 0, 0, 0, 255, 255];
170            const GREEN: [i32; 7] = [0, 255, 255, 255, 0, 0, 0];
171            const BLUE: [i32; 7] = [0, 0, 0, 255, 255, 255, 0];
172            for x in 0..78 {
173                let i = x / 13;
174                let off = (x - i * 13) as i32;
175                let r = RED[i] + (RED[i + 1] - RED[i]) * off / 13;
176                let g = GREEN[i] + (GREEN[i + 1] - GREEN[i]) * off / 13;
177                let b = BLUE[i] + (BLUE[i + 1] - BLUE[i]) * off / 13;
178                let rgb = (r << 16) + (g << 8) + b;
179                let hfb = o.hfb_alloc(false, false, 0xFFFFFF, rgb as u32);
180                o.hfb(hfb).spaces(1);
181            }
182        } else {
183            o.hfb(2).spaces(13);
184            o.hfb(6).spaces(13);
185            o.hfb(4).spaces(13);
186            o.hfb(5).spaces(13);
187            o.hfb(1).spaces(13);
188            o.hfb(3).spaces(13);
189        }
190
191        yy = end + 1;
192        let mut xx = x0 + 40;
193
194        o.at(yy, xx).hfb(99).text("ASCII");
195        for a in 0..96 {
196            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
197                .char(char::from_u32((a + 32) as u32).unwrap());
198        }
199
200        xx += 20;
201        o.at(yy, xx).hfb(99).text("Latin-1");
202        for a in 0..96 {
203            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
204                .char(char::from_u32((a + 160) as u32).unwrap());
205        }
206
207        const BOXTITLE1: &str = "\
208Single  Single  Double  Thick";
209        const BOXTITLE2: &str = "\
210+Double +Thick  +Single +Single";
211
212        const BOXTEST: &str = "\
213+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
214| | H | | | $ | H H | H $ $ | $
215+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
216| | H | | | $ | H H | H $ $ | $
217+=+=+=+ +*+*+*+ +-+-+-+ +-+-+-+
218| | H | | | $ | H H | H $ $ | $
219+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+";
220
221        let boxtest = Output::box_from_ascii_art(BOXTEST);
222        yy = end + 1;
223        xx = x0 + 2;
224        o.at(yy - 2, xx).text(BOXTITLE1);
225        o.at(yy - 1, xx).text(BOXTITLE2);
226        for line in boxtest.split('\n') {
227            o.at(yy, xx).text(line);
228            yy += 1;
229        }
230
231        o.flush();
232    }
Source

pub fn flush(&mut self)

Mark all the data from the start of the buffer to the current end of the buffer as ready for flushing and send a message to the Terminal to do the flush. Any data added after this call won’t be flushed unless another call to this method is made. This gives precise control of how much data is flushed despite flushing being an asynchronous operation.

Examples found in repository?
examples/test1.rs (line 102)
78    fn input(&mut self, cx: CX![], key: Key) {
79        match key {
80            Key::Ctrl('L') => self.redraw(cx),
81            Key::Ctrl('C') => stop!(cx),
82            _ => {
83                use std::str::FromStr;
84                let s = format!("{key}");
85                let k = Key::from_str(&s);
86                assert!(k.is_ok(), "Round-trip failed for {s}");
87                let k = k.unwrap();
88                assert_eq!(k, key, "Mismatch for {key} -> {s} -> {k}");
89                let hfb = if s.starts_with("M-") {
90                    172
91                } else if s.starts_with("C-") {
92                    141
93                } else if matches!(key, Key::Pr(_)) {
94                    151
95                } else {
96                    162
97                };
98                if let Some(ref tshare) = self.tshare {
99                    let o = tshare.output(cx);
100                    o.hfb(hfb).text(&s);
101                    o.hfb(71).text(" ");
102                    o.flush();
103                }
104            }
105        }
106    }
107
108    fn draw(o: &mut Output) {
109        o.clear_all_99();
110        let sx = o.sx();
111        let sy = o.sy();
112        if sy < 24 || sx < 80 {
113            o.hfb(162);
114            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
115            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
116            o.hfb(99);
117            o.flush();
118            return;
119        }
120
121        const TEXT: [char; 17] = [
122            'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', '.', ' ', ' ',
123        ];
124        let mut last_hfb = 99;
125        for y in 0..sy {
126            o.at(y, 0);
127            for x in 0..sx {
128                let hfb = ((x * 8) / sx + (y & 7) * 10 + ((y >> 3) & 1) * 100) as u16;
129                if hfb != last_hfb {
130                    o.hfb(hfb);
131                    last_hfb = hfb;
132                }
133                o.char(TEXT[(1000 + x - y) as usize % TEXT.len()]);
134            }
135        }
136        o.at(sy - 2, (sx - 60) / 2)
137            .hfb(162)
138            .text("[ Type to show decoding, Ctrl-C to exit, Ctrl-L to redraw ]")
139            .hfb(99);
140        o.at(0, 0);
141        o.flush();
142    }
More examples
Hide additional examples
examples/test0.rs (line 93)
86    fn draw(o: &mut Output) {
87        o.clear_all_99();
88        if o.sy() < 24 || o.sx() < 80 {
89            o.hfb(162);
90            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
91            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
92            o.hfb(99);
93            o.flush();
94            return;
95        }
96
97        let x0 = (o.sx() - 80) >> 1;
98        let y0 = (o.sy() - 24) >> 1;
99        let mut yy = y0;
100        let c256 = o.features().colour_256;
101        o.at(yy, x0).hfb(99).text("Colour mode:");
102        o.at(yy, x0 + 15)
103            .hfb(199)
104            .text(if c256 { "256-colour" } else { "8-colour" });
105        yy += 2;
106
107        o.at(yy, x0).hfb(99).text("Attributes:");
108        yy += 1;
109        const TEXT: [&str; 4] = ["White:", "Brown:", "Blue:", "Black:"];
110        const BASE_HFB: [u16; 4] = [70, 60, 10, 3];
111        for i in 0..4 {
112            let hfb = BASE_HFB[i];
113            o.at(yy, x0 + 2).hfb(99).text(TEXT[i]);
114            o.at(yy, x0 + 16).hfb(hfb).text(" norm ");
115            o.at(yy, x0 + 22).hfb(100 + hfb).text("bold ");
116            o.at(yy, x0 + 27).hfb(200 + hfb).text("undl ");
117            o.at(yy, x0 + 32).hfb(300 + hfb).text("both ");
118            yy += 1;
119        }
120        o.at(yy + 1, x0)
121            .hfb(60)
122            .text(" (On 8-colour expect bold/ul to");
123        o.at(yy + 2, x0)
124            .hfb(60)
125            .text("  be emulated as colour changes.)");
126        let y1a = yy + 3;
127
128        yy = y0;
129        o.at(yy, x0 + 40)
130            .hfb(99)
131            .text("Base, bold and background colours:");
132        o.at(yy + 1, x0 + 42).hfb(7).text("  black   ");
133        o.at(yy + 2, x0 + 42).hfb(10).text("  blue    ");
134        o.at(yy + 3, x0 + 42).hfb(20).text("  red     ");
135        o.at(yy + 4, x0 + 42).hfb(30).text("  magenta ");
136        o.at(yy + 5, x0 + 42).hfb(40).text("  green   ");
137        o.at(yy + 6, x0 + 42).hfb(50).text("  cyan    ");
138        o.at(yy + 7, x0 + 42).hfb(60).text("  yellow  ");
139        o.at(yy + 8, x0 + 42).hfb(70).text("  white   ");
140        o.at(yy + 1, x0 + 54).hfb(100).text("  black   ");
141        o.at(yy + 2, x0 + 54).hfb(110).text("  blue    ");
142        o.at(yy + 3, x0 + 54).hfb(120).text("  red     ");
143        o.at(yy + 4, x0 + 54).hfb(130).text("  magenta ");
144        o.at(yy + 5, x0 + 54).hfb(140).text("  green   ");
145        o.at(yy + 6, x0 + 54).hfb(150).text("  cyan    ");
146        o.at(yy + 7, x0 + 54).hfb(160).text("  yellow  ");
147        o.at(yy + 8, x0 + 54).hfb(170).text("  white   ");
148        o.at(yy + 1, x0 + 66).hfb(70).text("  black   ");
149        o.at(yy + 2, x0 + 66).hfb(71).text("  blue    ");
150        o.at(yy + 3, x0 + 66).hfb(72).text("  red     ");
151        o.at(yy + 4, x0 + 66).hfb(73).text("  magenta ");
152        o.at(yy + 5, x0 + 66).hfb(4).text("  green   ");
153        o.at(yy + 6, x0 + 66).hfb(5).text("  cyan    ");
154        o.at(yy + 7, x0 + 66).hfb(6).text("  yellow  ");
155        o.at(yy + 8, x0 + 66).hfb(7).text("  white   ");
156        o.at(yy + 10, x0 + 40)
157            .hfb(60)
158            .text(" (Expect all 16 colours to be");
159        o.at(yy + 11, x0 + 40)
160            .hfb(60)
161            .text("  visible in all cases.)");
162        let y1b = yy + 12;
163        let end = y1a.max(y1b);
164
165        yy = end + 10;
166        o.at(yy - 1, x0).hfb(99).text("Hue wheel");
167        o.at(yy, x0);
168        if o.features().colour_256 {
169            const RED: [i32; 7] = [255, 255, 0, 0, 0, 255, 255];
170            const GREEN: [i32; 7] = [0, 255, 255, 255, 0, 0, 0];
171            const BLUE: [i32; 7] = [0, 0, 0, 255, 255, 255, 0];
172            for x in 0..78 {
173                let i = x / 13;
174                let off = (x - i * 13) as i32;
175                let r = RED[i] + (RED[i + 1] - RED[i]) * off / 13;
176                let g = GREEN[i] + (GREEN[i + 1] - GREEN[i]) * off / 13;
177                let b = BLUE[i] + (BLUE[i + 1] - BLUE[i]) * off / 13;
178                let rgb = (r << 16) + (g << 8) + b;
179                let hfb = o.hfb_alloc(false, false, 0xFFFFFF, rgb as u32);
180                o.hfb(hfb).spaces(1);
181            }
182        } else {
183            o.hfb(2).spaces(13);
184            o.hfb(6).spaces(13);
185            o.hfb(4).spaces(13);
186            o.hfb(5).spaces(13);
187            o.hfb(1).spaces(13);
188            o.hfb(3).spaces(13);
189        }
190
191        yy = end + 1;
192        let mut xx = x0 + 40;
193
194        o.at(yy, xx).hfb(99).text("ASCII");
195        for a in 0..96 {
196            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
197                .char(char::from_u32((a + 32) as u32).unwrap());
198        }
199
200        xx += 20;
201        o.at(yy, xx).hfb(99).text("Latin-1");
202        for a in 0..96 {
203            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
204                .char(char::from_u32((a + 160) as u32).unwrap());
205        }
206
207        const BOXTITLE1: &str = "\
208Single  Single  Double  Thick";
209        const BOXTITLE2: &str = "\
210+Double +Thick  +Single +Single";
211
212        const BOXTEST: &str = "\
213+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
214| | H | | | $ | H H | H $ $ | $
215+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
216| | H | | | $ | H H | H $ $ | $
217+=+=+=+ +*+*+*+ +-+-+-+ +-+-+-+
218| | H | | | $ | H H | H $ $ | $
219+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+";
220
221        let boxtest = Output::box_from_ascii_art(BOXTEST);
222        yy = end + 1;
223        xx = x0 + 2;
224        o.at(yy - 2, xx).text(BOXTITLE1);
225        o.at(yy - 1, xx).text(BOXTITLE2);
226        for line in boxtest.split('\n') {
227            o.at(yy, xx).text(line);
228            yy += 1;
229        }
230
231        o.flush();
232    }
Source

pub fn text(&mut self, data: &str) -> &mut Self

Add a chunk of UTF-8 string data to the output buffer.

See also the Write implementation, which allows use of write! and writeln! to add data to the buffer.

Examples found in repository?
examples/test1.rs (line 100)
78    fn input(&mut self, cx: CX![], key: Key) {
79        match key {
80            Key::Ctrl('L') => self.redraw(cx),
81            Key::Ctrl('C') => stop!(cx),
82            _ => {
83                use std::str::FromStr;
84                let s = format!("{key}");
85                let k = Key::from_str(&s);
86                assert!(k.is_ok(), "Round-trip failed for {s}");
87                let k = k.unwrap();
88                assert_eq!(k, key, "Mismatch for {key} -> {s} -> {k}");
89                let hfb = if s.starts_with("M-") {
90                    172
91                } else if s.starts_with("C-") {
92                    141
93                } else if matches!(key, Key::Pr(_)) {
94                    151
95                } else {
96                    162
97                };
98                if let Some(ref tshare) = self.tshare {
99                    let o = tshare.output(cx);
100                    o.hfb(hfb).text(&s);
101                    o.hfb(71).text(" ");
102                    o.flush();
103                }
104            }
105        }
106    }
107
108    fn draw(o: &mut Output) {
109        o.clear_all_99();
110        let sx = o.sx();
111        let sy = o.sy();
112        if sy < 24 || sx < 80 {
113            o.hfb(162);
114            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
115            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
116            o.hfb(99);
117            o.flush();
118            return;
119        }
120
121        const TEXT: [char; 17] = [
122            'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', '.', ' ', ' ',
123        ];
124        let mut last_hfb = 99;
125        for y in 0..sy {
126            o.at(y, 0);
127            for x in 0..sx {
128                let hfb = ((x * 8) / sx + (y & 7) * 10 + ((y >> 3) & 1) * 100) as u16;
129                if hfb != last_hfb {
130                    o.hfb(hfb);
131                    last_hfb = hfb;
132                }
133                o.char(TEXT[(1000 + x - y) as usize % TEXT.len()]);
134            }
135        }
136        o.at(sy - 2, (sx - 60) / 2)
137            .hfb(162)
138            .text("[ Type to show decoding, Ctrl-C to exit, Ctrl-L to redraw ]")
139            .hfb(99);
140        o.at(0, 0);
141        o.flush();
142    }
More examples
Hide additional examples
examples/test0.rs (line 101)
86    fn draw(o: &mut Output) {
87        o.clear_all_99();
88        if o.sy() < 24 || o.sx() < 80 {
89            o.hfb(162);
90            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
91            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
92            o.hfb(99);
93            o.flush();
94            return;
95        }
96
97        let x0 = (o.sx() - 80) >> 1;
98        let y0 = (o.sy() - 24) >> 1;
99        let mut yy = y0;
100        let c256 = o.features().colour_256;
101        o.at(yy, x0).hfb(99).text("Colour mode:");
102        o.at(yy, x0 + 15)
103            .hfb(199)
104            .text(if c256 { "256-colour" } else { "8-colour" });
105        yy += 2;
106
107        o.at(yy, x0).hfb(99).text("Attributes:");
108        yy += 1;
109        const TEXT: [&str; 4] = ["White:", "Brown:", "Blue:", "Black:"];
110        const BASE_HFB: [u16; 4] = [70, 60, 10, 3];
111        for i in 0..4 {
112            let hfb = BASE_HFB[i];
113            o.at(yy, x0 + 2).hfb(99).text(TEXT[i]);
114            o.at(yy, x0 + 16).hfb(hfb).text(" norm ");
115            o.at(yy, x0 + 22).hfb(100 + hfb).text("bold ");
116            o.at(yy, x0 + 27).hfb(200 + hfb).text("undl ");
117            o.at(yy, x0 + 32).hfb(300 + hfb).text("both ");
118            yy += 1;
119        }
120        o.at(yy + 1, x0)
121            .hfb(60)
122            .text(" (On 8-colour expect bold/ul to");
123        o.at(yy + 2, x0)
124            .hfb(60)
125            .text("  be emulated as colour changes.)");
126        let y1a = yy + 3;
127
128        yy = y0;
129        o.at(yy, x0 + 40)
130            .hfb(99)
131            .text("Base, bold and background colours:");
132        o.at(yy + 1, x0 + 42).hfb(7).text("  black   ");
133        o.at(yy + 2, x0 + 42).hfb(10).text("  blue    ");
134        o.at(yy + 3, x0 + 42).hfb(20).text("  red     ");
135        o.at(yy + 4, x0 + 42).hfb(30).text("  magenta ");
136        o.at(yy + 5, x0 + 42).hfb(40).text("  green   ");
137        o.at(yy + 6, x0 + 42).hfb(50).text("  cyan    ");
138        o.at(yy + 7, x0 + 42).hfb(60).text("  yellow  ");
139        o.at(yy + 8, x0 + 42).hfb(70).text("  white   ");
140        o.at(yy + 1, x0 + 54).hfb(100).text("  black   ");
141        o.at(yy + 2, x0 + 54).hfb(110).text("  blue    ");
142        o.at(yy + 3, x0 + 54).hfb(120).text("  red     ");
143        o.at(yy + 4, x0 + 54).hfb(130).text("  magenta ");
144        o.at(yy + 5, x0 + 54).hfb(140).text("  green   ");
145        o.at(yy + 6, x0 + 54).hfb(150).text("  cyan    ");
146        o.at(yy + 7, x0 + 54).hfb(160).text("  yellow  ");
147        o.at(yy + 8, x0 + 54).hfb(170).text("  white   ");
148        o.at(yy + 1, x0 + 66).hfb(70).text("  black   ");
149        o.at(yy + 2, x0 + 66).hfb(71).text("  blue    ");
150        o.at(yy + 3, x0 + 66).hfb(72).text("  red     ");
151        o.at(yy + 4, x0 + 66).hfb(73).text("  magenta ");
152        o.at(yy + 5, x0 + 66).hfb(4).text("  green   ");
153        o.at(yy + 6, x0 + 66).hfb(5).text("  cyan    ");
154        o.at(yy + 7, x0 + 66).hfb(6).text("  yellow  ");
155        o.at(yy + 8, x0 + 66).hfb(7).text("  white   ");
156        o.at(yy + 10, x0 + 40)
157            .hfb(60)
158            .text(" (Expect all 16 colours to be");
159        o.at(yy + 11, x0 + 40)
160            .hfb(60)
161            .text("  visible in all cases.)");
162        let y1b = yy + 12;
163        let end = y1a.max(y1b);
164
165        yy = end + 10;
166        o.at(yy - 1, x0).hfb(99).text("Hue wheel");
167        o.at(yy, x0);
168        if o.features().colour_256 {
169            const RED: [i32; 7] = [255, 255, 0, 0, 0, 255, 255];
170            const GREEN: [i32; 7] = [0, 255, 255, 255, 0, 0, 0];
171            const BLUE: [i32; 7] = [0, 0, 0, 255, 255, 255, 0];
172            for x in 0..78 {
173                let i = x / 13;
174                let off = (x - i * 13) as i32;
175                let r = RED[i] + (RED[i + 1] - RED[i]) * off / 13;
176                let g = GREEN[i] + (GREEN[i + 1] - GREEN[i]) * off / 13;
177                let b = BLUE[i] + (BLUE[i + 1] - BLUE[i]) * off / 13;
178                let rgb = (r << 16) + (g << 8) + b;
179                let hfb = o.hfb_alloc(false, false, 0xFFFFFF, rgb as u32);
180                o.hfb(hfb).spaces(1);
181            }
182        } else {
183            o.hfb(2).spaces(13);
184            o.hfb(6).spaces(13);
185            o.hfb(4).spaces(13);
186            o.hfb(5).spaces(13);
187            o.hfb(1).spaces(13);
188            o.hfb(3).spaces(13);
189        }
190
191        yy = end + 1;
192        let mut xx = x0 + 40;
193
194        o.at(yy, xx).hfb(99).text("ASCII");
195        for a in 0..96 {
196            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
197                .char(char::from_u32((a + 32) as u32).unwrap());
198        }
199
200        xx += 20;
201        o.at(yy, xx).hfb(99).text("Latin-1");
202        for a in 0..96 {
203            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
204                .char(char::from_u32((a + 160) as u32).unwrap());
205        }
206
207        const BOXTITLE1: &str = "\
208Single  Single  Double  Thick";
209        const BOXTITLE2: &str = "\
210+Double +Thick  +Single +Single";
211
212        const BOXTEST: &str = "\
213+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
214| | H | | | $ | H H | H $ $ | $
215+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
216| | H | | | $ | H H | H $ $ | $
217+=+=+=+ +*+*+*+ +-+-+-+ +-+-+-+
218| | H | | | $ | H H | H $ $ | $
219+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+";
220
221        let boxtest = Output::box_from_ascii_art(BOXTEST);
222        yy = end + 1;
223        xx = x0 + 2;
224        o.at(yy - 2, xx).text(BOXTITLE1);
225        o.at(yy - 1, xx).text(BOXTITLE2);
226        for line in boxtest.split('\n') {
227            o.at(yy, xx).text(line);
228            yy += 1;
229        }
230
231        o.flush();
232    }
Source

pub fn bytes(&mut self, data: &[u8]) -> &mut Self

Add a chunk of byte data to the output buffer.

See also the Write implementation, which allows use of write! and writeln! to add data to the buffer.

Source

pub fn char(&mut self, ch: char) -> &mut Self

Add a char to the output buffer as 1-4 bytes of UTF-8

Examples found in repository?
examples/test1.rs (line 133)
108    fn draw(o: &mut Output) {
109        o.clear_all_99();
110        let sx = o.sx();
111        let sy = o.sy();
112        if sy < 24 || sx < 80 {
113            o.hfb(162);
114            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
115            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
116            o.hfb(99);
117            o.flush();
118            return;
119        }
120
121        const TEXT: [char; 17] = [
122            'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', '.', ' ', ' ',
123        ];
124        let mut last_hfb = 99;
125        for y in 0..sy {
126            o.at(y, 0);
127            for x in 0..sx {
128                let hfb = ((x * 8) / sx + (y & 7) * 10 + ((y >> 3) & 1) * 100) as u16;
129                if hfb != last_hfb {
130                    o.hfb(hfb);
131                    last_hfb = hfb;
132                }
133                o.char(TEXT[(1000 + x - y) as usize % TEXT.len()]);
134            }
135        }
136        o.at(sy - 2, (sx - 60) / 2)
137            .hfb(162)
138            .text("[ Type to show decoding, Ctrl-C to exit, Ctrl-L to redraw ]")
139            .hfb(99);
140        o.at(0, 0);
141        o.flush();
142    }
More examples
Hide additional examples
examples/test0.rs (line 197)
86    fn draw(o: &mut Output) {
87        o.clear_all_99();
88        if o.sy() < 24 || o.sx() < 80 {
89            o.hfb(162);
90            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
91            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
92            o.hfb(99);
93            o.flush();
94            return;
95        }
96
97        let x0 = (o.sx() - 80) >> 1;
98        let y0 = (o.sy() - 24) >> 1;
99        let mut yy = y0;
100        let c256 = o.features().colour_256;
101        o.at(yy, x0).hfb(99).text("Colour mode:");
102        o.at(yy, x0 + 15)
103            .hfb(199)
104            .text(if c256 { "256-colour" } else { "8-colour" });
105        yy += 2;
106
107        o.at(yy, x0).hfb(99).text("Attributes:");
108        yy += 1;
109        const TEXT: [&str; 4] = ["White:", "Brown:", "Blue:", "Black:"];
110        const BASE_HFB: [u16; 4] = [70, 60, 10, 3];
111        for i in 0..4 {
112            let hfb = BASE_HFB[i];
113            o.at(yy, x0 + 2).hfb(99).text(TEXT[i]);
114            o.at(yy, x0 + 16).hfb(hfb).text(" norm ");
115            o.at(yy, x0 + 22).hfb(100 + hfb).text("bold ");
116            o.at(yy, x0 + 27).hfb(200 + hfb).text("undl ");
117            o.at(yy, x0 + 32).hfb(300 + hfb).text("both ");
118            yy += 1;
119        }
120        o.at(yy + 1, x0)
121            .hfb(60)
122            .text(" (On 8-colour expect bold/ul to");
123        o.at(yy + 2, x0)
124            .hfb(60)
125            .text("  be emulated as colour changes.)");
126        let y1a = yy + 3;
127
128        yy = y0;
129        o.at(yy, x0 + 40)
130            .hfb(99)
131            .text("Base, bold and background colours:");
132        o.at(yy + 1, x0 + 42).hfb(7).text("  black   ");
133        o.at(yy + 2, x0 + 42).hfb(10).text("  blue    ");
134        o.at(yy + 3, x0 + 42).hfb(20).text("  red     ");
135        o.at(yy + 4, x0 + 42).hfb(30).text("  magenta ");
136        o.at(yy + 5, x0 + 42).hfb(40).text("  green   ");
137        o.at(yy + 6, x0 + 42).hfb(50).text("  cyan    ");
138        o.at(yy + 7, x0 + 42).hfb(60).text("  yellow  ");
139        o.at(yy + 8, x0 + 42).hfb(70).text("  white   ");
140        o.at(yy + 1, x0 + 54).hfb(100).text("  black   ");
141        o.at(yy + 2, x0 + 54).hfb(110).text("  blue    ");
142        o.at(yy + 3, x0 + 54).hfb(120).text("  red     ");
143        o.at(yy + 4, x0 + 54).hfb(130).text("  magenta ");
144        o.at(yy + 5, x0 + 54).hfb(140).text("  green   ");
145        o.at(yy + 6, x0 + 54).hfb(150).text("  cyan    ");
146        o.at(yy + 7, x0 + 54).hfb(160).text("  yellow  ");
147        o.at(yy + 8, x0 + 54).hfb(170).text("  white   ");
148        o.at(yy + 1, x0 + 66).hfb(70).text("  black   ");
149        o.at(yy + 2, x0 + 66).hfb(71).text("  blue    ");
150        o.at(yy + 3, x0 + 66).hfb(72).text("  red     ");
151        o.at(yy + 4, x0 + 66).hfb(73).text("  magenta ");
152        o.at(yy + 5, x0 + 66).hfb(4).text("  green   ");
153        o.at(yy + 6, x0 + 66).hfb(5).text("  cyan    ");
154        o.at(yy + 7, x0 + 66).hfb(6).text("  yellow  ");
155        o.at(yy + 8, x0 + 66).hfb(7).text("  white   ");
156        o.at(yy + 10, x0 + 40)
157            .hfb(60)
158            .text(" (Expect all 16 colours to be");
159        o.at(yy + 11, x0 + 40)
160            .hfb(60)
161            .text("  visible in all cases.)");
162        let y1b = yy + 12;
163        let end = y1a.max(y1b);
164
165        yy = end + 10;
166        o.at(yy - 1, x0).hfb(99).text("Hue wheel");
167        o.at(yy, x0);
168        if o.features().colour_256 {
169            const RED: [i32; 7] = [255, 255, 0, 0, 0, 255, 255];
170            const GREEN: [i32; 7] = [0, 255, 255, 255, 0, 0, 0];
171            const BLUE: [i32; 7] = [0, 0, 0, 255, 255, 255, 0];
172            for x in 0..78 {
173                let i = x / 13;
174                let off = (x - i * 13) as i32;
175                let r = RED[i] + (RED[i + 1] - RED[i]) * off / 13;
176                let g = GREEN[i] + (GREEN[i + 1] - GREEN[i]) * off / 13;
177                let b = BLUE[i] + (BLUE[i + 1] - BLUE[i]) * off / 13;
178                let rgb = (r << 16) + (g << 8) + b;
179                let hfb = o.hfb_alloc(false, false, 0xFFFFFF, rgb as u32);
180                o.hfb(hfb).spaces(1);
181            }
182        } else {
183            o.hfb(2).spaces(13);
184            o.hfb(6).spaces(13);
185            o.hfb(4).spaces(13);
186            o.hfb(5).spaces(13);
187            o.hfb(1).spaces(13);
188            o.hfb(3).spaces(13);
189        }
190
191        yy = end + 1;
192        let mut xx = x0 + 40;
193
194        o.at(yy, xx).hfb(99).text("ASCII");
195        for a in 0..96 {
196            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
197                .char(char::from_u32((a + 32) as u32).unwrap());
198        }
199
200        xx += 20;
201        o.at(yy, xx).hfb(99).text("Latin-1");
202        for a in 0..96 {
203            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
204                .char(char::from_u32((a + 160) as u32).unwrap());
205        }
206
207        const BOXTITLE1: &str = "\
208Single  Single  Double  Thick";
209        const BOXTITLE2: &str = "\
210+Double +Thick  +Single +Single";
211
212        const BOXTEST: &str = "\
213+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
214| | H | | | $ | H H | H $ $ | $
215+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
216| | H | | | $ | H H | H $ $ | $
217+=+=+=+ +*+*+*+ +-+-+-+ +-+-+-+
218| | H | | | $ | H H | H $ $ | $
219+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+";
220
221        let boxtest = Output::box_from_ascii_art(BOXTEST);
222        yy = end + 1;
223        xx = x0 + 2;
224        o.at(yy - 2, xx).text(BOXTITLE1);
225        o.at(yy - 1, xx).text(BOXTITLE2);
226        for line in boxtest.split('\n') {
227            o.at(yy, xx).text(line);
228            yy += 1;
229        }
230
231        o.flush();
232    }
Source

pub fn byt(&mut self, v1: u8) -> &mut Self

Add a single byte to the output buffer.

Source

pub fn asc(&mut self, c: char) -> &mut Self

Add a single ASCII byte to the output buffer.

Source

pub fn spaces(&mut self, n: i32) -> &mut Self

Add N spaces. The spaces are written with the current colour-pair. This is the only portable way to write areas of coloured empty cells.

Examples found in repository?
examples/test0.rs (line 180)
86    fn draw(o: &mut Output) {
87        o.clear_all_99();
88        if o.sy() < 24 || o.sx() < 80 {
89            o.hfb(162);
90            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
91            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
92            o.hfb(99);
93            o.flush();
94            return;
95        }
96
97        let x0 = (o.sx() - 80) >> 1;
98        let y0 = (o.sy() - 24) >> 1;
99        let mut yy = y0;
100        let c256 = o.features().colour_256;
101        o.at(yy, x0).hfb(99).text("Colour mode:");
102        o.at(yy, x0 + 15)
103            .hfb(199)
104            .text(if c256 { "256-colour" } else { "8-colour" });
105        yy += 2;
106
107        o.at(yy, x0).hfb(99).text("Attributes:");
108        yy += 1;
109        const TEXT: [&str; 4] = ["White:", "Brown:", "Blue:", "Black:"];
110        const BASE_HFB: [u16; 4] = [70, 60, 10, 3];
111        for i in 0..4 {
112            let hfb = BASE_HFB[i];
113            o.at(yy, x0 + 2).hfb(99).text(TEXT[i]);
114            o.at(yy, x0 + 16).hfb(hfb).text(" norm ");
115            o.at(yy, x0 + 22).hfb(100 + hfb).text("bold ");
116            o.at(yy, x0 + 27).hfb(200 + hfb).text("undl ");
117            o.at(yy, x0 + 32).hfb(300 + hfb).text("both ");
118            yy += 1;
119        }
120        o.at(yy + 1, x0)
121            .hfb(60)
122            .text(" (On 8-colour expect bold/ul to");
123        o.at(yy + 2, x0)
124            .hfb(60)
125            .text("  be emulated as colour changes.)");
126        let y1a = yy + 3;
127
128        yy = y0;
129        o.at(yy, x0 + 40)
130            .hfb(99)
131            .text("Base, bold and background colours:");
132        o.at(yy + 1, x0 + 42).hfb(7).text("  black   ");
133        o.at(yy + 2, x0 + 42).hfb(10).text("  blue    ");
134        o.at(yy + 3, x0 + 42).hfb(20).text("  red     ");
135        o.at(yy + 4, x0 + 42).hfb(30).text("  magenta ");
136        o.at(yy + 5, x0 + 42).hfb(40).text("  green   ");
137        o.at(yy + 6, x0 + 42).hfb(50).text("  cyan    ");
138        o.at(yy + 7, x0 + 42).hfb(60).text("  yellow  ");
139        o.at(yy + 8, x0 + 42).hfb(70).text("  white   ");
140        o.at(yy + 1, x0 + 54).hfb(100).text("  black   ");
141        o.at(yy + 2, x0 + 54).hfb(110).text("  blue    ");
142        o.at(yy + 3, x0 + 54).hfb(120).text("  red     ");
143        o.at(yy + 4, x0 + 54).hfb(130).text("  magenta ");
144        o.at(yy + 5, x0 + 54).hfb(140).text("  green   ");
145        o.at(yy + 6, x0 + 54).hfb(150).text("  cyan    ");
146        o.at(yy + 7, x0 + 54).hfb(160).text("  yellow  ");
147        o.at(yy + 8, x0 + 54).hfb(170).text("  white   ");
148        o.at(yy + 1, x0 + 66).hfb(70).text("  black   ");
149        o.at(yy + 2, x0 + 66).hfb(71).text("  blue    ");
150        o.at(yy + 3, x0 + 66).hfb(72).text("  red     ");
151        o.at(yy + 4, x0 + 66).hfb(73).text("  magenta ");
152        o.at(yy + 5, x0 + 66).hfb(4).text("  green   ");
153        o.at(yy + 6, x0 + 66).hfb(5).text("  cyan    ");
154        o.at(yy + 7, x0 + 66).hfb(6).text("  yellow  ");
155        o.at(yy + 8, x0 + 66).hfb(7).text("  white   ");
156        o.at(yy + 10, x0 + 40)
157            .hfb(60)
158            .text(" (Expect all 16 colours to be");
159        o.at(yy + 11, x0 + 40)
160            .hfb(60)
161            .text("  visible in all cases.)");
162        let y1b = yy + 12;
163        let end = y1a.max(y1b);
164
165        yy = end + 10;
166        o.at(yy - 1, x0).hfb(99).text("Hue wheel");
167        o.at(yy, x0);
168        if o.features().colour_256 {
169            const RED: [i32; 7] = [255, 255, 0, 0, 0, 255, 255];
170            const GREEN: [i32; 7] = [0, 255, 255, 255, 0, 0, 0];
171            const BLUE: [i32; 7] = [0, 0, 0, 255, 255, 255, 0];
172            for x in 0..78 {
173                let i = x / 13;
174                let off = (x - i * 13) as i32;
175                let r = RED[i] + (RED[i + 1] - RED[i]) * off / 13;
176                let g = GREEN[i] + (GREEN[i + 1] - GREEN[i]) * off / 13;
177                let b = BLUE[i] + (BLUE[i + 1] - BLUE[i]) * off / 13;
178                let rgb = (r << 16) + (g << 8) + b;
179                let hfb = o.hfb_alloc(false, false, 0xFFFFFF, rgb as u32);
180                o.hfb(hfb).spaces(1);
181            }
182        } else {
183            o.hfb(2).spaces(13);
184            o.hfb(6).spaces(13);
185            o.hfb(4).spaces(13);
186            o.hfb(5).spaces(13);
187            o.hfb(1).spaces(13);
188            o.hfb(3).spaces(13);
189        }
190
191        yy = end + 1;
192        let mut xx = x0 + 40;
193
194        o.at(yy, xx).hfb(99).text("ASCII");
195        for a in 0..96 {
196            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
197                .char(char::from_u32((a + 32) as u32).unwrap());
198        }
199
200        xx += 20;
201        o.at(yy, xx).hfb(99).text("Latin-1");
202        for a in 0..96 {
203            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
204                .char(char::from_u32((a + 160) as u32).unwrap());
205        }
206
207        const BOXTITLE1: &str = "\
208Single  Single  Double  Thick";
209        const BOXTITLE2: &str = "\
210+Double +Thick  +Single +Single";
211
212        const BOXTEST: &str = "\
213+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
214| | H | | | $ | H H | H $ $ | $
215+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
216| | H | | | $ | H H | H $ $ | $
217+=+=+=+ +*+*+*+ +-+-+-+ +-+-+-+
218| | H | | | $ | H H | H $ $ | $
219+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+";
220
221        let boxtest = Output::box_from_ascii_art(BOXTEST);
222        yy = end + 1;
223        xx = x0 + 2;
224        o.at(yy - 2, xx).text(BOXTITLE1);
225        o.at(yy - 1, xx).text(BOXTITLE2);
226        for line in boxtest.split('\n') {
227            o.at(yy, xx).text(line);
228            yy += 1;
229        }
230
231        o.flush();
232    }
Source

pub fn esc(&mut self, c: char) -> &mut Self

Add an ESC byte (27) + ASCII byte to the output buffer.

Source

pub fn csi(&mut self) -> &mut Self

Add ESC [, which is the CSI sequence

Source

pub fn repl_char(&mut self) -> &mut Self

Add the unicode replacement character U+FFFD

Source

pub fn num(&mut self, v: i32) -> &mut Self

Add a 1-3 digit decimal number (0..=999) to the output buffer, as used in control sequences. If number is out of range, then nearest valid number is used.

Source

pub fn origin(&mut self) -> &mut Self

Add ANSI sequence to move to origin (top-left)

Source

pub fn at(&mut self, y: i32, x: i32) -> &mut Self

Add ANSI sequence to move cursor to the given coordinates. Note that coordinates are row-first, with (0,0) as top-left. Coordinates are taken modulo the screen dimensions, so for example -1,-1 is bottom-right, and (0, -10) is 10 from the right on the top line.

Examples found in repository?
examples/test1.rs (line 114)
108    fn draw(o: &mut Output) {
109        o.clear_all_99();
110        let sx = o.sx();
111        let sy = o.sy();
112        if sy < 24 || sx < 80 {
113            o.hfb(162);
114            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
115            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
116            o.hfb(99);
117            o.flush();
118            return;
119        }
120
121        const TEXT: [char; 17] = [
122            'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', '.', ' ', ' ',
123        ];
124        let mut last_hfb = 99;
125        for y in 0..sy {
126            o.at(y, 0);
127            for x in 0..sx {
128                let hfb = ((x * 8) / sx + (y & 7) * 10 + ((y >> 3) & 1) * 100) as u16;
129                if hfb != last_hfb {
130                    o.hfb(hfb);
131                    last_hfb = hfb;
132                }
133                o.char(TEXT[(1000 + x - y) as usize % TEXT.len()]);
134            }
135        }
136        o.at(sy - 2, (sx - 60) / 2)
137            .hfb(162)
138            .text("[ Type to show decoding, Ctrl-C to exit, Ctrl-L to redraw ]")
139            .hfb(99);
140        o.at(0, 0);
141        o.flush();
142    }
More examples
Hide additional examples
examples/test0.rs (line 90)
86    fn draw(o: &mut Output) {
87        o.clear_all_99();
88        if o.sy() < 24 || o.sx() < 80 {
89            o.hfb(162);
90            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
91            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
92            o.hfb(99);
93            o.flush();
94            return;
95        }
96
97        let x0 = (o.sx() - 80) >> 1;
98        let y0 = (o.sy() - 24) >> 1;
99        let mut yy = y0;
100        let c256 = o.features().colour_256;
101        o.at(yy, x0).hfb(99).text("Colour mode:");
102        o.at(yy, x0 + 15)
103            .hfb(199)
104            .text(if c256 { "256-colour" } else { "8-colour" });
105        yy += 2;
106
107        o.at(yy, x0).hfb(99).text("Attributes:");
108        yy += 1;
109        const TEXT: [&str; 4] = ["White:", "Brown:", "Blue:", "Black:"];
110        const BASE_HFB: [u16; 4] = [70, 60, 10, 3];
111        for i in 0..4 {
112            let hfb = BASE_HFB[i];
113            o.at(yy, x0 + 2).hfb(99).text(TEXT[i]);
114            o.at(yy, x0 + 16).hfb(hfb).text(" norm ");
115            o.at(yy, x0 + 22).hfb(100 + hfb).text("bold ");
116            o.at(yy, x0 + 27).hfb(200 + hfb).text("undl ");
117            o.at(yy, x0 + 32).hfb(300 + hfb).text("both ");
118            yy += 1;
119        }
120        o.at(yy + 1, x0)
121            .hfb(60)
122            .text(" (On 8-colour expect bold/ul to");
123        o.at(yy + 2, x0)
124            .hfb(60)
125            .text("  be emulated as colour changes.)");
126        let y1a = yy + 3;
127
128        yy = y0;
129        o.at(yy, x0 + 40)
130            .hfb(99)
131            .text("Base, bold and background colours:");
132        o.at(yy + 1, x0 + 42).hfb(7).text("  black   ");
133        o.at(yy + 2, x0 + 42).hfb(10).text("  blue    ");
134        o.at(yy + 3, x0 + 42).hfb(20).text("  red     ");
135        o.at(yy + 4, x0 + 42).hfb(30).text("  magenta ");
136        o.at(yy + 5, x0 + 42).hfb(40).text("  green   ");
137        o.at(yy + 6, x0 + 42).hfb(50).text("  cyan    ");
138        o.at(yy + 7, x0 + 42).hfb(60).text("  yellow  ");
139        o.at(yy + 8, x0 + 42).hfb(70).text("  white   ");
140        o.at(yy + 1, x0 + 54).hfb(100).text("  black   ");
141        o.at(yy + 2, x0 + 54).hfb(110).text("  blue    ");
142        o.at(yy + 3, x0 + 54).hfb(120).text("  red     ");
143        o.at(yy + 4, x0 + 54).hfb(130).text("  magenta ");
144        o.at(yy + 5, x0 + 54).hfb(140).text("  green   ");
145        o.at(yy + 6, x0 + 54).hfb(150).text("  cyan    ");
146        o.at(yy + 7, x0 + 54).hfb(160).text("  yellow  ");
147        o.at(yy + 8, x0 + 54).hfb(170).text("  white   ");
148        o.at(yy + 1, x0 + 66).hfb(70).text("  black   ");
149        o.at(yy + 2, x0 + 66).hfb(71).text("  blue    ");
150        o.at(yy + 3, x0 + 66).hfb(72).text("  red     ");
151        o.at(yy + 4, x0 + 66).hfb(73).text("  magenta ");
152        o.at(yy + 5, x0 + 66).hfb(4).text("  green   ");
153        o.at(yy + 6, x0 + 66).hfb(5).text("  cyan    ");
154        o.at(yy + 7, x0 + 66).hfb(6).text("  yellow  ");
155        o.at(yy + 8, x0 + 66).hfb(7).text("  white   ");
156        o.at(yy + 10, x0 + 40)
157            .hfb(60)
158            .text(" (Expect all 16 colours to be");
159        o.at(yy + 11, x0 + 40)
160            .hfb(60)
161            .text("  visible in all cases.)");
162        let y1b = yy + 12;
163        let end = y1a.max(y1b);
164
165        yy = end + 10;
166        o.at(yy - 1, x0).hfb(99).text("Hue wheel");
167        o.at(yy, x0);
168        if o.features().colour_256 {
169            const RED: [i32; 7] = [255, 255, 0, 0, 0, 255, 255];
170            const GREEN: [i32; 7] = [0, 255, 255, 255, 0, 0, 0];
171            const BLUE: [i32; 7] = [0, 0, 0, 255, 255, 255, 0];
172            for x in 0..78 {
173                let i = x / 13;
174                let off = (x - i * 13) as i32;
175                let r = RED[i] + (RED[i + 1] - RED[i]) * off / 13;
176                let g = GREEN[i] + (GREEN[i + 1] - GREEN[i]) * off / 13;
177                let b = BLUE[i] + (BLUE[i + 1] - BLUE[i]) * off / 13;
178                let rgb = (r << 16) + (g << 8) + b;
179                let hfb = o.hfb_alloc(false, false, 0xFFFFFF, rgb as u32);
180                o.hfb(hfb).spaces(1);
181            }
182        } else {
183            o.hfb(2).spaces(13);
184            o.hfb(6).spaces(13);
185            o.hfb(4).spaces(13);
186            o.hfb(5).spaces(13);
187            o.hfb(1).spaces(13);
188            o.hfb(3).spaces(13);
189        }
190
191        yy = end + 1;
192        let mut xx = x0 + 40;
193
194        o.at(yy, xx).hfb(99).text("ASCII");
195        for a in 0..96 {
196            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
197                .char(char::from_u32((a + 32) as u32).unwrap());
198        }
199
200        xx += 20;
201        o.at(yy, xx).hfb(99).text("Latin-1");
202        for a in 0..96 {
203            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
204                .char(char::from_u32((a + 160) as u32).unwrap());
205        }
206
207        const BOXTITLE1: &str = "\
208Single  Single  Double  Thick";
209        const BOXTITLE2: &str = "\
210+Double +Thick  +Single +Single";
211
212        const BOXTEST: &str = "\
213+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
214| | H | | | $ | H H | H $ $ | $
215+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
216| | H | | | $ | H H | H $ $ | $
217+=+=+=+ +*+*+*+ +-+-+-+ +-+-+-+
218| | H | | | $ | H H | H $ $ | $
219+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+";
220
221        let boxtest = Output::box_from_ascii_art(BOXTEST);
222        yy = end + 1;
223        xx = x0 + 2;
224        o.at(yy - 2, xx).text(BOXTITLE1);
225        o.at(yy - 1, xx).text(BOXTITLE2);
226        for line in boxtest.split('\n') {
227            o.at(yy, xx).text(line);
228            yy += 1;
229        }
230
231        o.flush();
232    }
Source

pub fn skip(&mut self, n: i32) -> &mut Self

Add ANSI sequence to skip the cursor forwards (rightwards) N cells, without overwriting them.

Source

pub fn newline(&mut self) -> &mut Self

Move cursor to the start of the next row. Note that writing a full line leaves the write position just past the end of the line, but not on the next line, so calling this method correctly moves to the next line in that case.

Source

pub fn attr(&mut self, codes: &str) -> &mut Self

Add an attribute string. The codes passed should be the semicolon-separated list of numeric codes, for example “1;31;46”.

Source

pub fn hfb(&mut self, hfb: u16) -> &mut Self

Add an attribute string to provide the given HFB attribute-set expressed as 3 decimal digits HFB, or 2 decimal digits FB, or for 256-colours as a value returned by Output::hfb_alloc. This is intended for compact representation of combinations of the basic 8 colours and bold and/or underline.

H is highlight, used to control bold/underline: 0 normal, 1 bold, 2 underline, 3 bold+underline. F and B are foreground and background in colour-intensity order, 0-9: 0 black, 1 blue, 2 red, 3 magenta, 4 green, 5 cyan, 6 yellow, 7 white, 9 default. Note that this means that 99 gives the default colour combination, i.e. white on black on a black terminal, or black on white on a white terminal.

Examples found in repository?
examples/test1.rs (line 100)
78    fn input(&mut self, cx: CX![], key: Key) {
79        match key {
80            Key::Ctrl('L') => self.redraw(cx),
81            Key::Ctrl('C') => stop!(cx),
82            _ => {
83                use std::str::FromStr;
84                let s = format!("{key}");
85                let k = Key::from_str(&s);
86                assert!(k.is_ok(), "Round-trip failed for {s}");
87                let k = k.unwrap();
88                assert_eq!(k, key, "Mismatch for {key} -> {s} -> {k}");
89                let hfb = if s.starts_with("M-") {
90                    172
91                } else if s.starts_with("C-") {
92                    141
93                } else if matches!(key, Key::Pr(_)) {
94                    151
95                } else {
96                    162
97                };
98                if let Some(ref tshare) = self.tshare {
99                    let o = tshare.output(cx);
100                    o.hfb(hfb).text(&s);
101                    o.hfb(71).text(" ");
102                    o.flush();
103                }
104            }
105        }
106    }
107
108    fn draw(o: &mut Output) {
109        o.clear_all_99();
110        let sx = o.sx();
111        let sy = o.sy();
112        if sy < 24 || sx < 80 {
113            o.hfb(162);
114            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
115            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
116            o.hfb(99);
117            o.flush();
118            return;
119        }
120
121        const TEXT: [char; 17] = [
122            'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', '.', ' ', ' ',
123        ];
124        let mut last_hfb = 99;
125        for y in 0..sy {
126            o.at(y, 0);
127            for x in 0..sx {
128                let hfb = ((x * 8) / sx + (y & 7) * 10 + ((y >> 3) & 1) * 100) as u16;
129                if hfb != last_hfb {
130                    o.hfb(hfb);
131                    last_hfb = hfb;
132                }
133                o.char(TEXT[(1000 + x - y) as usize % TEXT.len()]);
134            }
135        }
136        o.at(sy - 2, (sx - 60) / 2)
137            .hfb(162)
138            .text("[ Type to show decoding, Ctrl-C to exit, Ctrl-L to redraw ]")
139            .hfb(99);
140        o.at(0, 0);
141        o.flush();
142    }
More examples
Hide additional examples
examples/test0.rs (line 89)
86    fn draw(o: &mut Output) {
87        o.clear_all_99();
88        if o.sy() < 24 || o.sx() < 80 {
89            o.hfb(162);
90            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
91            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
92            o.hfb(99);
93            o.flush();
94            return;
95        }
96
97        let x0 = (o.sx() - 80) >> 1;
98        let y0 = (o.sy() - 24) >> 1;
99        let mut yy = y0;
100        let c256 = o.features().colour_256;
101        o.at(yy, x0).hfb(99).text("Colour mode:");
102        o.at(yy, x0 + 15)
103            .hfb(199)
104            .text(if c256 { "256-colour" } else { "8-colour" });
105        yy += 2;
106
107        o.at(yy, x0).hfb(99).text("Attributes:");
108        yy += 1;
109        const TEXT: [&str; 4] = ["White:", "Brown:", "Blue:", "Black:"];
110        const BASE_HFB: [u16; 4] = [70, 60, 10, 3];
111        for i in 0..4 {
112            let hfb = BASE_HFB[i];
113            o.at(yy, x0 + 2).hfb(99).text(TEXT[i]);
114            o.at(yy, x0 + 16).hfb(hfb).text(" norm ");
115            o.at(yy, x0 + 22).hfb(100 + hfb).text("bold ");
116            o.at(yy, x0 + 27).hfb(200 + hfb).text("undl ");
117            o.at(yy, x0 + 32).hfb(300 + hfb).text("both ");
118            yy += 1;
119        }
120        o.at(yy + 1, x0)
121            .hfb(60)
122            .text(" (On 8-colour expect bold/ul to");
123        o.at(yy + 2, x0)
124            .hfb(60)
125            .text("  be emulated as colour changes.)");
126        let y1a = yy + 3;
127
128        yy = y0;
129        o.at(yy, x0 + 40)
130            .hfb(99)
131            .text("Base, bold and background colours:");
132        o.at(yy + 1, x0 + 42).hfb(7).text("  black   ");
133        o.at(yy + 2, x0 + 42).hfb(10).text("  blue    ");
134        o.at(yy + 3, x0 + 42).hfb(20).text("  red     ");
135        o.at(yy + 4, x0 + 42).hfb(30).text("  magenta ");
136        o.at(yy + 5, x0 + 42).hfb(40).text("  green   ");
137        o.at(yy + 6, x0 + 42).hfb(50).text("  cyan    ");
138        o.at(yy + 7, x0 + 42).hfb(60).text("  yellow  ");
139        o.at(yy + 8, x0 + 42).hfb(70).text("  white   ");
140        o.at(yy + 1, x0 + 54).hfb(100).text("  black   ");
141        o.at(yy + 2, x0 + 54).hfb(110).text("  blue    ");
142        o.at(yy + 3, x0 + 54).hfb(120).text("  red     ");
143        o.at(yy + 4, x0 + 54).hfb(130).text("  magenta ");
144        o.at(yy + 5, x0 + 54).hfb(140).text("  green   ");
145        o.at(yy + 6, x0 + 54).hfb(150).text("  cyan    ");
146        o.at(yy + 7, x0 + 54).hfb(160).text("  yellow  ");
147        o.at(yy + 8, x0 + 54).hfb(170).text("  white   ");
148        o.at(yy + 1, x0 + 66).hfb(70).text("  black   ");
149        o.at(yy + 2, x0 + 66).hfb(71).text("  blue    ");
150        o.at(yy + 3, x0 + 66).hfb(72).text("  red     ");
151        o.at(yy + 4, x0 + 66).hfb(73).text("  magenta ");
152        o.at(yy + 5, x0 + 66).hfb(4).text("  green   ");
153        o.at(yy + 6, x0 + 66).hfb(5).text("  cyan    ");
154        o.at(yy + 7, x0 + 66).hfb(6).text("  yellow  ");
155        o.at(yy + 8, x0 + 66).hfb(7).text("  white   ");
156        o.at(yy + 10, x0 + 40)
157            .hfb(60)
158            .text(" (Expect all 16 colours to be");
159        o.at(yy + 11, x0 + 40)
160            .hfb(60)
161            .text("  visible in all cases.)");
162        let y1b = yy + 12;
163        let end = y1a.max(y1b);
164
165        yy = end + 10;
166        o.at(yy - 1, x0).hfb(99).text("Hue wheel");
167        o.at(yy, x0);
168        if o.features().colour_256 {
169            const RED: [i32; 7] = [255, 255, 0, 0, 0, 255, 255];
170            const GREEN: [i32; 7] = [0, 255, 255, 255, 0, 0, 0];
171            const BLUE: [i32; 7] = [0, 0, 0, 255, 255, 255, 0];
172            for x in 0..78 {
173                let i = x / 13;
174                let off = (x - i * 13) as i32;
175                let r = RED[i] + (RED[i + 1] - RED[i]) * off / 13;
176                let g = GREEN[i] + (GREEN[i + 1] - GREEN[i]) * off / 13;
177                let b = BLUE[i] + (BLUE[i + 1] - BLUE[i]) * off / 13;
178                let rgb = (r << 16) + (g << 8) + b;
179                let hfb = o.hfb_alloc(false, false, 0xFFFFFF, rgb as u32);
180                o.hfb(hfb).spaces(1);
181            }
182        } else {
183            o.hfb(2).spaces(13);
184            o.hfb(6).spaces(13);
185            o.hfb(4).spaces(13);
186            o.hfb(5).spaces(13);
187            o.hfb(1).spaces(13);
188            o.hfb(3).spaces(13);
189        }
190
191        yy = end + 1;
192        let mut xx = x0 + 40;
193
194        o.at(yy, xx).hfb(99).text("ASCII");
195        for a in 0..96 {
196            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
197                .char(char::from_u32((a + 32) as u32).unwrap());
198        }
199
200        xx += 20;
201        o.at(yy, xx).hfb(99).text("Latin-1");
202        for a in 0..96 {
203            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
204                .char(char::from_u32((a + 160) as u32).unwrap());
205        }
206
207        const BOXTITLE1: &str = "\
208Single  Single  Double  Thick";
209        const BOXTITLE2: &str = "\
210+Double +Thick  +Single +Single";
211
212        const BOXTEST: &str = "\
213+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
214| | H | | | $ | H H | H $ $ | $
215+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
216| | H | | | $ | H H | H $ $ | $
217+=+=+=+ +*+*+*+ +-+-+-+ +-+-+-+
218| | H | | | $ | H H | H $ $ | $
219+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+";
220
221        let boxtest = Output::box_from_ascii_art(BOXTEST);
222        yy = end + 1;
223        xx = x0 + 2;
224        o.at(yy - 2, xx).text(BOXTITLE1);
225        o.at(yy - 1, xx).text(BOXTITLE2);
226        for line in boxtest.split('\n') {
227            o.at(yy, xx).text(line);
228            yy += 1;
229        }
230
231        o.flush();
232    }
Source

pub fn clear_all_99(&mut self) -> &mut Self

Add ANSI sequence to clear the whole display. This clears with the terminal’s default colour-pair (99), and leaves the current colours set to the default, and cursor at top-left.

Examples found in repository?
examples/teeclub/main.rs (line 95)
89    fn resize(&mut self, cx: CX![], tsh: Option<TermShare>) {
90        self.tsh = tsh;
91
92        if let Some(ref tsh) = self.tsh {
93            let out = tsh.output(cx);
94            out.attr_99().cursor_show().scroll_up().save_cleanup();
95            out.cursor_hide().clear_all_99();
96
97            if self.logo_hfb.is_none() && out.features().colour_256 {
98                const LOGO_RGB: [(f64, u32); 7] = [
99                    (0.0, 0xFFFF00),
100                    (1.0, 0x00FF00),
101                    (2.0, 0x22FFFF),
102                    (3.0, 0x4444FF),
103                    (4.0, 0xFF22FF),
104                    (5.0, 0xFF0000),
105                    (6.0, 0xFFFF00),
106                ];
107                self.logo_hfb = Some(
108                    (0..30)
109                        .map(|i| {
110                            let rgb = out.rgb_interpolate(&LOGO_RGB, i as f64 * 0.2);
111                            out.hfb_alloc(false, false, rgb, 0x000000)
112                        })
113                        .collect(),
114                );
115            }
116
117            self.layout(cx);
118        }
119    }
More examples
Hide additional examples
examples/test1.rs (line 109)
108    fn draw(o: &mut Output) {
109        o.clear_all_99();
110        let sx = o.sx();
111        let sy = o.sy();
112        if sy < 24 || sx < 80 {
113            o.hfb(162);
114            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
115            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
116            o.hfb(99);
117            o.flush();
118            return;
119        }
120
121        const TEXT: [char; 17] = [
122            'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', '.', ' ', ' ',
123        ];
124        let mut last_hfb = 99;
125        for y in 0..sy {
126            o.at(y, 0);
127            for x in 0..sx {
128                let hfb = ((x * 8) / sx + (y & 7) * 10 + ((y >> 3) & 1) * 100) as u16;
129                if hfb != last_hfb {
130                    o.hfb(hfb);
131                    last_hfb = hfb;
132                }
133                o.char(TEXT[(1000 + x - y) as usize % TEXT.len()]);
134            }
135        }
136        o.at(sy - 2, (sx - 60) / 2)
137            .hfb(162)
138            .text("[ Type to show decoding, Ctrl-C to exit, Ctrl-L to redraw ]")
139            .hfb(99);
140        o.at(0, 0);
141        o.flush();
142    }
examples/test0.rs (line 87)
86    fn draw(o: &mut Output) {
87        o.clear_all_99();
88        if o.sy() < 24 || o.sx() < 80 {
89            o.hfb(162);
90            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
91            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
92            o.hfb(99);
93            o.flush();
94            return;
95        }
96
97        let x0 = (o.sx() - 80) >> 1;
98        let y0 = (o.sy() - 24) >> 1;
99        let mut yy = y0;
100        let c256 = o.features().colour_256;
101        o.at(yy, x0).hfb(99).text("Colour mode:");
102        o.at(yy, x0 + 15)
103            .hfb(199)
104            .text(if c256 { "256-colour" } else { "8-colour" });
105        yy += 2;
106
107        o.at(yy, x0).hfb(99).text("Attributes:");
108        yy += 1;
109        const TEXT: [&str; 4] = ["White:", "Brown:", "Blue:", "Black:"];
110        const BASE_HFB: [u16; 4] = [70, 60, 10, 3];
111        for i in 0..4 {
112            let hfb = BASE_HFB[i];
113            o.at(yy, x0 + 2).hfb(99).text(TEXT[i]);
114            o.at(yy, x0 + 16).hfb(hfb).text(" norm ");
115            o.at(yy, x0 + 22).hfb(100 + hfb).text("bold ");
116            o.at(yy, x0 + 27).hfb(200 + hfb).text("undl ");
117            o.at(yy, x0 + 32).hfb(300 + hfb).text("both ");
118            yy += 1;
119        }
120        o.at(yy + 1, x0)
121            .hfb(60)
122            .text(" (On 8-colour expect bold/ul to");
123        o.at(yy + 2, x0)
124            .hfb(60)
125            .text("  be emulated as colour changes.)");
126        let y1a = yy + 3;
127
128        yy = y0;
129        o.at(yy, x0 + 40)
130            .hfb(99)
131            .text("Base, bold and background colours:");
132        o.at(yy + 1, x0 + 42).hfb(7).text("  black   ");
133        o.at(yy + 2, x0 + 42).hfb(10).text("  blue    ");
134        o.at(yy + 3, x0 + 42).hfb(20).text("  red     ");
135        o.at(yy + 4, x0 + 42).hfb(30).text("  magenta ");
136        o.at(yy + 5, x0 + 42).hfb(40).text("  green   ");
137        o.at(yy + 6, x0 + 42).hfb(50).text("  cyan    ");
138        o.at(yy + 7, x0 + 42).hfb(60).text("  yellow  ");
139        o.at(yy + 8, x0 + 42).hfb(70).text("  white   ");
140        o.at(yy + 1, x0 + 54).hfb(100).text("  black   ");
141        o.at(yy + 2, x0 + 54).hfb(110).text("  blue    ");
142        o.at(yy + 3, x0 + 54).hfb(120).text("  red     ");
143        o.at(yy + 4, x0 + 54).hfb(130).text("  magenta ");
144        o.at(yy + 5, x0 + 54).hfb(140).text("  green   ");
145        o.at(yy + 6, x0 + 54).hfb(150).text("  cyan    ");
146        o.at(yy + 7, x0 + 54).hfb(160).text("  yellow  ");
147        o.at(yy + 8, x0 + 54).hfb(170).text("  white   ");
148        o.at(yy + 1, x0 + 66).hfb(70).text("  black   ");
149        o.at(yy + 2, x0 + 66).hfb(71).text("  blue    ");
150        o.at(yy + 3, x0 + 66).hfb(72).text("  red     ");
151        o.at(yy + 4, x0 + 66).hfb(73).text("  magenta ");
152        o.at(yy + 5, x0 + 66).hfb(4).text("  green   ");
153        o.at(yy + 6, x0 + 66).hfb(5).text("  cyan    ");
154        o.at(yy + 7, x0 + 66).hfb(6).text("  yellow  ");
155        o.at(yy + 8, x0 + 66).hfb(7).text("  white   ");
156        o.at(yy + 10, x0 + 40)
157            .hfb(60)
158            .text(" (Expect all 16 colours to be");
159        o.at(yy + 11, x0 + 40)
160            .hfb(60)
161            .text("  visible in all cases.)");
162        let y1b = yy + 12;
163        let end = y1a.max(y1b);
164
165        yy = end + 10;
166        o.at(yy - 1, x0).hfb(99).text("Hue wheel");
167        o.at(yy, x0);
168        if o.features().colour_256 {
169            const RED: [i32; 7] = [255, 255, 0, 0, 0, 255, 255];
170            const GREEN: [i32; 7] = [0, 255, 255, 255, 0, 0, 0];
171            const BLUE: [i32; 7] = [0, 0, 0, 255, 255, 255, 0];
172            for x in 0..78 {
173                let i = x / 13;
174                let off = (x - i * 13) as i32;
175                let r = RED[i] + (RED[i + 1] - RED[i]) * off / 13;
176                let g = GREEN[i] + (GREEN[i + 1] - GREEN[i]) * off / 13;
177                let b = BLUE[i] + (BLUE[i + 1] - BLUE[i]) * off / 13;
178                let rgb = (r << 16) + (g << 8) + b;
179                let hfb = o.hfb_alloc(false, false, 0xFFFFFF, rgb as u32);
180                o.hfb(hfb).spaces(1);
181            }
182        } else {
183            o.hfb(2).spaces(13);
184            o.hfb(6).spaces(13);
185            o.hfb(4).spaces(13);
186            o.hfb(5).spaces(13);
187            o.hfb(1).spaces(13);
188            o.hfb(3).spaces(13);
189        }
190
191        yy = end + 1;
192        let mut xx = x0 + 40;
193
194        o.at(yy, xx).hfb(99).text("ASCII");
195        for a in 0..96 {
196            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
197                .char(char::from_u32((a + 32) as u32).unwrap());
198        }
199
200        xx += 20;
201        o.at(yy, xx).hfb(99).text("Latin-1");
202        for a in 0..96 {
203            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
204                .char(char::from_u32((a + 160) as u32).unwrap());
205        }
206
207        const BOXTITLE1: &str = "\
208Single  Single  Double  Thick";
209        const BOXTITLE2: &str = "\
210+Double +Thick  +Single +Single";
211
212        const BOXTEST: &str = "\
213+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
214| | H | | | $ | H H | H $ $ | $
215+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
216| | H | | | $ | H H | H $ $ | $
217+=+=+=+ +*+*+*+ +-+-+-+ +-+-+-+
218| | H | | | $ | H H | H $ $ | $
219+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+";
220
221        let boxtest = Output::box_from_ascii_art(BOXTEST);
222        yy = end + 1;
223        xx = x0 + 2;
224        o.at(yy - 2, xx).text(BOXTITLE1);
225        o.at(yy - 1, xx).text(BOXTITLE2);
226        for line in boxtest.split('\n') {
227            o.at(yy, xx).text(line);
228            yy += 1;
229        }
230
231        o.flush();
232    }
Source

pub fn clear_all_99_and_remote(&mut self) -> &mut Self

Add ANSI sequence to clear the whole display. This clears with the terminal’s default colour-pair (99), and leaves the current colours set to the default, and cursor at top-left.

This also clears the internal idea of what the remote page looks like for the update and tile mechanism, so that updates operate correctly. This would typically be called on a resize.

Examples found in repository?
examples/fontedit/app.rs (line 89)
85    fn redraw(&mut self, cx: CX![]) {
86        if let Some(ref tsh) = self.tsh {
87            let out = tsh.output(cx);
88            out.attr_99().cursor_show().scroll_up().save_cleanup();
89            out.cursor_hide().clear_all_99_and_remote();
90
91            // Draw fixed stuff here, then break out and store
92            // sub-tiles for areas that need to be updated later
93            let tile = tsh.tile(cx);
94            let sx = tile.sx();
95            let sy = tile.sy();
96            let split_y1 = sy - self.font.sy as i32;
97            let split_y0 = split_y1.min(10);
98            let (top, _, cells_tile) = tile.split_yy(split_y0, split_y1);
99            let spare = sx.saturating_sub(80);
100            let (ox, mini_sx) = if (spare as usize) < self.font.sx / 2 {
101                (spare / 2, 0)
102            } else {
103                (0, spare)
104            };
105            let (_, rest) = top.split_x(ox);
106            let (param_tile, mini_tile, mut keys_tile) = rest.split_xx(40, 40 + mini_sx);
107
108            if let Some(mut r) = keys_tile.region(cx, 0, 0, split_y0, 40) {
109                r.hfb(172).clear_all();
110                let text = "\
111Keys: Arrows move, [Space] change pixel
112Mode on/off: [d] draw, [r] roll
113Fill: [f] flood, [v] vert, [h] horiz
114[n] new glyph, [u] undo, [l] ruler line
115Clip: [c] copy, [P] paste.
116Index: [PgUp] [PgDn] [Home] [End].
117[S] save, [Q] save+quit, [^C] hard quit
118Edit the font file directly to change
119font size or codepoint numbers.";
120                r.text(&text.replace('[', "\0171 ").replace(']', " \0172"));
121            }
122            self.cells_tile = cells_tile;
123            self.param_tile = param_tile;
124            self.mini_tile = mini_tile;
125
126            self.draw_cells(cx);
127            self.draw_mini(cx);
128            self.draw_param(cx);
129        }
130    }
Source

pub fn clear_all(&mut self) -> &mut Self

Clear the whole display to the current colour-pair. This is done by writing spaces to all the cells on the display, since it cannot be done portably using ANSI sequences. Leaves cursor at top-left.

Source

pub fn clear_eol_99(&mut self) -> &mut Self

Add ANSI sequence to erase to end-of-line. This erases with the terminal’s default colour-pair (99), and leaves the current colours set to the default. Some terminals can erase with any colour-pair, but this is not univerally supported, so is not provided here.

Source

pub fn attr_99(&mut self) -> &mut Self

Add ANSI sequence to reset attributes to the default colour-pair (99). The default colour-pair is white on black on a black terminal, or black on white on a white terminal.

Examples found in repository?
examples/test0.rs (line 72)
69    fn redraw(&mut self, cx: CX![]) {
70        if let Some(ref tshare) = self.tshare {
71            let o = tshare.output(cx);
72            o.attr_99().cursor_show().scroll_up().save_cleanup();
73            o.cursor_hide();
74            Self::draw(o);
75        }
76    }
More examples
Hide additional examples
examples/test1.rs (line 72)
69    fn redraw(&mut self, cx: CX![]) {
70        if let Some(ref tshare) = self.tshare {
71            let o = tshare.output(cx);
72            o.attr_99().cursor_show().scroll_up().save_cleanup();
73            o.cursor_hide();
74            Self::draw(o);
75        }
76    }
examples/test2.rs (line 73)
68    fn resize(&mut self, cx: CX![], tshare: Option<TermShare>) {
69        self.tshare = tshare;
70
71        if let Some(ref tshare) = self.tshare {
72            let o = tshare.output(cx);
73            o.attr_99().cursor_show().scroll_up().save_cleanup();
74            o.cursor_hide();
75            self.page = o.new_page();
76        }
77
78        self.redraw(cx, true);
79    }
examples/teeclub/main.rs (line 94)
89    fn resize(&mut self, cx: CX![], tsh: Option<TermShare>) {
90        self.tsh = tsh;
91
92        if let Some(ref tsh) = self.tsh {
93            let out = tsh.output(cx);
94            out.attr_99().cursor_show().scroll_up().save_cleanup();
95            out.cursor_hide().clear_all_99();
96
97            if self.logo_hfb.is_none() && out.features().colour_256 {
98                const LOGO_RGB: [(f64, u32); 7] = [
99                    (0.0, 0xFFFF00),
100                    (1.0, 0x00FF00),
101                    (2.0, 0x22FFFF),
102                    (3.0, 0x4444FF),
103                    (4.0, 0xFF22FF),
104                    (5.0, 0xFF0000),
105                    (6.0, 0xFFFF00),
106                ];
107                self.logo_hfb = Some(
108                    (0..30)
109                        .map(|i| {
110                            let rgb = out.rgb_interpolate(&LOGO_RGB, i as f64 * 0.2);
111                            out.hfb_alloc(false, false, rgb, 0x000000)
112                        })
113                        .collect(),
114                );
115            }
116
117            self.layout(cx);
118        }
119    }
examples/fontedit/app.rs (line 88)
85    fn redraw(&mut self, cx: CX![]) {
86        if let Some(ref tsh) = self.tsh {
87            let out = tsh.output(cx);
88            out.attr_99().cursor_show().scroll_up().save_cleanup();
89            out.cursor_hide().clear_all_99_and_remote();
90
91            // Draw fixed stuff here, then break out and store
92            // sub-tiles for areas that need to be updated later
93            let tile = tsh.tile(cx);
94            let sx = tile.sx();
95            let sy = tile.sy();
96            let split_y1 = sy - self.font.sy as i32;
97            let split_y0 = split_y1.min(10);
98            let (top, _, cells_tile) = tile.split_yy(split_y0, split_y1);
99            let spare = sx.saturating_sub(80);
100            let (ox, mini_sx) = if (spare as usize) < self.font.sx / 2 {
101                (spare / 2, 0)
102            } else {
103                (0, spare)
104            };
105            let (_, rest) = top.split_x(ox);
106            let (param_tile, mini_tile, mut keys_tile) = rest.split_xx(40, 40 + mini_sx);
107
108            if let Some(mut r) = keys_tile.region(cx, 0, 0, split_y0, 40) {
109                r.hfb(172).clear_all();
110                let text = "\
111Keys: Arrows move, [Space] change pixel
112Mode on/off: [d] draw, [r] roll
113Fill: [f] flood, [v] vert, [h] horiz
114[n] new glyph, [u] undo, [l] ruler line
115Clip: [c] copy, [P] paste.
116Index: [PgUp] [PgDn] [Home] [End].
117[S] save, [Q] save+quit, [^C] hard quit
118Edit the font file directly to change
119font size or codepoint numbers.";
120                r.text(&text.replace('[', "\0171 ").replace(']', " \0172"));
121            }
122            self.cells_tile = cells_tile;
123            self.param_tile = param_tile;
124            self.mini_tile = mini_tile;
125
126            self.draw_cells(cx);
127            self.draw_mini(cx);
128            self.draw_param(cx);
129        }
130    }
Source

pub fn reset(&mut self) -> &mut Self

Add ANSI sequence to do a full reset of the terminal. This is ESC c. The screen is erased, and all settings are reset to defaults. This includes tab stops, scroll region, character set, etc.

Source

pub fn cursor_underline(&mut self) -> &mut Self

Add ANSI sequence to switch to underline cursor

Source

pub fn cursor_block(&mut self) -> &mut Self

Add ANSI sequence to switch to block cursor

Source

pub fn cursor_show(&mut self) -> &mut Self

Add ANSI sequences to show cursor

Examples found in repository?
examples/test0.rs (line 72)
69    fn redraw(&mut self, cx: CX![]) {
70        if let Some(ref tshare) = self.tshare {
71            let o = tshare.output(cx);
72            o.attr_99().cursor_show().scroll_up().save_cleanup();
73            o.cursor_hide();
74            Self::draw(o);
75        }
76    }
More examples
Hide additional examples
examples/test1.rs (line 72)
69    fn redraw(&mut self, cx: CX![]) {
70        if let Some(ref tshare) = self.tshare {
71            let o = tshare.output(cx);
72            o.attr_99().cursor_show().scroll_up().save_cleanup();
73            o.cursor_hide();
74            Self::draw(o);
75        }
76    }
examples/test2.rs (line 73)
68    fn resize(&mut self, cx: CX![], tshare: Option<TermShare>) {
69        self.tshare = tshare;
70
71        if let Some(ref tshare) = self.tshare {
72            let o = tshare.output(cx);
73            o.attr_99().cursor_show().scroll_up().save_cleanup();
74            o.cursor_hide();
75            self.page = o.new_page();
76        }
77
78        self.redraw(cx, true);
79    }
examples/teeclub/main.rs (line 94)
89    fn resize(&mut self, cx: CX![], tsh: Option<TermShare>) {
90        self.tsh = tsh;
91
92        if let Some(ref tsh) = self.tsh {
93            let out = tsh.output(cx);
94            out.attr_99().cursor_show().scroll_up().save_cleanup();
95            out.cursor_hide().clear_all_99();
96
97            if self.logo_hfb.is_none() && out.features().colour_256 {
98                const LOGO_RGB: [(f64, u32); 7] = [
99                    (0.0, 0xFFFF00),
100                    (1.0, 0x00FF00),
101                    (2.0, 0x22FFFF),
102                    (3.0, 0x4444FF),
103                    (4.0, 0xFF22FF),
104                    (5.0, 0xFF0000),
105                    (6.0, 0xFFFF00),
106                ];
107                self.logo_hfb = Some(
108                    (0..30)
109                        .map(|i| {
110                            let rgb = out.rgb_interpolate(&LOGO_RGB, i as f64 * 0.2);
111                            out.hfb_alloc(false, false, rgb, 0x000000)
112                        })
113                        .collect(),
114                );
115            }
116
117            self.layout(cx);
118        }
119    }
examples/fontedit/app.rs (line 88)
85    fn redraw(&mut self, cx: CX![]) {
86        if let Some(ref tsh) = self.tsh {
87            let out = tsh.output(cx);
88            out.attr_99().cursor_show().scroll_up().save_cleanup();
89            out.cursor_hide().clear_all_99_and_remote();
90
91            // Draw fixed stuff here, then break out and store
92            // sub-tiles for areas that need to be updated later
93            let tile = tsh.tile(cx);
94            let sx = tile.sx();
95            let sy = tile.sy();
96            let split_y1 = sy - self.font.sy as i32;
97            let split_y0 = split_y1.min(10);
98            let (top, _, cells_tile) = tile.split_yy(split_y0, split_y1);
99            let spare = sx.saturating_sub(80);
100            let (ox, mini_sx) = if (spare as usize) < self.font.sx / 2 {
101                (spare / 2, 0)
102            } else {
103                (0, spare)
104            };
105            let (_, rest) = top.split_x(ox);
106            let (param_tile, mini_tile, mut keys_tile) = rest.split_xx(40, 40 + mini_sx);
107
108            if let Some(mut r) = keys_tile.region(cx, 0, 0, split_y0, 40) {
109                r.hfb(172).clear_all();
110                let text = "\
111Keys: Arrows move, [Space] change pixel
112Mode on/off: [d] draw, [r] roll
113Fill: [f] flood, [v] vert, [h] horiz
114[n] new glyph, [u] undo, [l] ruler line
115Clip: [c] copy, [P] paste.
116Index: [PgUp] [PgDn] [Home] [End].
117[S] save, [Q] save+quit, [^C] hard quit
118Edit the font file directly to change
119font size or codepoint numbers.";
120                r.text(&text.replace('[', "\0171 ").replace(']', " \0172"));
121            }
122            self.cells_tile = cells_tile;
123            self.param_tile = param_tile;
124            self.mini_tile = mini_tile;
125
126            self.draw_cells(cx);
127            self.draw_mini(cx);
128            self.draw_param(cx);
129        }
130    }
Source

pub fn cursor_hide(&mut self) -> &mut Self

Add ANSI sequences to hide cursor

Examples found in repository?
examples/test0.rs (line 73)
69    fn redraw(&mut self, cx: CX![]) {
70        if let Some(ref tshare) = self.tshare {
71            let o = tshare.output(cx);
72            o.attr_99().cursor_show().scroll_up().save_cleanup();
73            o.cursor_hide();
74            Self::draw(o);
75        }
76    }
More examples
Hide additional examples
examples/test1.rs (line 73)
69    fn redraw(&mut self, cx: CX![]) {
70        if let Some(ref tshare) = self.tshare {
71            let o = tshare.output(cx);
72            o.attr_99().cursor_show().scroll_up().save_cleanup();
73            o.cursor_hide();
74            Self::draw(o);
75        }
76    }
examples/test2.rs (line 74)
68    fn resize(&mut self, cx: CX![], tshare: Option<TermShare>) {
69        self.tshare = tshare;
70
71        if let Some(ref tshare) = self.tshare {
72            let o = tshare.output(cx);
73            o.attr_99().cursor_show().scroll_up().save_cleanup();
74            o.cursor_hide();
75            self.page = o.new_page();
76        }
77
78        self.redraw(cx, true);
79    }
examples/teeclub/main.rs (line 95)
89    fn resize(&mut self, cx: CX![], tsh: Option<TermShare>) {
90        self.tsh = tsh;
91
92        if let Some(ref tsh) = self.tsh {
93            let out = tsh.output(cx);
94            out.attr_99().cursor_show().scroll_up().save_cleanup();
95            out.cursor_hide().clear_all_99();
96
97            if self.logo_hfb.is_none() && out.features().colour_256 {
98                const LOGO_RGB: [(f64, u32); 7] = [
99                    (0.0, 0xFFFF00),
100                    (1.0, 0x00FF00),
101                    (2.0, 0x22FFFF),
102                    (3.0, 0x4444FF),
103                    (4.0, 0xFF22FF),
104                    (5.0, 0xFF0000),
105                    (6.0, 0xFFFF00),
106                ];
107                self.logo_hfb = Some(
108                    (0..30)
109                        .map(|i| {
110                            let rgb = out.rgb_interpolate(&LOGO_RGB, i as f64 * 0.2);
111                            out.hfb_alloc(false, false, rgb, 0x000000)
112                        })
113                        .collect(),
114                );
115            }
116
117            self.layout(cx);
118        }
119    }
examples/fontedit/app.rs (line 89)
85    fn redraw(&mut self, cx: CX![]) {
86        if let Some(ref tsh) = self.tsh {
87            let out = tsh.output(cx);
88            out.attr_99().cursor_show().scroll_up().save_cleanup();
89            out.cursor_hide().clear_all_99_and_remote();
90
91            // Draw fixed stuff here, then break out and store
92            // sub-tiles for areas that need to be updated later
93            let tile = tsh.tile(cx);
94            let sx = tile.sx();
95            let sy = tile.sy();
96            let split_y1 = sy - self.font.sy as i32;
97            let split_y0 = split_y1.min(10);
98            let (top, _, cells_tile) = tile.split_yy(split_y0, split_y1);
99            let spare = sx.saturating_sub(80);
100            let (ox, mini_sx) = if (spare as usize) < self.font.sx / 2 {
101                (spare / 2, 0)
102            } else {
103                (0, spare)
104            };
105            let (_, rest) = top.split_x(ox);
106            let (param_tile, mini_tile, mut keys_tile) = rest.split_xx(40, 40 + mini_sx);
107
108            if let Some(mut r) = keys_tile.region(cx, 0, 0, split_y0, 40) {
109                r.hfb(172).clear_all();
110                let text = "\
111Keys: Arrows move, [Space] change pixel
112Mode on/off: [d] draw, [r] roll
113Fill: [f] flood, [v] vert, [h] horiz
114[n] new glyph, [u] undo, [l] ruler line
115Clip: [c] copy, [P] paste.
116Index: [PgUp] [PgDn] [Home] [End].
117[S] save, [Q] save+quit, [^C] hard quit
118Edit the font file directly to change
119font size or codepoint numbers.";
120                r.text(&text.replace('[', "\0171 ").replace(']', " \0172"));
121            }
122            self.cells_tile = cells_tile;
123            self.param_tile = param_tile;
124            self.mini_tile = mini_tile;
125
126            self.draw_cells(cx);
127            self.draw_mini(cx);
128            self.draw_param(cx);
129        }
130    }
Source

pub fn scroll_up(&mut self) -> &mut Self

Move cursor to bottom line and do a linefeed. This results in the screen scrolling one line, and the cursor being left at the bottom-left corner, with default colours active.

Examples found in repository?
examples/test0.rs (line 72)
69    fn redraw(&mut self, cx: CX![]) {
70        if let Some(ref tshare) = self.tshare {
71            let o = tshare.output(cx);
72            o.attr_99().cursor_show().scroll_up().save_cleanup();
73            o.cursor_hide();
74            Self::draw(o);
75        }
76    }
More examples
Hide additional examples
examples/test1.rs (line 72)
69    fn redraw(&mut self, cx: CX![]) {
70        if let Some(ref tshare) = self.tshare {
71            let o = tshare.output(cx);
72            o.attr_99().cursor_show().scroll_up().save_cleanup();
73            o.cursor_hide();
74            Self::draw(o);
75        }
76    }
examples/test2.rs (line 73)
68    fn resize(&mut self, cx: CX![], tshare: Option<TermShare>) {
69        self.tshare = tshare;
70
71        if let Some(ref tshare) = self.tshare {
72            let o = tshare.output(cx);
73            o.attr_99().cursor_show().scroll_up().save_cleanup();
74            o.cursor_hide();
75            self.page = o.new_page();
76        }
77
78        self.redraw(cx, true);
79    }
examples/teeclub/main.rs (line 94)
89    fn resize(&mut self, cx: CX![], tsh: Option<TermShare>) {
90        self.tsh = tsh;
91
92        if let Some(ref tsh) = self.tsh {
93            let out = tsh.output(cx);
94            out.attr_99().cursor_show().scroll_up().save_cleanup();
95            out.cursor_hide().clear_all_99();
96
97            if self.logo_hfb.is_none() && out.features().colour_256 {
98                const LOGO_RGB: [(f64, u32); 7] = [
99                    (0.0, 0xFFFF00),
100                    (1.0, 0x00FF00),
101                    (2.0, 0x22FFFF),
102                    (3.0, 0x4444FF),
103                    (4.0, 0xFF22FF),
104                    (5.0, 0xFF0000),
105                    (6.0, 0xFFFF00),
106                ];
107                self.logo_hfb = Some(
108                    (0..30)
109                        .map(|i| {
110                            let rgb = out.rgb_interpolate(&LOGO_RGB, i as f64 * 0.2);
111                            out.hfb_alloc(false, false, rgb, 0x000000)
112                        })
113                        .collect(),
114                );
115            }
116
117            self.layout(cx);
118        }
119    }
examples/fontedit/app.rs (line 88)
85    fn redraw(&mut self, cx: CX![]) {
86        if let Some(ref tsh) = self.tsh {
87            let out = tsh.output(cx);
88            out.attr_99().cursor_show().scroll_up().save_cleanup();
89            out.cursor_hide().clear_all_99_and_remote();
90
91            // Draw fixed stuff here, then break out and store
92            // sub-tiles for areas that need to be updated later
93            let tile = tsh.tile(cx);
94            let sx = tile.sx();
95            let sy = tile.sy();
96            let split_y1 = sy - self.font.sy as i32;
97            let split_y0 = split_y1.min(10);
98            let (top, _, cells_tile) = tile.split_yy(split_y0, split_y1);
99            let spare = sx.saturating_sub(80);
100            let (ox, mini_sx) = if (spare as usize) < self.font.sx / 2 {
101                (spare / 2, 0)
102            } else {
103                (0, spare)
104            };
105            let (_, rest) = top.split_x(ox);
106            let (param_tile, mini_tile, mut keys_tile) = rest.split_xx(40, 40 + mini_sx);
107
108            if let Some(mut r) = keys_tile.region(cx, 0, 0, split_y0, 40) {
109                r.hfb(172).clear_all();
110                let text = "\
111Keys: Arrows move, [Space] change pixel
112Mode on/off: [d] draw, [r] roll
113Fill: [f] flood, [v] vert, [h] horiz
114[n] new glyph, [u] undo, [l] ruler line
115Clip: [c] copy, [P] paste.
116Index: [PgUp] [PgDn] [Home] [End].
117[S] save, [Q] save+quit, [^C] hard quit
118Edit the font file directly to change
119font size or codepoint numbers.";
120                r.text(&text.replace('[', "\0171 ").replace(']', " \0172"));
121            }
122            self.cells_tile = cells_tile;
123            self.param_tile = param_tile;
124            self.mini_tile = mini_tile;
125
126            self.draw_cells(cx);
127            self.draw_mini(cx);
128            self.draw_param(cx);
129        }
130    }
Source

pub fn save_cleanup(&mut self)

Save the current contents of the output buffer as the cleanup string, then clear the output buffer. The cleanup string will be output to the terminal on error or when the terminal is paused or shutdown.

This string should reset any settings that have been modified, and put the cursor somewhere sensible. The default is Esc c which completely resets the terminal, but usually it’s better to do something less drastic, resetting just the terminal state that was changed by the app, for example termout.attr_99().show_cursor().scroll_up().save_cleanup().

The new cleanup string will be installed on the next flush.

Note that when the Terminal actor is dropped, the cleanup string will be emitted if required. However if the event loop has stopped running, then this will not happen. So in the app shutdown, it’s important that the Terminal actor is dropped before the main loop stops running. See the examples for configurations that work.

Examples found in repository?
examples/test0.rs (line 72)
69    fn redraw(&mut self, cx: CX![]) {
70        if let Some(ref tshare) = self.tshare {
71            let o = tshare.output(cx);
72            o.attr_99().cursor_show().scroll_up().save_cleanup();
73            o.cursor_hide();
74            Self::draw(o);
75        }
76    }
More examples
Hide additional examples
examples/test1.rs (line 72)
69    fn redraw(&mut self, cx: CX![]) {
70        if let Some(ref tshare) = self.tshare {
71            let o = tshare.output(cx);
72            o.attr_99().cursor_show().scroll_up().save_cleanup();
73            o.cursor_hide();
74            Self::draw(o);
75        }
76    }
examples/test2.rs (line 73)
68    fn resize(&mut self, cx: CX![], tshare: Option<TermShare>) {
69        self.tshare = tshare;
70
71        if let Some(ref tshare) = self.tshare {
72            let o = tshare.output(cx);
73            o.attr_99().cursor_show().scroll_up().save_cleanup();
74            o.cursor_hide();
75            self.page = o.new_page();
76        }
77
78        self.redraw(cx, true);
79    }
examples/teeclub/main.rs (line 94)
89    fn resize(&mut self, cx: CX![], tsh: Option<TermShare>) {
90        self.tsh = tsh;
91
92        if let Some(ref tsh) = self.tsh {
93            let out = tsh.output(cx);
94            out.attr_99().cursor_show().scroll_up().save_cleanup();
95            out.cursor_hide().clear_all_99();
96
97            if self.logo_hfb.is_none() && out.features().colour_256 {
98                const LOGO_RGB: [(f64, u32); 7] = [
99                    (0.0, 0xFFFF00),
100                    (1.0, 0x00FF00),
101                    (2.0, 0x22FFFF),
102                    (3.0, 0x4444FF),
103                    (4.0, 0xFF22FF),
104                    (5.0, 0xFF0000),
105                    (6.0, 0xFFFF00),
106                ];
107                self.logo_hfb = Some(
108                    (0..30)
109                        .map(|i| {
110                            let rgb = out.rgb_interpolate(&LOGO_RGB, i as f64 * 0.2);
111                            out.hfb_alloc(false, false, rgb, 0x000000)
112                        })
113                        .collect(),
114                );
115            }
116
117            self.layout(cx);
118        }
119    }
examples/fontedit/app.rs (line 88)
85    fn redraw(&mut self, cx: CX![]) {
86        if let Some(ref tsh) = self.tsh {
87            let out = tsh.output(cx);
88            out.attr_99().cursor_show().scroll_up().save_cleanup();
89            out.cursor_hide().clear_all_99_and_remote();
90
91            // Draw fixed stuff here, then break out and store
92            // sub-tiles for areas that need to be updated later
93            let tile = tsh.tile(cx);
94            let sx = tile.sx();
95            let sy = tile.sy();
96            let split_y1 = sy - self.font.sy as i32;
97            let split_y0 = split_y1.min(10);
98            let (top, _, cells_tile) = tile.split_yy(split_y0, split_y1);
99            let spare = sx.saturating_sub(80);
100            let (ox, mini_sx) = if (spare as usize) < self.font.sx / 2 {
101                (spare / 2, 0)
102            } else {
103                (0, spare)
104            };
105            let (_, rest) = top.split_x(ox);
106            let (param_tile, mini_tile, mut keys_tile) = rest.split_xx(40, 40 + mini_sx);
107
108            if let Some(mut r) = keys_tile.region(cx, 0, 0, split_y0, 40) {
109                r.hfb(172).clear_all();
110                let text = "\
111Keys: Arrows move, [Space] change pixel
112Mode on/off: [d] draw, [r] roll
113Fill: [f] flood, [v] vert, [h] horiz
114[n] new glyph, [u] undo, [l] ruler line
115Clip: [c] copy, [P] paste.
116Index: [PgUp] [PgDn] [Home] [End].
117[S] save, [Q] save+quit, [^C] hard quit
118Edit the font file directly to change
119font size or codepoint numbers.";
120                r.text(&text.replace('[', "\0171 ").replace(']', " \0172"));
121            }
122            self.cells_tile = cells_tile;
123            self.param_tile = param_tile;
124            self.mini_tile = mini_tile;
125
126            self.draw_cells(cx);
127            self.draw_mini(cx);
128            self.draw_param(cx);
129        }
130    }
Source

pub fn hfb_alloc( &mut self, bold: bool, underline: bool, fg: u32, bg: u32, ) -> u16

Allocate an HFB value to represent the given attribute-set (bold, underline, foreground, background), where colours are expressed using 0xRRGGBB values. Chooses nearest colours out of standard 256-colour palette if available, or else reverts to 8-colour approximations. If the colour has been allocated previously, returns that HFB value. Colour allocations last as long as the Terminal actor remains alive.

Examples found in repository?
examples/teeclub/main.rs (line 111)
89    fn resize(&mut self, cx: CX![], tsh: Option<TermShare>) {
90        self.tsh = tsh;
91
92        if let Some(ref tsh) = self.tsh {
93            let out = tsh.output(cx);
94            out.attr_99().cursor_show().scroll_up().save_cleanup();
95            out.cursor_hide().clear_all_99();
96
97            if self.logo_hfb.is_none() && out.features().colour_256 {
98                const LOGO_RGB: [(f64, u32); 7] = [
99                    (0.0, 0xFFFF00),
100                    (1.0, 0x00FF00),
101                    (2.0, 0x22FFFF),
102                    (3.0, 0x4444FF),
103                    (4.0, 0xFF22FF),
104                    (5.0, 0xFF0000),
105                    (6.0, 0xFFFF00),
106                ];
107                self.logo_hfb = Some(
108                    (0..30)
109                        .map(|i| {
110                            let rgb = out.rgb_interpolate(&LOGO_RGB, i as f64 * 0.2);
111                            out.hfb_alloc(false, false, rgb, 0x000000)
112                        })
113                        .collect(),
114                );
115            }
116
117            self.layout(cx);
118        }
119    }
More examples
Hide additional examples
examples/test0.rs (line 179)
86    fn draw(o: &mut Output) {
87        o.clear_all_99();
88        if o.sy() < 24 || o.sx() < 80 {
89            o.hfb(162);
90            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
91            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
92            o.hfb(99);
93            o.flush();
94            return;
95        }
96
97        let x0 = (o.sx() - 80) >> 1;
98        let y0 = (o.sy() - 24) >> 1;
99        let mut yy = y0;
100        let c256 = o.features().colour_256;
101        o.at(yy, x0).hfb(99).text("Colour mode:");
102        o.at(yy, x0 + 15)
103            .hfb(199)
104            .text(if c256 { "256-colour" } else { "8-colour" });
105        yy += 2;
106
107        o.at(yy, x0).hfb(99).text("Attributes:");
108        yy += 1;
109        const TEXT: [&str; 4] = ["White:", "Brown:", "Blue:", "Black:"];
110        const BASE_HFB: [u16; 4] = [70, 60, 10, 3];
111        for i in 0..4 {
112            let hfb = BASE_HFB[i];
113            o.at(yy, x0 + 2).hfb(99).text(TEXT[i]);
114            o.at(yy, x0 + 16).hfb(hfb).text(" norm ");
115            o.at(yy, x0 + 22).hfb(100 + hfb).text("bold ");
116            o.at(yy, x0 + 27).hfb(200 + hfb).text("undl ");
117            o.at(yy, x0 + 32).hfb(300 + hfb).text("both ");
118            yy += 1;
119        }
120        o.at(yy + 1, x0)
121            .hfb(60)
122            .text(" (On 8-colour expect bold/ul to");
123        o.at(yy + 2, x0)
124            .hfb(60)
125            .text("  be emulated as colour changes.)");
126        let y1a = yy + 3;
127
128        yy = y0;
129        o.at(yy, x0 + 40)
130            .hfb(99)
131            .text("Base, bold and background colours:");
132        o.at(yy + 1, x0 + 42).hfb(7).text("  black   ");
133        o.at(yy + 2, x0 + 42).hfb(10).text("  blue    ");
134        o.at(yy + 3, x0 + 42).hfb(20).text("  red     ");
135        o.at(yy + 4, x0 + 42).hfb(30).text("  magenta ");
136        o.at(yy + 5, x0 + 42).hfb(40).text("  green   ");
137        o.at(yy + 6, x0 + 42).hfb(50).text("  cyan    ");
138        o.at(yy + 7, x0 + 42).hfb(60).text("  yellow  ");
139        o.at(yy + 8, x0 + 42).hfb(70).text("  white   ");
140        o.at(yy + 1, x0 + 54).hfb(100).text("  black   ");
141        o.at(yy + 2, x0 + 54).hfb(110).text("  blue    ");
142        o.at(yy + 3, x0 + 54).hfb(120).text("  red     ");
143        o.at(yy + 4, x0 + 54).hfb(130).text("  magenta ");
144        o.at(yy + 5, x0 + 54).hfb(140).text("  green   ");
145        o.at(yy + 6, x0 + 54).hfb(150).text("  cyan    ");
146        o.at(yy + 7, x0 + 54).hfb(160).text("  yellow  ");
147        o.at(yy + 8, x0 + 54).hfb(170).text("  white   ");
148        o.at(yy + 1, x0 + 66).hfb(70).text("  black   ");
149        o.at(yy + 2, x0 + 66).hfb(71).text("  blue    ");
150        o.at(yy + 3, x0 + 66).hfb(72).text("  red     ");
151        o.at(yy + 4, x0 + 66).hfb(73).text("  magenta ");
152        o.at(yy + 5, x0 + 66).hfb(4).text("  green   ");
153        o.at(yy + 6, x0 + 66).hfb(5).text("  cyan    ");
154        o.at(yy + 7, x0 + 66).hfb(6).text("  yellow  ");
155        o.at(yy + 8, x0 + 66).hfb(7).text("  white   ");
156        o.at(yy + 10, x0 + 40)
157            .hfb(60)
158            .text(" (Expect all 16 colours to be");
159        o.at(yy + 11, x0 + 40)
160            .hfb(60)
161            .text("  visible in all cases.)");
162        let y1b = yy + 12;
163        let end = y1a.max(y1b);
164
165        yy = end + 10;
166        o.at(yy - 1, x0).hfb(99).text("Hue wheel");
167        o.at(yy, x0);
168        if o.features().colour_256 {
169            const RED: [i32; 7] = [255, 255, 0, 0, 0, 255, 255];
170            const GREEN: [i32; 7] = [0, 255, 255, 255, 0, 0, 0];
171            const BLUE: [i32; 7] = [0, 0, 0, 255, 255, 255, 0];
172            for x in 0..78 {
173                let i = x / 13;
174                let off = (x - i * 13) as i32;
175                let r = RED[i] + (RED[i + 1] - RED[i]) * off / 13;
176                let g = GREEN[i] + (GREEN[i + 1] - GREEN[i]) * off / 13;
177                let b = BLUE[i] + (BLUE[i + 1] - BLUE[i]) * off / 13;
178                let rgb = (r << 16) + (g << 8) + b;
179                let hfb = o.hfb_alloc(false, false, 0xFFFFFF, rgb as u32);
180                o.hfb(hfb).spaces(1);
181            }
182        } else {
183            o.hfb(2).spaces(13);
184            o.hfb(6).spaces(13);
185            o.hfb(4).spaces(13);
186            o.hfb(5).spaces(13);
187            o.hfb(1).spaces(13);
188            o.hfb(3).spaces(13);
189        }
190
191        yy = end + 1;
192        let mut xx = x0 + 40;
193
194        o.at(yy, xx).hfb(99).text("ASCII");
195        for a in 0..96 {
196            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
197                .char(char::from_u32((a + 32) as u32).unwrap());
198        }
199
200        xx += 20;
201        o.at(yy, xx).hfb(99).text("Latin-1");
202        for a in 0..96 {
203            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
204                .char(char::from_u32((a + 160) as u32).unwrap());
205        }
206
207        const BOXTITLE1: &str = "\
208Single  Single  Double  Thick";
209        const BOXTITLE2: &str = "\
210+Double +Thick  +Single +Single";
211
212        const BOXTEST: &str = "\
213+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
214| | H | | | $ | H H | H $ $ | $
215+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
216| | H | | | $ | H H | H $ $ | $
217+=+=+=+ +*+*+*+ +-+-+-+ +-+-+-+
218| | H | | | $ | H H | H $ $ | $
219+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+";
220
221        let boxtest = Output::box_from_ascii_art(BOXTEST);
222        yy = end + 1;
223        xx = x0 + 2;
224        o.at(yy - 2, xx).text(BOXTITLE1);
225        o.at(yy - 1, xx).text(BOXTITLE2);
226        for line in boxtest.split('\n') {
227            o.at(yy, xx).text(line);
228            yy += 1;
229        }
230
231        o.flush();
232    }
Source

pub fn rgb_interpolate(&self, list: &[(f64, u32)], value: f64) -> u32

Generate an interpolated 24-bit RGB value based on the given value within the given ordered list of value-to-RGB mappings (f64, u32) which should be in order of value. If the provided value is before the first or after the last, the first/last RGB value is returned instead of an interpolated value.

Examples found in repository?
examples/teeclub/main.rs (line 110)
89    fn resize(&mut self, cx: CX![], tsh: Option<TermShare>) {
90        self.tsh = tsh;
91
92        if let Some(ref tsh) = self.tsh {
93            let out = tsh.output(cx);
94            out.attr_99().cursor_show().scroll_up().save_cleanup();
95            out.cursor_hide().clear_all_99();
96
97            if self.logo_hfb.is_none() && out.features().colour_256 {
98                const LOGO_RGB: [(f64, u32); 7] = [
99                    (0.0, 0xFFFF00),
100                    (1.0, 0x00FF00),
101                    (2.0, 0x22FFFF),
102                    (3.0, 0x4444FF),
103                    (4.0, 0xFF22FF),
104                    (5.0, 0xFF0000),
105                    (6.0, 0xFFFF00),
106                ];
107                self.logo_hfb = Some(
108                    (0..30)
109                        .map(|i| {
110                            let rgb = out.rgb_interpolate(&LOGO_RGB, i as f64 * 0.2);
111                            out.hfb_alloc(false, false, rgb, 0x000000)
112                        })
113                        .collect(),
114                );
115            }
116
117            self.layout(cx);
118        }
119    }
Source

pub fn update_to(&mut self, page: &mut Page, redraw: bool)

Update the terminal screen to match the given Page. A minimised update is sent to the terminal (by comparing to the previous Page sent) unless redraw is true in which case the terminal is cleared and a full update is sent.

Examples found in repository?
examples/test2.rs (line 146)
143    fn update(&mut self, cx: CX![], full: bool) {
144        if let Some(ref tshare) = self.tshare {
145            let o = tshare.output(cx);
146            o.update_to(&mut self.page, full);
147        }
148    }
Source

pub fn new_page(&self) -> Page

Create a new blank Page with the same size as the terminal, cleared to default foreground/background colours (HFB 99).

Examples found in repository?
examples/test2.rs (line 75)
68    fn resize(&mut self, cx: CX![], tshare: Option<TermShare>) {
69        self.tshare = tshare;
70
71        if let Some(ref tshare) = self.tshare {
72            let o = tshare.output(cx);
73            o.attr_99().cursor_show().scroll_up().save_cleanup();
74            o.cursor_hide();
75            self.page = o.new_page();
76        }
77
78        self.redraw(cx, true);
79    }
Source

pub fn box_from_ascii_art(inp: &str) -> String

Generate a multi-line diagram in Unicode box characters from simple ASCII-art. The input is a multi-line diagram using the following characters:

  • | and - for single-line vertical and horizontal
  • H and = for double-lined vertical and horizontal
  • $ and * for thick single-line vertical and horizontal
  • + for a cautious joiner, which won’t join to itself
  • # for an enthusiastic joiner, which will join to any joiner

The joiner uses thick, thin or double parts depending on the adjacent characters.

Examples found in repository?
examples/test0.rs (line 221)
86    fn draw(o: &mut Output) {
87        o.clear_all_99();
88        if o.sy() < 24 || o.sx() < 80 {
89            o.hfb(162);
90            o.at(o.sy() >> 1, (o.sx() - 30) >> 1);
91            write!(o, " Terminal too small: {} x {} ", o.sy(), o.sx()).unwrap();
92            o.hfb(99);
93            o.flush();
94            return;
95        }
96
97        let x0 = (o.sx() - 80) >> 1;
98        let y0 = (o.sy() - 24) >> 1;
99        let mut yy = y0;
100        let c256 = o.features().colour_256;
101        o.at(yy, x0).hfb(99).text("Colour mode:");
102        o.at(yy, x0 + 15)
103            .hfb(199)
104            .text(if c256 { "256-colour" } else { "8-colour" });
105        yy += 2;
106
107        o.at(yy, x0).hfb(99).text("Attributes:");
108        yy += 1;
109        const TEXT: [&str; 4] = ["White:", "Brown:", "Blue:", "Black:"];
110        const BASE_HFB: [u16; 4] = [70, 60, 10, 3];
111        for i in 0..4 {
112            let hfb = BASE_HFB[i];
113            o.at(yy, x0 + 2).hfb(99).text(TEXT[i]);
114            o.at(yy, x0 + 16).hfb(hfb).text(" norm ");
115            o.at(yy, x0 + 22).hfb(100 + hfb).text("bold ");
116            o.at(yy, x0 + 27).hfb(200 + hfb).text("undl ");
117            o.at(yy, x0 + 32).hfb(300 + hfb).text("both ");
118            yy += 1;
119        }
120        o.at(yy + 1, x0)
121            .hfb(60)
122            .text(" (On 8-colour expect bold/ul to");
123        o.at(yy + 2, x0)
124            .hfb(60)
125            .text("  be emulated as colour changes.)");
126        let y1a = yy + 3;
127
128        yy = y0;
129        o.at(yy, x0 + 40)
130            .hfb(99)
131            .text("Base, bold and background colours:");
132        o.at(yy + 1, x0 + 42).hfb(7).text("  black   ");
133        o.at(yy + 2, x0 + 42).hfb(10).text("  blue    ");
134        o.at(yy + 3, x0 + 42).hfb(20).text("  red     ");
135        o.at(yy + 4, x0 + 42).hfb(30).text("  magenta ");
136        o.at(yy + 5, x0 + 42).hfb(40).text("  green   ");
137        o.at(yy + 6, x0 + 42).hfb(50).text("  cyan    ");
138        o.at(yy + 7, x0 + 42).hfb(60).text("  yellow  ");
139        o.at(yy + 8, x0 + 42).hfb(70).text("  white   ");
140        o.at(yy + 1, x0 + 54).hfb(100).text("  black   ");
141        o.at(yy + 2, x0 + 54).hfb(110).text("  blue    ");
142        o.at(yy + 3, x0 + 54).hfb(120).text("  red     ");
143        o.at(yy + 4, x0 + 54).hfb(130).text("  magenta ");
144        o.at(yy + 5, x0 + 54).hfb(140).text("  green   ");
145        o.at(yy + 6, x0 + 54).hfb(150).text("  cyan    ");
146        o.at(yy + 7, x0 + 54).hfb(160).text("  yellow  ");
147        o.at(yy + 8, x0 + 54).hfb(170).text("  white   ");
148        o.at(yy + 1, x0 + 66).hfb(70).text("  black   ");
149        o.at(yy + 2, x0 + 66).hfb(71).text("  blue    ");
150        o.at(yy + 3, x0 + 66).hfb(72).text("  red     ");
151        o.at(yy + 4, x0 + 66).hfb(73).text("  magenta ");
152        o.at(yy + 5, x0 + 66).hfb(4).text("  green   ");
153        o.at(yy + 6, x0 + 66).hfb(5).text("  cyan    ");
154        o.at(yy + 7, x0 + 66).hfb(6).text("  yellow  ");
155        o.at(yy + 8, x0 + 66).hfb(7).text("  white   ");
156        o.at(yy + 10, x0 + 40)
157            .hfb(60)
158            .text(" (Expect all 16 colours to be");
159        o.at(yy + 11, x0 + 40)
160            .hfb(60)
161            .text("  visible in all cases.)");
162        let y1b = yy + 12;
163        let end = y1a.max(y1b);
164
165        yy = end + 10;
166        o.at(yy - 1, x0).hfb(99).text("Hue wheel");
167        o.at(yy, x0);
168        if o.features().colour_256 {
169            const RED: [i32; 7] = [255, 255, 0, 0, 0, 255, 255];
170            const GREEN: [i32; 7] = [0, 255, 255, 255, 0, 0, 0];
171            const BLUE: [i32; 7] = [0, 0, 0, 255, 255, 255, 0];
172            for x in 0..78 {
173                let i = x / 13;
174                let off = (x - i * 13) as i32;
175                let r = RED[i] + (RED[i + 1] - RED[i]) * off / 13;
176                let g = GREEN[i] + (GREEN[i + 1] - GREEN[i]) * off / 13;
177                let b = BLUE[i] + (BLUE[i + 1] - BLUE[i]) * off / 13;
178                let rgb = (r << 16) + (g << 8) + b;
179                let hfb = o.hfb_alloc(false, false, 0xFFFFFF, rgb as u32);
180                o.hfb(hfb).spaces(1);
181            }
182        } else {
183            o.hfb(2).spaces(13);
184            o.hfb(6).spaces(13);
185            o.hfb(4).spaces(13);
186            o.hfb(5).spaces(13);
187            o.hfb(1).spaces(13);
188            o.hfb(3).spaces(13);
189        }
190
191        yy = end + 1;
192        let mut xx = x0 + 40;
193
194        o.at(yy, xx).hfb(99).text("ASCII");
195        for a in 0..96 {
196            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
197                .char(char::from_u32((a + 32) as u32).unwrap());
198        }
199
200        xx += 20;
201        o.at(yy, xx).hfb(99).text("Latin-1");
202        for a in 0..96 {
203            o.at(yy + 1 + (a >> 4), xx + 1 + (a & 15))
204                .char(char::from_u32((a + 160) as u32).unwrap());
205        }
206
207        const BOXTITLE1: &str = "\
208Single  Single  Double  Thick";
209        const BOXTITLE2: &str = "\
210+Double +Thick  +Single +Single";
211
212        const BOXTEST: &str = "\
213+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
214| | H | | | $ | H H | H $ $ | $
215+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+
216| | H | | | $ | H H | H $ $ | $
217+=+=+=+ +*+*+*+ +-+-+-+ +-+-+-+
218| | H | | | $ | H H | H $ $ | $
219+-+-+-+ +-+-+-+ +=+=+=+ +*+*+*+";
220
221        let boxtest = Output::box_from_ascii_art(BOXTEST);
222        yy = end + 1;
223        xx = x0 + 2;
224        o.at(yy - 2, xx).text(BOXTITLE1);
225        o.at(yy - 1, xx).text(BOXTITLE2);
226        for line in boxtest.split('\n') {
227            o.at(yy, xx).text(line);
228            yy += 1;
229        }
230
231        o.flush();
232    }

Trait Implementations§

Source§

impl Write for Output

Source§

fn flush(&mut self) -> Result<()>

Logically we consider the final destination of the Write trait to be the buffer. So this flush call does nothing. In general we’ll want to gather all the updates into one big flush to avoid tearing on the terminal.

Source§

fn write(&mut self, buf: &[u8]) -> Result<usize>

Writes a buffer into this writer, returning how many bytes were written. Read more
1.36.0 · Source§

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize, Error>

Like write, except that it writes from a slice of buffers. Read more
Source§

fn is_write_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Writer has an efficient write_vectored implementation. Read more
1.0.0 · Source§

fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>

Attempts to write an entire buffer into this writer. Read more
Source§

fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>

🔬This is a nightly-only experimental API. (write_all_vectored)
Attempts to write multiple buffers into this writer. Read more
1.0.0 · Source§

fn write_fmt(&mut self, args: Arguments<'_>) -> Result<(), Error>

Writes a formatted string into this writer, returning any error encountered. Read more
1.0.0 · Source§

fn by_ref(&mut self) -> &mut Self
where Self: Sized,

Creates a “by reference” adapter for this instance of Write. Read more

Auto Trait Implementations§

§

impl Freeze for Output

§

impl !RefUnwindSafe for Output

§

impl !Send for Output

§

impl !Sync for Output

§

impl Unpin for Output

§

impl UnsafeUnpin for Output

§

impl !UnwindSafe for Output

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.