pub struct Scrollbar<'a> { /* private fields */ }
Expand description
A widget to display a scrollbar
The following components of the scrollbar are customizable in symbol and style. Note the scrollbar is represented horizontally but it can also be set vertically (which is actually the default).
<--▮------->
^ ^ ^ ^
│ │ │ └ end
│ │ └──── track
│ └──────── thumb
└─────────── begin
§Important
You must specify the ScrollbarState::content_length
before rendering the Scrollbar
, or
else the Scrollbar
will render blank.
§Examples
use ratatui::{
layout::{Margin, Rect},
text::Line,
widgets::{
Block, Borders, Paragraph, Scrollbar, ScrollbarOrientation, ScrollbarState,
StatefulWidget,
},
Frame,
};
let vertical_scroll = 0; // from app state
let items = vec![
Line::from("Item 1"),
Line::from("Item 2"),
Line::from("Item 3"),
];
let paragraph = Paragraph::new(items.clone())
.scroll((vertical_scroll as u16, 0))
.block(Block::new().borders(Borders::RIGHT)); // to show a background for the scrollbar
let scrollbar = Scrollbar::new(ScrollbarOrientation::VerticalRight)
.begin_symbol(Some("↑"))
.end_symbol(Some("↓"));
let mut scrollbar_state = ScrollbarState::new(items.len()).position(vertical_scroll);
let area = frame.area();
// Note we render the paragraph
frame.render_widget(paragraph, area);
// and the scrollbar, those are separate widgets
frame.render_stateful_widget(
scrollbar,
area.inner(Margin {
// using an inner vertical margin of 1 unit makes the scrollbar inside the block
vertical: 1,
horizontal: 0,
}),
&mut scrollbar_state,
);
Implementations§
Source§impl<'a> Scrollbar<'a>
impl<'a> Scrollbar<'a>
Sourcepub const fn new(orientation: ScrollbarOrientation) -> Self
pub const fn new(orientation: ScrollbarOrientation) -> Self
Creates a new scrollbar with the given orientation.
Most of the time you’ll want ScrollbarOrientation::VerticalRight
or
ScrollbarOrientation::HorizontalBottom
. See ScrollbarOrientation
for more options.
Examples found in repository?
174fn render_scrollbar(position: usize, area: Rect, buf: &mut Buffer) {
175 let mut state = ScrollbarState::default()
176 .content_length(INGREDIENTS.len())
177 .viewport_content_length(6)
178 .position(position);
179 Scrollbar::new(ScrollbarOrientation::VerticalRight)
180 .begin_symbol(None)
181 .end_symbol(None)
182 .track_symbol(None)
183 .thumb_symbol("▐")
184 .render(area, buf, &mut state);
185}
More examples
307 fn render_demo(self, area: Rect, buf: &mut Buffer) -> bool {
308 // render demo content into a separate buffer so all examples fit we add an extra
309 // area.height to make sure the last example is fully visible even when the scroll offset is
310 // at the max
311 let height = example_height();
312 let demo_area = Rect::new(0, 0, area.width, height);
313 let mut demo_buf = Buffer::empty(demo_area);
314
315 let scrollbar_needed = self.scroll_offset != 0 || height > area.height;
316 let content_area = if scrollbar_needed {
317 Rect {
318 width: demo_area.width - 1,
319 ..demo_area
320 }
321 } else {
322 demo_area
323 };
324
325 let mut spacing = self.spacing;
326 self.selected_tab
327 .render(content_area, &mut demo_buf, &mut spacing);
328
329 let visible_content = demo_buf
330 .content
331 .into_iter()
332 .skip((area.width * self.scroll_offset) as usize)
333 .take(area.area() as usize);
334 for (i, cell) in visible_content.enumerate() {
335 let x = i as u16 % area.width;
336 let y = i as u16 / area.width;
337 buf[(area.x + x, area.y + y)] = cell;
338 }
339
340 if scrollbar_needed {
341 let area = area.intersection(buf.area);
342 let mut state = ScrollbarState::new(max_scroll_offset() as usize)
343 .position(self.scroll_offset as usize);
344 Scrollbar::new(ScrollbarOrientation::VerticalRight).render(area, buf, &mut state);
345 }
346 scrollbar_needed
347 }
92 fn draw(&mut self, frame: &mut Frame) {
93 let area = frame.area();
94
95 // Words made "loooong" to demonstrate line breaking.
96 let s =
97 "Veeeeeeeeeeeeeeeery loooooooooooooooooong striiiiiiiiiiiiiiiiiiiiiiiiiing. ";
98 let mut long_line = s.repeat(usize::from(area.width) / s.len() + 4);
99 long_line.push('\n');
100
101 let chunks = Layout::vertical([
102 Constraint::Min(1),
103 Constraint::Percentage(25),
104 Constraint::Percentage(25),
105 Constraint::Percentage(25),
106 Constraint::Percentage(25),
107 ])
108 .split(area);
109
110 let text = vec![
111 Line::from("This is a line "),
112 Line::from("This is a line ".red()),
113 Line::from("This is a line".on_dark_gray()),
114 Line::from("This is a longer line".crossed_out()),
115 Line::from(long_line.clone()),
116 Line::from("This is a line".reset()),
117 Line::from(vec![
118 Span::raw("Masked text: "),
119 Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
120 ]),
121 Line::from("This is a line "),
122 Line::from("This is a line ".red()),
123 Line::from("This is a line".on_dark_gray()),
124 Line::from("This is a longer line".crossed_out()),
125 Line::from(long_line.clone()),
126 Line::from("This is a line".reset()),
127 Line::from(vec![
128 Span::raw("Masked text: "),
129 Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
130 ]),
131 ];
132 self.vertical_scroll_state = self.vertical_scroll_state.content_length(text.len());
133 self.horizontal_scroll_state = self.horizontal_scroll_state.content_length(long_line.len());
134
135 let create_block = |title: &'static str| Block::bordered().gray().title(title.bold());
136
137 let title = Block::new()
138 .title_alignment(Alignment::Center)
139 .title("Use h j k l or ◄ ▲ ▼ ► to scroll ".bold());
140 frame.render_widget(title, chunks[0]);
141
142 let paragraph = Paragraph::new(text.clone())
143 .gray()
144 .block(create_block("Vertical scrollbar with arrows"))
145 .scroll((self.vertical_scroll as u16, 0));
146 frame.render_widget(paragraph, chunks[1]);
147 frame.render_stateful_widget(
148 Scrollbar::new(ScrollbarOrientation::VerticalRight)
149 .begin_symbol(Some("↑"))
150 .end_symbol(Some("↓")),
151 chunks[1],
152 &mut self.vertical_scroll_state,
153 );
154
155 let paragraph = Paragraph::new(text.clone())
156 .gray()
157 .block(create_block(
158 "Vertical scrollbar without arrows, without track symbol and mirrored",
159 ))
160 .scroll((self.vertical_scroll as u16, 0));
161 frame.render_widget(paragraph, chunks[2]);
162 frame.render_stateful_widget(
163 Scrollbar::new(ScrollbarOrientation::VerticalLeft)
164 .symbols(scrollbar::VERTICAL)
165 .begin_symbol(None)
166 .track_symbol(None)
167 .end_symbol(None),
168 chunks[2].inner(Margin {
169 vertical: 1,
170 horizontal: 0,
171 }),
172 &mut self.vertical_scroll_state,
173 );
174
175 let paragraph = Paragraph::new(text.clone())
176 .gray()
177 .block(create_block(
178 "Horizontal scrollbar with only begin arrow & custom thumb symbol",
179 ))
180 .scroll((0, self.horizontal_scroll as u16));
181 frame.render_widget(paragraph, chunks[3]);
182 frame.render_stateful_widget(
183 Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
184 .thumb_symbol("🬋")
185 .end_symbol(None),
186 chunks[3].inner(Margin {
187 vertical: 0,
188 horizontal: 1,
189 }),
190 &mut self.horizontal_scroll_state,
191 );
192
193 let paragraph = Paragraph::new(text.clone())
194 .gray()
195 .block(create_block(
196 "Horizontal scrollbar without arrows & custom thumb and track symbol",
197 ))
198 .scroll((0, self.horizontal_scroll as u16));
199 frame.render_widget(paragraph, chunks[4]);
200 frame.render_stateful_widget(
201 Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
202 .thumb_symbol("░")
203 .track_symbol(Some("─")),
204 chunks[4].inner(Margin {
205 vertical: 0,
206 horizontal: 1,
207 }),
208 &mut self.horizontal_scroll_state,
209 );
210 }
Sourcepub const fn orientation(self, orientation: ScrollbarOrientation) -> Self
pub const fn orientation(self, orientation: ScrollbarOrientation) -> Self
Sets the position of the scrollbar.
The orientation of the scrollbar is the position it will take around a Rect
. See
ScrollbarOrientation
for more details.
Resets the symbols to DOUBLE_VERTICAL
or DOUBLE_HORIZONTAL
based on orientation.
This is a fluent setter method which must be chained or used as it consumes self
Examples found in repository?
269 fn render_scrollbar(&mut self, frame: &mut Frame, area: Rect) {
270 frame.render_stateful_widget(
271 Scrollbar::default()
272 .orientation(ScrollbarOrientation::VerticalRight)
273 .begin_symbol(None)
274 .end_symbol(None),
275 area.inner(Margin {
276 vertical: 1,
277 horizontal: 1,
278 }),
279 &mut self.scroll_state,
280 );
281 }
More examples
53fn render_hops(selected_row: usize, area: Rect, buf: &mut Buffer) {
54 let mut state = TableState::default().with_selected(Some(selected_row));
55 let rows = HOPS.iter().map(|hop| Row::new(vec![hop.host, hop.address]));
56 let block = Block::new()
57 .padding(Padding::new(1, 1, 1, 1))
58 .title_alignment(Alignment::Center)
59 .title("Traceroute bad.horse".bold().white());
60 StatefulWidget::render(
61 Table::new(rows, [Constraint::Max(100), Constraint::Length(15)])
62 .header(Row::new(vec!["Host", "Address"]).set_style(THEME.traceroute.header))
63 .row_highlight_style(THEME.traceroute.selected)
64 .block(block),
65 area,
66 buf,
67 &mut state,
68 );
69 let mut scrollbar_state = ScrollbarState::default()
70 .content_length(HOPS.len())
71 .position(selected_row);
72 let area = Rect {
73 width: area.width + 1,
74 y: area.y + 3,
75 height: area.height - 4,
76 ..area
77 };
78 Scrollbar::default()
79 .orientation(ScrollbarOrientation::VerticalLeft)
80 .begin_symbol(None)
81 .end_symbol(None)
82 .track_symbol(None)
83 .thumb_symbol("▌")
84 .render(area, buf, &mut scrollbar_state);
85}
Sourcepub const fn orientation_and_symbol(
self,
orientation: ScrollbarOrientation,
symbols: Set,
) -> Self
pub const fn orientation_and_symbol( self, orientation: ScrollbarOrientation, symbols: Set, ) -> Self
Sets the orientation and symbols for the scrollbar from a Set
.
This has the same effect as calling Scrollbar::orientation
and then
Scrollbar::symbols
. See those for more details.
This is a fluent setter method which must be chained or used as it consumes self
Sourcepub const fn thumb_symbol(self, thumb_symbol: &'a str) -> Self
pub const fn thumb_symbol(self, thumb_symbol: &'a str) -> Self
Sets the symbol that represents the thumb of the scrollbar.
The thumb is the handle representing the progression on the scrollbar. See Scrollbar
for a visual example of what this represents.
This is a fluent setter method which must be chained or used as it consumes self
Examples found in repository?
174fn render_scrollbar(position: usize, area: Rect, buf: &mut Buffer) {
175 let mut state = ScrollbarState::default()
176 .content_length(INGREDIENTS.len())
177 .viewport_content_length(6)
178 .position(position);
179 Scrollbar::new(ScrollbarOrientation::VerticalRight)
180 .begin_symbol(None)
181 .end_symbol(None)
182 .track_symbol(None)
183 .thumb_symbol("▐")
184 .render(area, buf, &mut state);
185}
More examples
53fn render_hops(selected_row: usize, area: Rect, buf: &mut Buffer) {
54 let mut state = TableState::default().with_selected(Some(selected_row));
55 let rows = HOPS.iter().map(|hop| Row::new(vec![hop.host, hop.address]));
56 let block = Block::new()
57 .padding(Padding::new(1, 1, 1, 1))
58 .title_alignment(Alignment::Center)
59 .title("Traceroute bad.horse".bold().white());
60 StatefulWidget::render(
61 Table::new(rows, [Constraint::Max(100), Constraint::Length(15)])
62 .header(Row::new(vec!["Host", "Address"]).set_style(THEME.traceroute.header))
63 .row_highlight_style(THEME.traceroute.selected)
64 .block(block),
65 area,
66 buf,
67 &mut state,
68 );
69 let mut scrollbar_state = ScrollbarState::default()
70 .content_length(HOPS.len())
71 .position(selected_row);
72 let area = Rect {
73 width: area.width + 1,
74 y: area.y + 3,
75 height: area.height - 4,
76 ..area
77 };
78 Scrollbar::default()
79 .orientation(ScrollbarOrientation::VerticalLeft)
80 .begin_symbol(None)
81 .end_symbol(None)
82 .track_symbol(None)
83 .thumb_symbol("▌")
84 .render(area, buf, &mut scrollbar_state);
85}
82fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
83 let vertical = Layout::vertical([Constraint::Length(1), Constraint::Min(0)]);
84 let [tabs, inbox] = vertical.areas(area);
85 let theme = THEME.email;
86 Tabs::new(vec![" Inbox ", " Sent ", " Drafts "])
87 .style(theme.tabs)
88 .highlight_style(theme.tabs_selected)
89 .select(0)
90 .divider("")
91 .render(tabs, buf);
92
93 let highlight_symbol = ">>";
94 let from_width = EMAILS
95 .iter()
96 .map(|e| e.from.width())
97 .max()
98 .unwrap_or_default();
99 let items = EMAILS.iter().map(|e| {
100 let from = format!("{:width$}", e.from, width = from_width).into();
101 ListItem::new(Line::from(vec![from, " ".into(), e.subject.into()]))
102 });
103 let mut state = ListState::default().with_selected(Some(selected_index));
104 StatefulWidget::render(
105 List::new(items)
106 .style(theme.inbox)
107 .highlight_style(theme.selected_item)
108 .highlight_symbol(highlight_symbol),
109 inbox,
110 buf,
111 &mut state,
112 );
113 let mut scrollbar_state = ScrollbarState::default()
114 .content_length(EMAILS.len())
115 .position(selected_index);
116 Scrollbar::default()
117 .begin_symbol(None)
118 .end_symbol(None)
119 .track_symbol(None)
120 .thumb_symbol("▐")
121 .render(inbox, buf, &mut scrollbar_state);
122}
92 fn draw(&mut self, frame: &mut Frame) {
93 let area = frame.area();
94
95 // Words made "loooong" to demonstrate line breaking.
96 let s =
97 "Veeeeeeeeeeeeeeeery loooooooooooooooooong striiiiiiiiiiiiiiiiiiiiiiiiiing. ";
98 let mut long_line = s.repeat(usize::from(area.width) / s.len() + 4);
99 long_line.push('\n');
100
101 let chunks = Layout::vertical([
102 Constraint::Min(1),
103 Constraint::Percentage(25),
104 Constraint::Percentage(25),
105 Constraint::Percentage(25),
106 Constraint::Percentage(25),
107 ])
108 .split(area);
109
110 let text = vec![
111 Line::from("This is a line "),
112 Line::from("This is a line ".red()),
113 Line::from("This is a line".on_dark_gray()),
114 Line::from("This is a longer line".crossed_out()),
115 Line::from(long_line.clone()),
116 Line::from("This is a line".reset()),
117 Line::from(vec![
118 Span::raw("Masked text: "),
119 Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
120 ]),
121 Line::from("This is a line "),
122 Line::from("This is a line ".red()),
123 Line::from("This is a line".on_dark_gray()),
124 Line::from("This is a longer line".crossed_out()),
125 Line::from(long_line.clone()),
126 Line::from("This is a line".reset()),
127 Line::from(vec![
128 Span::raw("Masked text: "),
129 Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
130 ]),
131 ];
132 self.vertical_scroll_state = self.vertical_scroll_state.content_length(text.len());
133 self.horizontal_scroll_state = self.horizontal_scroll_state.content_length(long_line.len());
134
135 let create_block = |title: &'static str| Block::bordered().gray().title(title.bold());
136
137 let title = Block::new()
138 .title_alignment(Alignment::Center)
139 .title("Use h j k l or ◄ ▲ ▼ ► to scroll ".bold());
140 frame.render_widget(title, chunks[0]);
141
142 let paragraph = Paragraph::new(text.clone())
143 .gray()
144 .block(create_block("Vertical scrollbar with arrows"))
145 .scroll((self.vertical_scroll as u16, 0));
146 frame.render_widget(paragraph, chunks[1]);
147 frame.render_stateful_widget(
148 Scrollbar::new(ScrollbarOrientation::VerticalRight)
149 .begin_symbol(Some("↑"))
150 .end_symbol(Some("↓")),
151 chunks[1],
152 &mut self.vertical_scroll_state,
153 );
154
155 let paragraph = Paragraph::new(text.clone())
156 .gray()
157 .block(create_block(
158 "Vertical scrollbar without arrows, without track symbol and mirrored",
159 ))
160 .scroll((self.vertical_scroll as u16, 0));
161 frame.render_widget(paragraph, chunks[2]);
162 frame.render_stateful_widget(
163 Scrollbar::new(ScrollbarOrientation::VerticalLeft)
164 .symbols(scrollbar::VERTICAL)
165 .begin_symbol(None)
166 .track_symbol(None)
167 .end_symbol(None),
168 chunks[2].inner(Margin {
169 vertical: 1,
170 horizontal: 0,
171 }),
172 &mut self.vertical_scroll_state,
173 );
174
175 let paragraph = Paragraph::new(text.clone())
176 .gray()
177 .block(create_block(
178 "Horizontal scrollbar with only begin arrow & custom thumb symbol",
179 ))
180 .scroll((0, self.horizontal_scroll as u16));
181 frame.render_widget(paragraph, chunks[3]);
182 frame.render_stateful_widget(
183 Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
184 .thumb_symbol("🬋")
185 .end_symbol(None),
186 chunks[3].inner(Margin {
187 vertical: 0,
188 horizontal: 1,
189 }),
190 &mut self.horizontal_scroll_state,
191 );
192
193 let paragraph = Paragraph::new(text.clone())
194 .gray()
195 .block(create_block(
196 "Horizontal scrollbar without arrows & custom thumb and track symbol",
197 ))
198 .scroll((0, self.horizontal_scroll as u16));
199 frame.render_widget(paragraph, chunks[4]);
200 frame.render_stateful_widget(
201 Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
202 .thumb_symbol("░")
203 .track_symbol(Some("─")),
204 chunks[4].inner(Margin {
205 vertical: 0,
206 horizontal: 1,
207 }),
208 &mut self.horizontal_scroll_state,
209 );
210 }
Sourcepub fn thumb_style<S: Into<Style>>(self, thumb_style: S) -> Self
pub fn thumb_style<S: Into<Style>>(self, thumb_style: S) -> Self
Sets the style on the scrollbar thumb.
The thumb is the handle representing the progression on the scrollbar. See Scrollbar
for a visual example of what this represents.
style
accepts any type that is convertible to Style
(e.g. Style
, Color
, or
your own type that implements Into<Style>
).
This is a fluent setter method which must be chained or used as it consumes self
Sourcepub const fn track_symbol(self, track_symbol: Option<&'a str>) -> Self
pub const fn track_symbol(self, track_symbol: Option<&'a str>) -> Self
Sets the symbol that represents the track of the scrollbar.
See Scrollbar
for a visual example of what this represents.
This is a fluent setter method which must be chained or used as it consumes self
Examples found in repository?
174fn render_scrollbar(position: usize, area: Rect, buf: &mut Buffer) {
175 let mut state = ScrollbarState::default()
176 .content_length(INGREDIENTS.len())
177 .viewport_content_length(6)
178 .position(position);
179 Scrollbar::new(ScrollbarOrientation::VerticalRight)
180 .begin_symbol(None)
181 .end_symbol(None)
182 .track_symbol(None)
183 .thumb_symbol("▐")
184 .render(area, buf, &mut state);
185}
More examples
53fn render_hops(selected_row: usize, area: Rect, buf: &mut Buffer) {
54 let mut state = TableState::default().with_selected(Some(selected_row));
55 let rows = HOPS.iter().map(|hop| Row::new(vec![hop.host, hop.address]));
56 let block = Block::new()
57 .padding(Padding::new(1, 1, 1, 1))
58 .title_alignment(Alignment::Center)
59 .title("Traceroute bad.horse".bold().white());
60 StatefulWidget::render(
61 Table::new(rows, [Constraint::Max(100), Constraint::Length(15)])
62 .header(Row::new(vec!["Host", "Address"]).set_style(THEME.traceroute.header))
63 .row_highlight_style(THEME.traceroute.selected)
64 .block(block),
65 area,
66 buf,
67 &mut state,
68 );
69 let mut scrollbar_state = ScrollbarState::default()
70 .content_length(HOPS.len())
71 .position(selected_row);
72 let area = Rect {
73 width: area.width + 1,
74 y: area.y + 3,
75 height: area.height - 4,
76 ..area
77 };
78 Scrollbar::default()
79 .orientation(ScrollbarOrientation::VerticalLeft)
80 .begin_symbol(None)
81 .end_symbol(None)
82 .track_symbol(None)
83 .thumb_symbol("▌")
84 .render(area, buf, &mut scrollbar_state);
85}
82fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
83 let vertical = Layout::vertical([Constraint::Length(1), Constraint::Min(0)]);
84 let [tabs, inbox] = vertical.areas(area);
85 let theme = THEME.email;
86 Tabs::new(vec![" Inbox ", " Sent ", " Drafts "])
87 .style(theme.tabs)
88 .highlight_style(theme.tabs_selected)
89 .select(0)
90 .divider("")
91 .render(tabs, buf);
92
93 let highlight_symbol = ">>";
94 let from_width = EMAILS
95 .iter()
96 .map(|e| e.from.width())
97 .max()
98 .unwrap_or_default();
99 let items = EMAILS.iter().map(|e| {
100 let from = format!("{:width$}", e.from, width = from_width).into();
101 ListItem::new(Line::from(vec![from, " ".into(), e.subject.into()]))
102 });
103 let mut state = ListState::default().with_selected(Some(selected_index));
104 StatefulWidget::render(
105 List::new(items)
106 .style(theme.inbox)
107 .highlight_style(theme.selected_item)
108 .highlight_symbol(highlight_symbol),
109 inbox,
110 buf,
111 &mut state,
112 );
113 let mut scrollbar_state = ScrollbarState::default()
114 .content_length(EMAILS.len())
115 .position(selected_index);
116 Scrollbar::default()
117 .begin_symbol(None)
118 .end_symbol(None)
119 .track_symbol(None)
120 .thumb_symbol("▐")
121 .render(inbox, buf, &mut scrollbar_state);
122}
92 fn draw(&mut self, frame: &mut Frame) {
93 let area = frame.area();
94
95 // Words made "loooong" to demonstrate line breaking.
96 let s =
97 "Veeeeeeeeeeeeeeeery loooooooooooooooooong striiiiiiiiiiiiiiiiiiiiiiiiiing. ";
98 let mut long_line = s.repeat(usize::from(area.width) / s.len() + 4);
99 long_line.push('\n');
100
101 let chunks = Layout::vertical([
102 Constraint::Min(1),
103 Constraint::Percentage(25),
104 Constraint::Percentage(25),
105 Constraint::Percentage(25),
106 Constraint::Percentage(25),
107 ])
108 .split(area);
109
110 let text = vec![
111 Line::from("This is a line "),
112 Line::from("This is a line ".red()),
113 Line::from("This is a line".on_dark_gray()),
114 Line::from("This is a longer line".crossed_out()),
115 Line::from(long_line.clone()),
116 Line::from("This is a line".reset()),
117 Line::from(vec![
118 Span::raw("Masked text: "),
119 Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
120 ]),
121 Line::from("This is a line "),
122 Line::from("This is a line ".red()),
123 Line::from("This is a line".on_dark_gray()),
124 Line::from("This is a longer line".crossed_out()),
125 Line::from(long_line.clone()),
126 Line::from("This is a line".reset()),
127 Line::from(vec![
128 Span::raw("Masked text: "),
129 Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
130 ]),
131 ];
132 self.vertical_scroll_state = self.vertical_scroll_state.content_length(text.len());
133 self.horizontal_scroll_state = self.horizontal_scroll_state.content_length(long_line.len());
134
135 let create_block = |title: &'static str| Block::bordered().gray().title(title.bold());
136
137 let title = Block::new()
138 .title_alignment(Alignment::Center)
139 .title("Use h j k l or ◄ ▲ ▼ ► to scroll ".bold());
140 frame.render_widget(title, chunks[0]);
141
142 let paragraph = Paragraph::new(text.clone())
143 .gray()
144 .block(create_block("Vertical scrollbar with arrows"))
145 .scroll((self.vertical_scroll as u16, 0));
146 frame.render_widget(paragraph, chunks[1]);
147 frame.render_stateful_widget(
148 Scrollbar::new(ScrollbarOrientation::VerticalRight)
149 .begin_symbol(Some("↑"))
150 .end_symbol(Some("↓")),
151 chunks[1],
152 &mut self.vertical_scroll_state,
153 );
154
155 let paragraph = Paragraph::new(text.clone())
156 .gray()
157 .block(create_block(
158 "Vertical scrollbar without arrows, without track symbol and mirrored",
159 ))
160 .scroll((self.vertical_scroll as u16, 0));
161 frame.render_widget(paragraph, chunks[2]);
162 frame.render_stateful_widget(
163 Scrollbar::new(ScrollbarOrientation::VerticalLeft)
164 .symbols(scrollbar::VERTICAL)
165 .begin_symbol(None)
166 .track_symbol(None)
167 .end_symbol(None),
168 chunks[2].inner(Margin {
169 vertical: 1,
170 horizontal: 0,
171 }),
172 &mut self.vertical_scroll_state,
173 );
174
175 let paragraph = Paragraph::new(text.clone())
176 .gray()
177 .block(create_block(
178 "Horizontal scrollbar with only begin arrow & custom thumb symbol",
179 ))
180 .scroll((0, self.horizontal_scroll as u16));
181 frame.render_widget(paragraph, chunks[3]);
182 frame.render_stateful_widget(
183 Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
184 .thumb_symbol("🬋")
185 .end_symbol(None),
186 chunks[3].inner(Margin {
187 vertical: 0,
188 horizontal: 1,
189 }),
190 &mut self.horizontal_scroll_state,
191 );
192
193 let paragraph = Paragraph::new(text.clone())
194 .gray()
195 .block(create_block(
196 "Horizontal scrollbar without arrows & custom thumb and track symbol",
197 ))
198 .scroll((0, self.horizontal_scroll as u16));
199 frame.render_widget(paragraph, chunks[4]);
200 frame.render_stateful_widget(
201 Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
202 .thumb_symbol("░")
203 .track_symbol(Some("─")),
204 chunks[4].inner(Margin {
205 vertical: 0,
206 horizontal: 1,
207 }),
208 &mut self.horizontal_scroll_state,
209 );
210 }
Sourcepub fn track_style<S: Into<Style>>(self, track_style: S) -> Self
pub fn track_style<S: Into<Style>>(self, track_style: S) -> Self
Sets the style that is used for the track of the scrollbar.
See Scrollbar
for a visual example of what this represents.
style
accepts any type that is convertible to Style
(e.g. Style
, Color
, or
your own type that implements Into<Style>
).
This is a fluent setter method which must be chained or used as it consumes self
Sourcepub const fn begin_symbol(self, begin_symbol: Option<&'a str>) -> Self
pub const fn begin_symbol(self, begin_symbol: Option<&'a str>) -> Self
Sets the symbol that represents the beginning of the scrollbar.
See Scrollbar
for a visual example of what this represents.
This is a fluent setter method which must be chained or used as it consumes self
Examples found in repository?
174fn render_scrollbar(position: usize, area: Rect, buf: &mut Buffer) {
175 let mut state = ScrollbarState::default()
176 .content_length(INGREDIENTS.len())
177 .viewport_content_length(6)
178 .position(position);
179 Scrollbar::new(ScrollbarOrientation::VerticalRight)
180 .begin_symbol(None)
181 .end_symbol(None)
182 .track_symbol(None)
183 .thumb_symbol("▐")
184 .render(area, buf, &mut state);
185}
More examples
269 fn render_scrollbar(&mut self, frame: &mut Frame, area: Rect) {
270 frame.render_stateful_widget(
271 Scrollbar::default()
272 .orientation(ScrollbarOrientation::VerticalRight)
273 .begin_symbol(None)
274 .end_symbol(None),
275 area.inner(Margin {
276 vertical: 1,
277 horizontal: 1,
278 }),
279 &mut self.scroll_state,
280 );
281 }
53fn render_hops(selected_row: usize, area: Rect, buf: &mut Buffer) {
54 let mut state = TableState::default().with_selected(Some(selected_row));
55 let rows = HOPS.iter().map(|hop| Row::new(vec![hop.host, hop.address]));
56 let block = Block::new()
57 .padding(Padding::new(1, 1, 1, 1))
58 .title_alignment(Alignment::Center)
59 .title("Traceroute bad.horse".bold().white());
60 StatefulWidget::render(
61 Table::new(rows, [Constraint::Max(100), Constraint::Length(15)])
62 .header(Row::new(vec!["Host", "Address"]).set_style(THEME.traceroute.header))
63 .row_highlight_style(THEME.traceroute.selected)
64 .block(block),
65 area,
66 buf,
67 &mut state,
68 );
69 let mut scrollbar_state = ScrollbarState::default()
70 .content_length(HOPS.len())
71 .position(selected_row);
72 let area = Rect {
73 width: area.width + 1,
74 y: area.y + 3,
75 height: area.height - 4,
76 ..area
77 };
78 Scrollbar::default()
79 .orientation(ScrollbarOrientation::VerticalLeft)
80 .begin_symbol(None)
81 .end_symbol(None)
82 .track_symbol(None)
83 .thumb_symbol("▌")
84 .render(area, buf, &mut scrollbar_state);
85}
82fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
83 let vertical = Layout::vertical([Constraint::Length(1), Constraint::Min(0)]);
84 let [tabs, inbox] = vertical.areas(area);
85 let theme = THEME.email;
86 Tabs::new(vec![" Inbox ", " Sent ", " Drafts "])
87 .style(theme.tabs)
88 .highlight_style(theme.tabs_selected)
89 .select(0)
90 .divider("")
91 .render(tabs, buf);
92
93 let highlight_symbol = ">>";
94 let from_width = EMAILS
95 .iter()
96 .map(|e| e.from.width())
97 .max()
98 .unwrap_or_default();
99 let items = EMAILS.iter().map(|e| {
100 let from = format!("{:width$}", e.from, width = from_width).into();
101 ListItem::new(Line::from(vec![from, " ".into(), e.subject.into()]))
102 });
103 let mut state = ListState::default().with_selected(Some(selected_index));
104 StatefulWidget::render(
105 List::new(items)
106 .style(theme.inbox)
107 .highlight_style(theme.selected_item)
108 .highlight_symbol(highlight_symbol),
109 inbox,
110 buf,
111 &mut state,
112 );
113 let mut scrollbar_state = ScrollbarState::default()
114 .content_length(EMAILS.len())
115 .position(selected_index);
116 Scrollbar::default()
117 .begin_symbol(None)
118 .end_symbol(None)
119 .track_symbol(None)
120 .thumb_symbol("▐")
121 .render(inbox, buf, &mut scrollbar_state);
122}
92 fn draw(&mut self, frame: &mut Frame) {
93 let area = frame.area();
94
95 // Words made "loooong" to demonstrate line breaking.
96 let s =
97 "Veeeeeeeeeeeeeeeery loooooooooooooooooong striiiiiiiiiiiiiiiiiiiiiiiiiing. ";
98 let mut long_line = s.repeat(usize::from(area.width) / s.len() + 4);
99 long_line.push('\n');
100
101 let chunks = Layout::vertical([
102 Constraint::Min(1),
103 Constraint::Percentage(25),
104 Constraint::Percentage(25),
105 Constraint::Percentage(25),
106 Constraint::Percentage(25),
107 ])
108 .split(area);
109
110 let text = vec![
111 Line::from("This is a line "),
112 Line::from("This is a line ".red()),
113 Line::from("This is a line".on_dark_gray()),
114 Line::from("This is a longer line".crossed_out()),
115 Line::from(long_line.clone()),
116 Line::from("This is a line".reset()),
117 Line::from(vec![
118 Span::raw("Masked text: "),
119 Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
120 ]),
121 Line::from("This is a line "),
122 Line::from("This is a line ".red()),
123 Line::from("This is a line".on_dark_gray()),
124 Line::from("This is a longer line".crossed_out()),
125 Line::from(long_line.clone()),
126 Line::from("This is a line".reset()),
127 Line::from(vec![
128 Span::raw("Masked text: "),
129 Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
130 ]),
131 ];
132 self.vertical_scroll_state = self.vertical_scroll_state.content_length(text.len());
133 self.horizontal_scroll_state = self.horizontal_scroll_state.content_length(long_line.len());
134
135 let create_block = |title: &'static str| Block::bordered().gray().title(title.bold());
136
137 let title = Block::new()
138 .title_alignment(Alignment::Center)
139 .title("Use h j k l or ◄ ▲ ▼ ► to scroll ".bold());
140 frame.render_widget(title, chunks[0]);
141
142 let paragraph = Paragraph::new(text.clone())
143 .gray()
144 .block(create_block("Vertical scrollbar with arrows"))
145 .scroll((self.vertical_scroll as u16, 0));
146 frame.render_widget(paragraph, chunks[1]);
147 frame.render_stateful_widget(
148 Scrollbar::new(ScrollbarOrientation::VerticalRight)
149 .begin_symbol(Some("↑"))
150 .end_symbol(Some("↓")),
151 chunks[1],
152 &mut self.vertical_scroll_state,
153 );
154
155 let paragraph = Paragraph::new(text.clone())
156 .gray()
157 .block(create_block(
158 "Vertical scrollbar without arrows, without track symbol and mirrored",
159 ))
160 .scroll((self.vertical_scroll as u16, 0));
161 frame.render_widget(paragraph, chunks[2]);
162 frame.render_stateful_widget(
163 Scrollbar::new(ScrollbarOrientation::VerticalLeft)
164 .symbols(scrollbar::VERTICAL)
165 .begin_symbol(None)
166 .track_symbol(None)
167 .end_symbol(None),
168 chunks[2].inner(Margin {
169 vertical: 1,
170 horizontal: 0,
171 }),
172 &mut self.vertical_scroll_state,
173 );
174
175 let paragraph = Paragraph::new(text.clone())
176 .gray()
177 .block(create_block(
178 "Horizontal scrollbar with only begin arrow & custom thumb symbol",
179 ))
180 .scroll((0, self.horizontal_scroll as u16));
181 frame.render_widget(paragraph, chunks[3]);
182 frame.render_stateful_widget(
183 Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
184 .thumb_symbol("🬋")
185 .end_symbol(None),
186 chunks[3].inner(Margin {
187 vertical: 0,
188 horizontal: 1,
189 }),
190 &mut self.horizontal_scroll_state,
191 );
192
193 let paragraph = Paragraph::new(text.clone())
194 .gray()
195 .block(create_block(
196 "Horizontal scrollbar without arrows & custom thumb and track symbol",
197 ))
198 .scroll((0, self.horizontal_scroll as u16));
199 frame.render_widget(paragraph, chunks[4]);
200 frame.render_stateful_widget(
201 Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
202 .thumb_symbol("░")
203 .track_symbol(Some("─")),
204 chunks[4].inner(Margin {
205 vertical: 0,
206 horizontal: 1,
207 }),
208 &mut self.horizontal_scroll_state,
209 );
210 }
Sourcepub fn begin_style<S: Into<Style>>(self, begin_style: S) -> Self
pub fn begin_style<S: Into<Style>>(self, begin_style: S) -> Self
Sets the style that is used for the beginning of the scrollbar.
See Scrollbar
for a visual example of what this represents.
style
accepts any type that is convertible to Style
(e.g. Style
, Color
, or
your own type that implements Into<Style>
).
This is a fluent setter method which must be chained or used as it consumes self
Sourcepub const fn end_symbol(self, end_symbol: Option<&'a str>) -> Self
pub const fn end_symbol(self, end_symbol: Option<&'a str>) -> Self
Sets the symbol that represents the end of the scrollbar.
See Scrollbar
for a visual example of what this represents.
This is a fluent setter method which must be chained or used as it consumes self
Examples found in repository?
174fn render_scrollbar(position: usize, area: Rect, buf: &mut Buffer) {
175 let mut state = ScrollbarState::default()
176 .content_length(INGREDIENTS.len())
177 .viewport_content_length(6)
178 .position(position);
179 Scrollbar::new(ScrollbarOrientation::VerticalRight)
180 .begin_symbol(None)
181 .end_symbol(None)
182 .track_symbol(None)
183 .thumb_symbol("▐")
184 .render(area, buf, &mut state);
185}
More examples
269 fn render_scrollbar(&mut self, frame: &mut Frame, area: Rect) {
270 frame.render_stateful_widget(
271 Scrollbar::default()
272 .orientation(ScrollbarOrientation::VerticalRight)
273 .begin_symbol(None)
274 .end_symbol(None),
275 area.inner(Margin {
276 vertical: 1,
277 horizontal: 1,
278 }),
279 &mut self.scroll_state,
280 );
281 }
53fn render_hops(selected_row: usize, area: Rect, buf: &mut Buffer) {
54 let mut state = TableState::default().with_selected(Some(selected_row));
55 let rows = HOPS.iter().map(|hop| Row::new(vec![hop.host, hop.address]));
56 let block = Block::new()
57 .padding(Padding::new(1, 1, 1, 1))
58 .title_alignment(Alignment::Center)
59 .title("Traceroute bad.horse".bold().white());
60 StatefulWidget::render(
61 Table::new(rows, [Constraint::Max(100), Constraint::Length(15)])
62 .header(Row::new(vec!["Host", "Address"]).set_style(THEME.traceroute.header))
63 .row_highlight_style(THEME.traceroute.selected)
64 .block(block),
65 area,
66 buf,
67 &mut state,
68 );
69 let mut scrollbar_state = ScrollbarState::default()
70 .content_length(HOPS.len())
71 .position(selected_row);
72 let area = Rect {
73 width: area.width + 1,
74 y: area.y + 3,
75 height: area.height - 4,
76 ..area
77 };
78 Scrollbar::default()
79 .orientation(ScrollbarOrientation::VerticalLeft)
80 .begin_symbol(None)
81 .end_symbol(None)
82 .track_symbol(None)
83 .thumb_symbol("▌")
84 .render(area, buf, &mut scrollbar_state);
85}
82fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
83 let vertical = Layout::vertical([Constraint::Length(1), Constraint::Min(0)]);
84 let [tabs, inbox] = vertical.areas(area);
85 let theme = THEME.email;
86 Tabs::new(vec![" Inbox ", " Sent ", " Drafts "])
87 .style(theme.tabs)
88 .highlight_style(theme.tabs_selected)
89 .select(0)
90 .divider("")
91 .render(tabs, buf);
92
93 let highlight_symbol = ">>";
94 let from_width = EMAILS
95 .iter()
96 .map(|e| e.from.width())
97 .max()
98 .unwrap_or_default();
99 let items = EMAILS.iter().map(|e| {
100 let from = format!("{:width$}", e.from, width = from_width).into();
101 ListItem::new(Line::from(vec![from, " ".into(), e.subject.into()]))
102 });
103 let mut state = ListState::default().with_selected(Some(selected_index));
104 StatefulWidget::render(
105 List::new(items)
106 .style(theme.inbox)
107 .highlight_style(theme.selected_item)
108 .highlight_symbol(highlight_symbol),
109 inbox,
110 buf,
111 &mut state,
112 );
113 let mut scrollbar_state = ScrollbarState::default()
114 .content_length(EMAILS.len())
115 .position(selected_index);
116 Scrollbar::default()
117 .begin_symbol(None)
118 .end_symbol(None)
119 .track_symbol(None)
120 .thumb_symbol("▐")
121 .render(inbox, buf, &mut scrollbar_state);
122}
92 fn draw(&mut self, frame: &mut Frame) {
93 let area = frame.area();
94
95 // Words made "loooong" to demonstrate line breaking.
96 let s =
97 "Veeeeeeeeeeeeeeeery loooooooooooooooooong striiiiiiiiiiiiiiiiiiiiiiiiiing. ";
98 let mut long_line = s.repeat(usize::from(area.width) / s.len() + 4);
99 long_line.push('\n');
100
101 let chunks = Layout::vertical([
102 Constraint::Min(1),
103 Constraint::Percentage(25),
104 Constraint::Percentage(25),
105 Constraint::Percentage(25),
106 Constraint::Percentage(25),
107 ])
108 .split(area);
109
110 let text = vec![
111 Line::from("This is a line "),
112 Line::from("This is a line ".red()),
113 Line::from("This is a line".on_dark_gray()),
114 Line::from("This is a longer line".crossed_out()),
115 Line::from(long_line.clone()),
116 Line::from("This is a line".reset()),
117 Line::from(vec![
118 Span::raw("Masked text: "),
119 Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
120 ]),
121 Line::from("This is a line "),
122 Line::from("This is a line ".red()),
123 Line::from("This is a line".on_dark_gray()),
124 Line::from("This is a longer line".crossed_out()),
125 Line::from(long_line.clone()),
126 Line::from("This is a line".reset()),
127 Line::from(vec![
128 Span::raw("Masked text: "),
129 Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
130 ]),
131 ];
132 self.vertical_scroll_state = self.vertical_scroll_state.content_length(text.len());
133 self.horizontal_scroll_state = self.horizontal_scroll_state.content_length(long_line.len());
134
135 let create_block = |title: &'static str| Block::bordered().gray().title(title.bold());
136
137 let title = Block::new()
138 .title_alignment(Alignment::Center)
139 .title("Use h j k l or ◄ ▲ ▼ ► to scroll ".bold());
140 frame.render_widget(title, chunks[0]);
141
142 let paragraph = Paragraph::new(text.clone())
143 .gray()
144 .block(create_block("Vertical scrollbar with arrows"))
145 .scroll((self.vertical_scroll as u16, 0));
146 frame.render_widget(paragraph, chunks[1]);
147 frame.render_stateful_widget(
148 Scrollbar::new(ScrollbarOrientation::VerticalRight)
149 .begin_symbol(Some("↑"))
150 .end_symbol(Some("↓")),
151 chunks[1],
152 &mut self.vertical_scroll_state,
153 );
154
155 let paragraph = Paragraph::new(text.clone())
156 .gray()
157 .block(create_block(
158 "Vertical scrollbar without arrows, without track symbol and mirrored",
159 ))
160 .scroll((self.vertical_scroll as u16, 0));
161 frame.render_widget(paragraph, chunks[2]);
162 frame.render_stateful_widget(
163 Scrollbar::new(ScrollbarOrientation::VerticalLeft)
164 .symbols(scrollbar::VERTICAL)
165 .begin_symbol(None)
166 .track_symbol(None)
167 .end_symbol(None),
168 chunks[2].inner(Margin {
169 vertical: 1,
170 horizontal: 0,
171 }),
172 &mut self.vertical_scroll_state,
173 );
174
175 let paragraph = Paragraph::new(text.clone())
176 .gray()
177 .block(create_block(
178 "Horizontal scrollbar with only begin arrow & custom thumb symbol",
179 ))
180 .scroll((0, self.horizontal_scroll as u16));
181 frame.render_widget(paragraph, chunks[3]);
182 frame.render_stateful_widget(
183 Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
184 .thumb_symbol("🬋")
185 .end_symbol(None),
186 chunks[3].inner(Margin {
187 vertical: 0,
188 horizontal: 1,
189 }),
190 &mut self.horizontal_scroll_state,
191 );
192
193 let paragraph = Paragraph::new(text.clone())
194 .gray()
195 .block(create_block(
196 "Horizontal scrollbar without arrows & custom thumb and track symbol",
197 ))
198 .scroll((0, self.horizontal_scroll as u16));
199 frame.render_widget(paragraph, chunks[4]);
200 frame.render_stateful_widget(
201 Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
202 .thumb_symbol("░")
203 .track_symbol(Some("─")),
204 chunks[4].inner(Margin {
205 vertical: 0,
206 horizontal: 1,
207 }),
208 &mut self.horizontal_scroll_state,
209 );
210 }
Sourcepub fn end_style<S: Into<Style>>(self, end_style: S) -> Self
pub fn end_style<S: Into<Style>>(self, end_style: S) -> Self
Sets the style that is used for the end of the scrollbar.
See Scrollbar
for a visual example of what this represents.
style
accepts any type that is convertible to Style
(e.g. Style
, Color
, or
your own type that implements Into<Style>
).
This is a fluent setter method which must be chained or used as it consumes self
Sourcepub const fn symbols(self, symbols: Set) -> Self
pub const fn symbols(self, symbols: Set) -> Self
Sets the symbols used for the various parts of the scrollbar from a Set
.
<--▮------->
^ ^ ^ ^
│ │ │ └ end
│ │ └──── track
│ └──────── thumb
└─────────── begin
Only sets begin_symbol
, end_symbol
and track_symbol
if they already contain a value.
If they were set to None
explicitly, this function will respect that choice. Use their
respective setters to change their value.
This is a fluent setter method which must be chained or used as it consumes self
Examples found in repository?
92 fn draw(&mut self, frame: &mut Frame) {
93 let area = frame.area();
94
95 // Words made "loooong" to demonstrate line breaking.
96 let s =
97 "Veeeeeeeeeeeeeeeery loooooooooooooooooong striiiiiiiiiiiiiiiiiiiiiiiiiing. ";
98 let mut long_line = s.repeat(usize::from(area.width) / s.len() + 4);
99 long_line.push('\n');
100
101 let chunks = Layout::vertical([
102 Constraint::Min(1),
103 Constraint::Percentage(25),
104 Constraint::Percentage(25),
105 Constraint::Percentage(25),
106 Constraint::Percentage(25),
107 ])
108 .split(area);
109
110 let text = vec![
111 Line::from("This is a line "),
112 Line::from("This is a line ".red()),
113 Line::from("This is a line".on_dark_gray()),
114 Line::from("This is a longer line".crossed_out()),
115 Line::from(long_line.clone()),
116 Line::from("This is a line".reset()),
117 Line::from(vec![
118 Span::raw("Masked text: "),
119 Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
120 ]),
121 Line::from("This is a line "),
122 Line::from("This is a line ".red()),
123 Line::from("This is a line".on_dark_gray()),
124 Line::from("This is a longer line".crossed_out()),
125 Line::from(long_line.clone()),
126 Line::from("This is a line".reset()),
127 Line::from(vec![
128 Span::raw("Masked text: "),
129 Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
130 ]),
131 ];
132 self.vertical_scroll_state = self.vertical_scroll_state.content_length(text.len());
133 self.horizontal_scroll_state = self.horizontal_scroll_state.content_length(long_line.len());
134
135 let create_block = |title: &'static str| Block::bordered().gray().title(title.bold());
136
137 let title = Block::new()
138 .title_alignment(Alignment::Center)
139 .title("Use h j k l or ◄ ▲ ▼ ► to scroll ".bold());
140 frame.render_widget(title, chunks[0]);
141
142 let paragraph = Paragraph::new(text.clone())
143 .gray()
144 .block(create_block("Vertical scrollbar with arrows"))
145 .scroll((self.vertical_scroll as u16, 0));
146 frame.render_widget(paragraph, chunks[1]);
147 frame.render_stateful_widget(
148 Scrollbar::new(ScrollbarOrientation::VerticalRight)
149 .begin_symbol(Some("↑"))
150 .end_symbol(Some("↓")),
151 chunks[1],
152 &mut self.vertical_scroll_state,
153 );
154
155 let paragraph = Paragraph::new(text.clone())
156 .gray()
157 .block(create_block(
158 "Vertical scrollbar without arrows, without track symbol and mirrored",
159 ))
160 .scroll((self.vertical_scroll as u16, 0));
161 frame.render_widget(paragraph, chunks[2]);
162 frame.render_stateful_widget(
163 Scrollbar::new(ScrollbarOrientation::VerticalLeft)
164 .symbols(scrollbar::VERTICAL)
165 .begin_symbol(None)
166 .track_symbol(None)
167 .end_symbol(None),
168 chunks[2].inner(Margin {
169 vertical: 1,
170 horizontal: 0,
171 }),
172 &mut self.vertical_scroll_state,
173 );
174
175 let paragraph = Paragraph::new(text.clone())
176 .gray()
177 .block(create_block(
178 "Horizontal scrollbar with only begin arrow & custom thumb symbol",
179 ))
180 .scroll((0, self.horizontal_scroll as u16));
181 frame.render_widget(paragraph, chunks[3]);
182 frame.render_stateful_widget(
183 Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
184 .thumb_symbol("🬋")
185 .end_symbol(None),
186 chunks[3].inner(Margin {
187 vertical: 0,
188 horizontal: 1,
189 }),
190 &mut self.horizontal_scroll_state,
191 );
192
193 let paragraph = Paragraph::new(text.clone())
194 .gray()
195 .block(create_block(
196 "Horizontal scrollbar without arrows & custom thumb and track symbol",
197 ))
198 .scroll((0, self.horizontal_scroll as u16));
199 frame.render_widget(paragraph, chunks[4]);
200 frame.render_stateful_widget(
201 Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
202 .thumb_symbol("░")
203 .track_symbol(Some("─")),
204 chunks[4].inner(Margin {
205 vertical: 0,
206 horizontal: 1,
207 }),
208 &mut self.horizontal_scroll_state,
209 );
210 }
Sourcepub fn style<S: Into<Style>>(self, style: S) -> Self
pub fn style<S: Into<Style>>(self, style: S) -> Self
Sets the style used for the various parts of the scrollbar from a Style
.
style
accepts any type that is convertible to Style
(e.g. Style
, Color
, or
your own type that implements Into<Style>
).
<--▮------->
^ ^ ^ ^
│ │ │ └ end
│ │ └──── track
│ └──────── thumb
└─────────── begin
This is a fluent setter method which must be chained or used as it consumes self
Trait Implementations§
Source§impl<'a> StatefulWidget for Scrollbar<'a>
impl<'a> StatefulWidget for Scrollbar<'a>
impl<'a> Eq for Scrollbar<'a>
impl<'a> StructuralPartialEq for Scrollbar<'a>
Auto Trait Implementations§
impl<'a> Freeze for Scrollbar<'a>
impl<'a> RefUnwindSafe for Scrollbar<'a>
impl<'a> Send for Scrollbar<'a>
impl<'a> Sync for Scrollbar<'a>
impl<'a> Unpin for Scrollbar<'a>
impl<'a> UnwindSafe for Scrollbar<'a>
Blanket Implementations§
Source§impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
Source§fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
Source§fn adapt_into(self) -> D
fn adapt_into(self) -> D
Source§impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
Source§fn arrays_from(colors: C) -> T
fn arrays_from(colors: C) -> T
Source§impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
Source§fn arrays_into(self) -> C
fn arrays_into(self) -> C
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
Source§type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
parameters
when converting.Source§fn cam16_into_unclamped(
self,
parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>,
) -> T
fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T
self
into C
, using the provided parameters.Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
Source§fn components_from(colors: C) -> T
fn components_from(colors: C) -> T
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.Source§impl<T> FromAngle<T> for T
impl<T> FromAngle<T> for T
Source§fn from_angle(angle: T) -> T
fn from_angle(angle: T) -> T
angle
.Source§impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
Source§fn from_stimulus(other: U) -> T
fn from_stimulus(other: U) -> T
other
into Self
, while performing the appropriate scaling,
rounding and clamping.Source§impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
Source§fn into_angle(self) -> U
fn into_angle(self) -> U
T
.Source§impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
Source§type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
parameters
when converting.Source§fn into_cam16_unclamped(
self,
parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>,
) -> T
fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T
self
into C
, using the provided parameters.Source§impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
Source§fn into_color(self) -> U
fn into_color(self) -> U
Source§impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
Source§fn into_color_unclamped(self) -> U
fn into_color_unclamped(self) -> U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoStimulus<T> for T
impl<T> IntoStimulus<T> for T
Source§fn into_stimulus(self) -> T
fn into_stimulus(self) -> T
self
into T
, while performing the appropriate scaling,
rounding and clamping.Source§impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
Source§type Error = <C as TryFromComponents<T>>::Error
type Error = <C as TryFromComponents<T>>::Error
try_into_colors
fails to cast.Source§fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
Source§impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
Source§fn try_into_color(self) -> Result<U, OutOfBounds<U>>
fn try_into_color(self) -> Result<U, OutOfBounds<U>>
OutOfBounds
error is returned which contains
the unclamped color. Read more