Skip to main content

tui_scrollbar/
glyphs.rs

1//! Glyph configuration for scrollbar rendering.
2
3/// Glyphs used to render the track, arrows, and thumb.
4///
5/// Arrays use indices 0..=7 to represent 1/8th through full coverage.
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct GlyphSet {
8    /// Track glyph for vertical scrollbars.
9    pub track_vertical: char,
10    /// Track glyph for horizontal scrollbars.
11    pub track_horizontal: char,
12    /// Arrow glyph for the start of a vertical scrollbar (top).
13    pub arrow_vertical_start: char,
14    /// Arrow glyph for the end of a vertical scrollbar (bottom).
15    pub arrow_vertical_end: char,
16    /// Arrow glyph for the start of a horizontal scrollbar (left).
17    pub arrow_horizontal_start: char,
18    /// Arrow glyph for the end of a horizontal scrollbar (right).
19    pub arrow_horizontal_end: char,
20    /// Thumb glyphs for vertical lower fills (1/8th through full).
21    pub thumb_vertical_lower: [char; 8],
22    /// Thumb glyphs for vertical upper fills (1/8th through full).
23    pub thumb_vertical_upper: [char; 8],
24    /// Thumb glyphs for horizontal left fills (1/8th through full).
25    pub thumb_horizontal_left: [char; 8],
26    /// Thumb glyphs for horizontal right fills (1/8th through full).
27    pub thumb_horizontal_right: [char; 8],
28}
29
30impl GlyphSet {
31    /// Minimal glyphs: no visible track by default.
32    ///
33    /// Choose this when the thumb should stand out by color against a filled background instead of
34    /// a visible line.
35    ///
36    /// This uses a space character for the track so the scrollbar is "all thumb", with the
37    /// background color coming from `track_style`.
38    ///
39    /// ```plain
40    /// [██      ]
41    /// [🮋█▏     ]
42    /// [🮊█▎     ]
43    /// [🮉█▍     ]
44    /// [▐█▌     ]
45    /// [🮈█▋     ]
46    /// [🮇█▊     ]
47    /// [▕█▉     ]
48    /// [ ██     ]
49    /// ```
50    pub const fn minimal() -> Self {
51        let mut glyphs = Self::symbols_for_legacy_computing();
52        glyphs.track_vertical = ' ';
53        glyphs.track_horizontal = ' ';
54        glyphs
55    }
56
57    /// Glyphs that include box-drawing line symbols for the track.
58    ///
59    /// Choose this when callers should see a visible track line behind the thumb.
60    ///
61    /// ```plain
62    /// [██──────]
63    /// [🮋█▏─────]
64    /// [🮊█▎─────]
65    /// [🮉█▍─────]
66    /// [▐█▌─────]
67    /// [🮈█▋─────]
68    /// [🮇█▊─────]
69    /// [▕█▉─────]
70    /// [─██─────]
71    /// ```
72    pub const fn box_drawing() -> Self {
73        Self::symbols_for_legacy_computing()
74    }
75
76    /// Glyphs that mix standard block elements with legacy supplement glyphs.
77    ///
78    /// Choose this when the terminal font supports [Symbols for Legacy Computing] and you want
79    /// precise 1/8th-cell rendering on every thumb edge.
80    ///
81    /// Use this to get full 1/8th coverage for upper and right edges that the standard block set
82    /// lacks; these glyphs come from [Symbols for Legacy Computing].
83    ///
84    /// ```plain
85    /// [██──────]
86    /// [🮋█▏─────]
87    /// [🮊█▎─────]
88    /// [🮉█▍─────]
89    /// [▐█▌─────]
90    /// [🮈█▋─────]
91    /// [🮇█▊─────]
92    /// [▕█▉─────]
93    /// [─██─────]
94    /// ```
95    ///
96    /// [Symbols for Legacy Computing]: https://en.wikipedia.org/wiki/Symbols_for_Legacy_Computing
97    pub const fn symbols_for_legacy_computing() -> Self {
98        let vertical_lower = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
99        let vertical_upper = ['▔', '🮂', '🮃', '▀', '🮄', '🮅', '🮆', '█'];
100        let horizontal_left = ['▏', '▎', '▍', '▌', '▋', '▊', '▉', '█'];
101        let horizontal_right = ['▕', '🮇', '🮈', '▐', '🮉', '🮊', '🮋', '█'];
102        Self {
103            track_vertical: '│',
104            track_horizontal: '─',
105            arrow_vertical_start: '▲',
106            arrow_vertical_end: '▼',
107            arrow_horizontal_start: '◀',
108            arrow_horizontal_end: '▶',
109            thumb_vertical_lower: vertical_lower,
110            thumb_vertical_upper: vertical_upper,
111            thumb_horizontal_left: horizontal_left,
112            thumb_horizontal_right: horizontal_right,
113        }
114    }
115
116    /// Glyphs using only standard Unicode block elements.
117    ///
118    /// Choose this if your font lacks the legacy glyphs.
119    ///
120    /// The standard block set does not include 1/8th upper or right fills (those come from
121    /// [Symbols for Legacy Computing]), so this set approximates upper and right partials by
122    /// rounding to coarse blocks:
123    ///
124    /// - ~1/4: `▔` / `▕`
125    /// - ~1/2 and ~3/4: `▀` / `▐`
126    /// - ~7/8 and full: `█`
127    ///
128    /// ```plain
129    /// [██──────]
130    /// [██▏─────]
131    /// [▐█▎─────]
132    /// [▐█▍─────]
133    /// [▐█▌─────]
134    /// [▐█▋─────]
135    /// [▕█▊─────]
136    /// [▕█▉─────]
137    /// [─██─────]
138    /// ```
139    ///
140    /// [Symbols for Legacy Computing]: https://en.wikipedia.org/wiki/Symbols_for_Legacy_Computing
141    pub const fn unicode() -> Self {
142        let vertical_lower = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
143        let vertical_upper = ['▔', '▔', '▀', '▀', '▀', '▀', '█', '█'];
144        let horizontal_left = ['▏', '▎', '▍', '▌', '▋', '▊', '▉', '█'];
145        let horizontal_right = ['▕', '▕', '▐', '▐', '▐', '▐', '█', '█'];
146        Self {
147            track_vertical: '│',
148            track_horizontal: '─',
149            arrow_vertical_start: '▲',
150            arrow_vertical_end: '▼',
151            arrow_horizontal_start: '◀',
152            arrow_horizontal_end: '▶',
153            thumb_vertical_lower: vertical_lower,
154            thumb_vertical_upper: vertical_upper,
155            thumb_horizontal_left: horizontal_left,
156            thumb_horizontal_right: horizontal_right,
157        }
158    }
159}
160
161impl Default for GlyphSet {
162    fn default() -> Self {
163        Self::minimal()
164    }
165}