pub struct Block<'a> { /* private fields */ }
Expand description
Base widget to be used to display a box border around all upper level ones.
The borders can be configured with Block::borders
and others. A block can have multiple
Title
using Block::title
. It can also be styled and
padded.
You can call the title methods multiple times to add multiple titles. Each title will be rendered with a single space separating titles that are in the same position or alignment. When both centered and non-centered titles are rendered, the centered space is calculated based on the full width of the block, rather than the leftover width.
Titles are not rendered in the corners of the block unless there is no border on that edge. If the block is too small and multiple titles overlap, the border may get cut off at a corner.
┌With at least a left border───
Without left border───
§Constructor methods
Block::new
creates a newBlock
with no border or paddings.Block::bordered
Create a new block with all borders shown.
§Setter methods
These methods are fluent setters. They return a new Block
with the specified property set.
Block::borders
Defines which borders to display.Block::border_style
Defines the style of the borders.Block::border_type
Sets the symbols used to display the border (e.g. single line, double line, thick or rounded borders).Block::padding
Defines the padding inside aBlock
.Block::style
Sets the base style of the widget.Block::title
Adds a title to the block.Block::title_alignment
Sets the defaultAlignment
for all block titles.Block::title_style
Applies the style to all titles.Block::title_top
Adds a title to the top of the block.Block::title_bottom
Adds a title to the bottom of the block.Block::title_position
Adds a title to the block.
§Other Methods
Block::inner
Compute the inner area of a block based on its border visibility rules.
Style
s are applied first to the entire block, then to the borders, and finally to the
titles. If the block is used as a container for another widget, the inner widget can also be
styled. See Style
for more information on how merging styles works.
§Examples
use ratatui::{
style::{Color, Style},
widgets::{Block, BorderType, Borders},
};
Block::new()
.border_type(BorderType::Rounded)
.borders(Borders::LEFT | Borders::RIGHT)
.border_style(Style::default().fg(Color::White))
.style(Style::default().bg(Color::Black))
.title("Block");
You may also use multiple titles like in the following:
use ratatui::widgets::{
block::{Position, Title},
Block,
};
Block::new()
.title("Title 1")
.title(Title::from("Title 2").position(Position::Bottom));
You can also pass it as parameters of another widget so that the block surrounds them:
use ratatui::widgets::{Block, Borders, List};
let surrounding_block = Block::default()
.borders(Borders::ALL)
.title("Here is a list of items");
let items = ["Item 1", "Item 2", "Item 3"];
let list = List::new(items).block(surrounding_block);
Implementations§
Source§impl<'a> Block<'a>
impl<'a> Block<'a>
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Examples found in repository?
More examples
83fn vertical_barchart(temperatures: &[u8]) -> BarChart {
84 let bars: Vec<Bar> = temperatures
85 .iter()
86 .enumerate()
87 .map(|(hour, value)| vertical_bar(hour, value))
88 .collect();
89 let title = Line::from("Weather (Vertical)").centered();
90 BarChart::default()
91 .data(BarGroup::default().bars(&bars))
92 .block(Block::new().title(title))
93 .bar_width(5)
94}
95
96fn vertical_bar(hour: usize, temperature: &u8) -> Bar {
97 Bar::default()
98 .value(u64::from(*temperature))
99 .label(Line::from(format!("{hour:>02}:00")))
100 .text_value(format!("{temperature:>3}°"))
101 .style(temperature_style(*temperature))
102 .value_style(temperature_style(*temperature).reversed())
103}
104
105/// Create a horizontal bar chart from the temperatures data.
106fn horizontal_barchart(temperatures: &[u8]) -> BarChart {
107 let bars: Vec<Bar> = temperatures
108 .iter()
109 .enumerate()
110 .map(|(hour, value)| horizontal_bar(hour, value))
111 .collect();
112 let title = Line::from("Weather (Horizontal)").centered();
113 BarChart::default()
114 .block(Block::new().title(title))
115 .data(BarGroup::default().bars(&bars))
116 .bar_width(1)
117 .bar_gap(0)
118 .direction(Direction::Horizontal)
119}
420 fn render_1px(&self, area: Rect, buf: &mut Buffer) {
421 let lighter_color = ConstraintName::from(self.constraint).lighter_color();
422 let main_color = ConstraintName::from(self.constraint).color();
423 let selected_color = if self.selected {
424 lighter_color
425 } else {
426 main_color
427 };
428 Block::new()
429 .fg(Self::TEXT_COLOR)
430 .bg(selected_color)
431 .render(area, buf);
432 }
141 fn render(self, area: Rect, buf: &mut Buffer) {
142 let vertical = Layout::vertical([
143 Constraint::Length(1),
144 Constraint::Min(0),
145 Constraint::Length(1),
146 ]);
147 let [title_bar, tab, bottom_bar] = vertical.areas(area);
148
149 Block::new().style(THEME.root).render(area, buf);
150 self.render_title_bar(title_bar, buf);
151 self.render_selected_tab(tab, buf);
152 App::render_bottom_bar(bottom_bar, buf);
153 }
273 fn tabs(self) -> impl Widget {
274 let tab_titles = SelectedTab::iter().map(SelectedTab::to_tab_title);
275 let block = Block::new()
276 .title("Flex Layouts ".bold())
277 .title(" Use ◄ ► to change tab, ▲ ▼ to scroll, - + to change spacing ");
278 Tabs::new(tab_titles)
279 .block(block)
280 .highlight_style(Modifier::REVERSED)
281 .select(self.selected_tab as usize)
282 .divider(" ")
283 .padding("", "")
284 }
Sourcepub const fn bordered() -> Self
pub const fn bordered() -> Self
Create a new block with all borders shown
use ratatui::widgets::{Block, Borders};
assert_eq!(Block::bordered(), Block::new().borders(Borders::ALL));
Examples found in repository?
More examples
114fn render_border_type(
115 paragraph: &Paragraph,
116 border_type: BorderType,
117 frame: &mut Frame,
118 area: Rect,
119) {
120 let block = Block::bordered()
121 .border_type(border_type)
122 .title(format!("BorderType::{border_type:#?}"));
123 frame.render_widget(paragraph.clone().block(block), area);
124}
125fn render_styled_borders(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
126 let block = Block::bordered()
127 .border_style(Style::new().blue().on_white().bold().italic())
128 .title("Styled borders");
129 frame.render_widget(paragraph.clone().block(block), area);
130}
131
132fn render_styled_block(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
133 let block = Block::bordered()
134 .style(Style::new().blue().on_white().bold().italic())
135 .title("Styled block");
136 frame.render_widget(paragraph.clone().block(block), area);
137}
138
139fn render_styled_title(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
140 let block = Block::bordered()
141 .title("Styled title")
142 .title_style(Style::new().blue().on_white().bold().italic());
143 frame.render_widget(paragraph.clone().block(block), area);
144}
145
146fn render_styled_title_content(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
147 let title = Line::from(vec![
148 "Styled ".blue().on_white().bold().italic(),
149 "title content".red().on_white().bold().italic(),
150 ]);
151 let block = Block::bordered().title(title);
152 frame.render_widget(paragraph.clone().block(block), area);
153}
154
155fn render_multiple_titles(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
156 let block = Block::bordered()
157 .title("Multiple".blue().on_white().bold().italic())
158 .title("Titles".red().on_white().bold().italic());
159 frame.render_widget(paragraph.clone().block(block), area);
160}
161
162fn render_multiple_title_positions(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
163 let block = Block::bordered()
164 .title(Line::from("top left").left_aligned())
165 .title(Line::from("top center").centered())
166 .title(Line::from("top right").right_aligned())
167 .title_bottom(Line::from("bottom left").left_aligned())
168 .title_bottom(Line::from("bottom center").centered())
169 .title_bottom(Line::from("bottom right").right_aligned());
170 frame.render_widget(paragraph.clone().block(block), area);
171}
172
173fn render_padding(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
174 let block = Block::bordered()
175 .padding(Padding::new(5, 10, 1, 2))
176 .title("Padding");
177 frame.render_widget(paragraph.clone().block(block), area);
178}
179
180fn render_nested_blocks(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
181 let outer_block = Block::bordered().title("Outer block");
182 let inner_block = Block::bordered().title("Inner block");
183 let inner = outer_block.inner(area);
184 frame.render_widget(outer_block, area);
185 frame.render_widget(paragraph.clone().block(inner_block), inner);
186}
176 fn map_canvas(&self) -> impl Widget + '_ {
177 Canvas::default()
178 .block(Block::bordered().title("World"))
179 .marker(self.marker)
180 .paint(|ctx| {
181 ctx.draw(&Map {
182 color: Color::Green,
183 resolution: MapResolution::High,
184 });
185 ctx.print(self.x, -self.y, "You are here".yellow());
186 })
187 .x_bounds([-180.0, 180.0])
188 .y_bounds([-90.0, 90.0])
189 }
190
191 fn draw_canvas(&self, area: Rect) -> impl Widget + '_ {
192 Canvas::default()
193 .block(Block::bordered().title("Draw here"))
194 .marker(self.marker)
195 .x_bounds([0.0, f64::from(area.width)])
196 .y_bounds([0.0, f64::from(area.height)])
197 .paint(move |ctx| {
198 let points = self
199 .points
200 .iter()
201 .map(|p| {
202 (
203 f64::from(p.x) - f64::from(area.left()),
204 f64::from(area.bottom()) - f64::from(p.y),
205 )
206 })
207 .collect_vec();
208 ctx.draw(&Points {
209 coords: &points,
210 color: Color::White,
211 });
212 })
213 }
214
215 fn pong_canvas(&self) -> impl Widget + '_ {
216 Canvas::default()
217 .block(Block::bordered().title("Pong"))
218 .marker(self.marker)
219 .paint(|ctx| {
220 ctx.draw(&self.ball);
221 })
222 .x_bounds([10.0, 210.0])
223 .y_bounds([10.0, 110.0])
224 }
225
226 fn boxes_canvas(&self, area: Rect) -> impl Widget {
227 let left = 0.0;
228 let right = f64::from(area.width);
229 let bottom = 0.0;
230 let top = f64::from(area.height).mul_add(2.0, -4.0);
231 Canvas::default()
232 .block(Block::bordered().title("Rects"))
233 .marker(self.marker)
234 .x_bounds([left, right])
235 .y_bounds([bottom, top])
236 .paint(|ctx| {
237 for i in 0..=11 {
238 ctx.draw(&Rectangle {
239 x: f64::from(i * i + 3 * i) / 2.0 + 2.0,
240 y: 2.0,
241 width: f64::from(i),
242 height: f64::from(i),
243 color: Color::Red,
244 });
245 ctx.draw(&Rectangle {
246 x: f64::from(i * i + 3 * i) / 2.0 + 2.0,
247 y: 21.0,
248 width: f64::from(i),
249 height: f64::from(i),
250 color: Color::Blue,
251 });
252 }
253 for i in 0..100 {
254 if i % 10 != 0 {
255 ctx.print(f64::from(i) + 1.0, 0.0, format!("{i}", i = i % 10));
256 }
257 if i % 2 == 0 && i % 10 != 0 {
258 ctx.print(0.0, f64::from(i), format!("{i}", i = i % 10));
259 }
260 }
261 })
262 }
434 fn render_2px(&self, area: Rect, buf: &mut Buffer) {
435 let lighter_color = ConstraintName::from(self.constraint).lighter_color();
436 let main_color = ConstraintName::from(self.constraint).color();
437 let selected_color = if self.selected {
438 lighter_color
439 } else {
440 main_color
441 };
442 Block::bordered()
443 .border_set(symbols::border::QUADRANT_OUTSIDE)
444 .border_style(Style::reset().fg(selected_color).reversed())
445 .render(area, buf);
446 }
447
448 fn render_4px(&self, area: Rect, buf: &mut Buffer) {
449 let lighter_color = ConstraintName::from(self.constraint).lighter_color();
450 let main_color = ConstraintName::from(self.constraint).color();
451 let selected_color = if self.selected {
452 lighter_color
453 } else {
454 main_color
455 };
456 let color = if self.legend {
457 selected_color
458 } else {
459 main_color
460 };
461 let label = self.label(area.width);
462 let block = Block::bordered()
463 .border_set(symbols::border::QUADRANT_OUTSIDE)
464 .border_style(Style::reset().fg(color).reversed())
465 .fg(Self::TEXT_COLOR)
466 .bg(color);
467 Paragraph::new(label)
468 .centered()
469 .fg(Self::TEXT_COLOR)
470 .bg(color)
471 .block(block)
472 .render(area, buf);
473
474 if !self.legend {
475 let border_color = if self.selected {
476 lighter_color
477 } else {
478 main_color
479 };
480 if let Some(last_row) = area.rows().last() {
481 buf.set_style(last_row, border_color);
482 }
483 }
484 }
485}
486
487impl Widget for SpacerBlock {
488 fn render(self, area: Rect, buf: &mut Buffer) {
489 match area.height {
490 1 => (),
491 2 => Self::render_2px(area, buf),
492 3 => Self::render_3px(area, buf),
493 _ => Self::render_4px(area, buf),
494 }
495 }
496}
497
498impl SpacerBlock {
499 const TEXT_COLOR: Color = SLATE.c500;
500 const BORDER_COLOR: Color = SLATE.c600;
501
502 /// A block with a corner borders
503 fn block() -> impl Widget {
504 let corners_only = symbols::border::Set {
505 top_left: line::NORMAL.top_left,
506 top_right: line::NORMAL.top_right,
507 bottom_left: line::NORMAL.bottom_left,
508 bottom_right: line::NORMAL.bottom_right,
509 vertical_left: " ",
510 vertical_right: " ",
511 horizontal_top: " ",
512 horizontal_bottom: " ",
513 };
514 Block::bordered()
515 .border_set(corners_only)
516 .border_style(Self::BORDER_COLOR)
517 }
283 fn render_footer(&self, frame: &mut Frame, area: Rect) {
284 let info_footer = Paragraph::new(Text::from_iter(INFO_TEXT))
285 .style(
286 Style::new()
287 .fg(self.colors.row_fg)
288 .bg(self.colors.buffer_bg),
289 )
290 .centered()
291 .block(
292 Block::bordered()
293 .border_type(BorderType::Double)
294 .border_style(Style::new().fg(self.colors.footer_border_color)),
295 );
296 frame.render_widget(info_footer, area);
297 }
Sourcepub fn title<T>(self, title: T) -> Self
pub fn title<T>(self, title: T) -> Self
Adds a title to the block.
The title
function allows you to add a title to the block. You can call this function
multiple times to add multiple titles.
Each title will be rendered with a single space separating titles that are in the same position or alignment. When both centered and non-centered titles are rendered, the centered space is calculated based on the full width of the block, rather than the leftover width.
You can provide any type that can be converted into Title
including: strings, string
slices (&str
), borrowed strings (Cow<str>
), spans, or vectors of
spans (Vec<Span>
).
By default, the titles will avoid being rendered in the corners of the block but will align against the left or right edge of the block if there is no border on that edge. The following demonstrates this behavior, notice the second title is one character off to the left.
┌With at least a left border───
Without left border───
Note: If the block is too small and multiple titles overlap, the border might get cut off at a corner.
§Examples
See the Block example for a visual representation of how the various borders and styles look when rendered.
The following example demonstrates:
- Default title alignment
- Multiple titles (notice “Center” is centered according to the full with of the block, not the leftover space)
- Two titles with the same alignment (notice the left titles are separated)
use ratatui::{
text::Line,
widgets::{Block, Borders},
};
Block::new()
.title("Title") // By default in the top left corner
.title(Line::from("Left").left_aligned()) // also on the left
.title(Line::from("Right").right_aligned())
.title(Line::from("Center").centered());
// Renders
// ┌Title─Left────Center─────────Right┐
§See also
Titles attached to a block can have default behaviors. See
§Future improvements
In a future release of Ratatui this method will be changed to accept Into<Line>
instead of
Into<Title>
. This allows us to remove the unnecessary Title
struct and store the
position in the block itself. For more information see
https://github.com/ratatui/ratatui/issues/738.
Examples found in repository?
More examples
107fn render_borders(paragraph: &Paragraph, border: Borders, frame: &mut Frame, area: Rect) {
108 let block = Block::new()
109 .borders(border)
110 .title(format!("Borders::{border:#?}"));
111 frame.render_widget(paragraph.clone().block(block), area);
112}
113
114fn render_border_type(
115 paragraph: &Paragraph,
116 border_type: BorderType,
117 frame: &mut Frame,
118 area: Rect,
119) {
120 let block = Block::bordered()
121 .border_type(border_type)
122 .title(format!("BorderType::{border_type:#?}"));
123 frame.render_widget(paragraph.clone().block(block), area);
124}
125fn render_styled_borders(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
126 let block = Block::bordered()
127 .border_style(Style::new().blue().on_white().bold().italic())
128 .title("Styled borders");
129 frame.render_widget(paragraph.clone().block(block), area);
130}
131
132fn render_styled_block(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
133 let block = Block::bordered()
134 .style(Style::new().blue().on_white().bold().italic())
135 .title("Styled block");
136 frame.render_widget(paragraph.clone().block(block), area);
137}
138
139fn render_styled_title(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
140 let block = Block::bordered()
141 .title("Styled title")
142 .title_style(Style::new().blue().on_white().bold().italic());
143 frame.render_widget(paragraph.clone().block(block), area);
144}
145
146fn render_styled_title_content(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
147 let title = Line::from(vec![
148 "Styled ".blue().on_white().bold().italic(),
149 "title content".red().on_white().bold().italic(),
150 ]);
151 let block = Block::bordered().title(title);
152 frame.render_widget(paragraph.clone().block(block), area);
153}
154
155fn render_multiple_titles(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
156 let block = Block::bordered()
157 .title("Multiple".blue().on_white().bold().italic())
158 .title("Titles".red().on_white().bold().italic());
159 frame.render_widget(paragraph.clone().block(block), area);
160}
161
162fn render_multiple_title_positions(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
163 let block = Block::bordered()
164 .title(Line::from("top left").left_aligned())
165 .title(Line::from("top center").centered())
166 .title(Line::from("top right").right_aligned())
167 .title_bottom(Line::from("bottom left").left_aligned())
168 .title_bottom(Line::from("bottom center").centered())
169 .title_bottom(Line::from("bottom right").right_aligned());
170 frame.render_widget(paragraph.clone().block(block), area);
171}
172
173fn render_padding(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
174 let block = Block::bordered()
175 .padding(Padding::new(5, 10, 1, 2))
176 .title("Padding");
177 frame.render_widget(paragraph.clone().block(block), area);
178}
179
180fn render_nested_blocks(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
181 let outer_block = Block::bordered().title("Outer block");
182 let inner_block = Block::bordered().title("Inner block");
183 let inner = outer_block.inner(area);
184 frame.render_widget(outer_block, area);
185 frame.render_widget(paragraph.clone().block(inner_block), inner);
186}
83fn vertical_barchart(temperatures: &[u8]) -> BarChart {
84 let bars: Vec<Bar> = temperatures
85 .iter()
86 .enumerate()
87 .map(|(hour, value)| vertical_bar(hour, value))
88 .collect();
89 let title = Line::from("Weather (Vertical)").centered();
90 BarChart::default()
91 .data(BarGroup::default().bars(&bars))
92 .block(Block::new().title(title))
93 .bar_width(5)
94}
95
96fn vertical_bar(hour: usize, temperature: &u8) -> Bar {
97 Bar::default()
98 .value(u64::from(*temperature))
99 .label(Line::from(format!("{hour:>02}:00")))
100 .text_value(format!("{temperature:>3}°"))
101 .style(temperature_style(*temperature))
102 .value_style(temperature_style(*temperature).reversed())
103}
104
105/// Create a horizontal bar chart from the temperatures data.
106fn horizontal_barchart(temperatures: &[u8]) -> BarChart {
107 let bars: Vec<Bar> = temperatures
108 .iter()
109 .enumerate()
110 .map(|(hour, value)| horizontal_bar(hour, value))
111 .collect();
112 let title = Line::from("Weather (Horizontal)").centered();
113 BarChart::default()
114 .block(Block::new().title(title))
115 .data(BarGroup::default().bars(&bars))
116 .bar_width(1)
117 .bar_gap(0)
118 .direction(Direction::Horizontal)
119}
273 fn tabs(self) -> impl Widget {
274 let tab_titles = SelectedTab::iter().map(SelectedTab::to_tab_title);
275 let block = Block::new()
276 .title("Flex Layouts ".bold())
277 .title(" Use ◄ ► to change tab, ▲ ▼ to scroll, - + to change spacing ");
278 Tabs::new(tab_titles)
279 .block(block)
280 .highlight_style(Modifier::REVERSED)
281 .select(self.selected_tab as usize)
282 .divider(" ")
283 .padding("", "")
284 }
- examples/canvas.rs
- examples/barchart-grouped.rs
- examples/layout.rs
- examples/popup.rs
- examples/demo2/tabs/about.rs
- examples/async.rs
- examples/demo2/tabs/recipe.rs
- examples/panic.rs
- examples/chart.rs
- examples/list.rs
- examples/demo2/tabs/traceroute.rs
- examples/sparkline.rs
- examples/inline.rs
- examples/user_input.rs
- examples/scrollbar.rs
Sourcepub fn title_top<T: Into<Line<'a>>>(self, title: T) -> Self
pub fn title_top<T: Into<Line<'a>>>(self, title: T) -> Self
Adds a title to the top of the block.
You can provide any type that can be converted into Line
including: strings, string
slices (&str
), borrowed strings (Cow<str>
), spans, or vectors of
spans (Vec<Span>
).
§Example
use ratatui::{ widgets::Block, text::Line };
Block::bordered()
.title_top("Left1") // By default in the top left corner
.title_top(Line::from("Left2").left_aligned())
.title_top(Line::from("Right").right_aligned())
.title_top(Line::from("Center").centered());
// Renders
// ┌Left1─Left2───Center─────────Right┐
// │ │
// └──────────────────────────────────┘
Examples found in repository?
178fn render_barchart(frame: &mut Frame, bar_chart: Rect) {
179 let dataset = Dataset::default()
180 .marker(symbols::Marker::HalfBlock)
181 .style(Style::new().fg(Color::Blue))
182 .graph_type(GraphType::Bar)
183 // a bell curve
184 .data(&[
185 (0., 0.4),
186 (10., 2.9),
187 (20., 13.5),
188 (30., 41.1),
189 (40., 80.1),
190 (50., 100.0),
191 (60., 80.1),
192 (70., 41.1),
193 (80., 13.5),
194 (90., 2.9),
195 (100., 0.4),
196 ]);
197
198 let chart = Chart::new(vec![dataset])
199 .block(Block::bordered().title_top(Line::from("Bar chart").cyan().bold().centered()))
200 .x_axis(
201 Axis::default()
202 .style(Style::default().gray())
203 .bounds([0.0, 100.0])
204 .labels(["0".bold(), "50".into(), "100.0".bold()]),
205 )
206 .y_axis(
207 Axis::default()
208 .style(Style::default().gray())
209 .bounds([0.0, 100.0])
210 .labels(["0".bold(), "50".into(), "100.0".bold()]),
211 )
212 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
213
214 frame.render_widget(chart, bar_chart);
215}
Sourcepub fn title_bottom<T: Into<Line<'a>>>(self, title: T) -> Self
pub fn title_bottom<T: Into<Line<'a>>>(self, title: T) -> Self
Adds a title to the bottom of the block.
You can provide any type that can be converted into Line
including: strings, string
slices (&str
), borrowed strings (Cow<str>
), spans, or vectors of
spans (Vec<Span>
).
§Example
use ratatui::{ widgets::Block, text::Line };
Block::bordered()
.title_bottom("Left1") // By default in the top left corner
.title_bottom(Line::from("Left2").left_aligned())
.title_bottom(Line::from("Right").right_aligned())
.title_bottom(Line::from("Center").centered());
// Renders
// ┌──────────────────────────────────┐
// │ │
// └Left1─Left2───Center─────────Right┘
Examples found in repository?
More examples
226 fn render(self, area: Rect, buf: &mut Buffer) {
227 let mut state = self.state.write().unwrap();
228
229 // a block with a right aligned title with the loading state on the right
230 let loading_state = Line::from(format!("{:?}", state.loading_state)).right_aligned();
231 let block = Block::bordered()
232 .title("Pull Requests")
233 .title(loading_state)
234 .title_bottom("j/k to scroll, q to quit");
235
236 // a table with the list of pull requests
237 let rows = state.pull_requests.iter();
238 let widths = [
239 Constraint::Length(5),
240 Constraint::Fill(1),
241 Constraint::Max(49),
242 ];
243 let table = Table::new(rows, widths)
244 .block(block)
245 .highlight_spacing(HighlightSpacing::Always)
246 .highlight_symbol(">>")
247 .row_highlight_style(Style::new().on_blue());
248
249 StatefulWidget::render(table, area, buf, &mut state.table_state);
250 }
Sourcepub fn title_style<S: Into<Style>>(self, style: S) -> Self
pub fn title_style<S: Into<Style>>(self, style: S) -> Self
Applies the style to all titles.
This style will be applied to all titles of the block. If a title has a style set, it will
be applied after this style. This style will be applied after any Block::style
or
Block::border_style
is applied.
See Style
for more information on how merging styles works.
style
accepts any type that is convertible to Style
(e.g. Style
, Color
, or
your own type that implements Into<Style>
).
Sourcepub const fn title_alignment(self, alignment: Alignment) -> Self
pub const fn title_alignment(self, alignment: Alignment) -> Self
Sets the default Alignment
for all block titles.
Titles that explicitly set an Alignment
will ignore this.
§Example
This example aligns all titles in the center except the “right” title which explicitly sets
Alignment::Right
.
use ratatui::{layout::Alignment, text::Line, widgets::Block};
Block::new()
.title_alignment(Alignment::Center)
// This title won't be aligned in the center
.title(Line::from("right").right_aligned())
.title("foo")
.title("bar");
Examples found in repository?
70fn render_crate_description(area: Rect, buf: &mut Buffer) {
71 let area = area.inner(Margin {
72 vertical: 4,
73 horizontal: 2,
74 });
75 Clear.render(area, buf); // clear out the color swatches
76 Block::new().style(THEME.content).render(area, buf);
77 let area = area.inner(Margin {
78 vertical: 1,
79 horizontal: 2,
80 });
81 let text = "- cooking up terminal user interfaces -
82
83 Ratatui is a Rust crate that provides widgets (e.g. Paragraph, Table) and draws them to the \
84 screen efficiently every frame.";
85 Paragraph::new(text)
86 .style(THEME.description)
87 .block(
88 Block::new()
89 .title(" Ratatui ")
90 .title_alignment(Alignment::Center)
91 .borders(Borders::TOP)
92 .border_style(THEME.description_title)
93 .padding(Padding::new(0, 0, 0, 0)),
94 )
95 .wrap(Wrap { trim: true })
96 .scroll((0, 0))
97 .render(area, buf);
98}
More examples
115 fn render(self, area: Rect, buf: &mut Buffer) {
116 RgbSwatch.render(area, buf);
117 let area = area.inner(Margin {
118 vertical: 1,
119 horizontal: 2,
120 });
121 Clear.render(area, buf);
122 Block::new()
123 .title("Ratatouille Recipe".bold().white())
124 .title_alignment(Alignment::Center)
125 .style(THEME.content)
126 .padding(Padding::new(1, 1, 2, 1))
127 .render(area, buf);
128
129 let scrollbar_area = Rect {
130 y: area.y + 2,
131 height: area.height - 3,
132 ..area
133 };
134 render_scrollbar(self.row_index, scrollbar_area, buf);
135
136 let area = area.inner(Margin {
137 horizontal: 2,
138 vertical: 1,
139 });
140 let [recipe, ingredients] =
141 Layout::horizontal([Constraint::Length(44), Constraint::Min(0)]).areas(area);
142
143 render_recipe(recipe, buf);
144 render_ingredients(self.row_index, ingredients, buf);
145 }
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}
86
87pub fn render_ping(progress: usize, area: Rect, buf: &mut Buffer) {
88 let mut data = [
89 8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 4, 3, 3, 2, 2, 1, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 8, 7,
90 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 2, 4, 6, 7, 8, 8, 8, 8, 6, 4, 2, 1, 1, 1, 1, 2, 2, 2, 3,
91 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
92 ];
93 let mid = progress % data.len();
94 data.rotate_left(mid);
95 Sparkline::default()
96 .block(
97 Block::new()
98 .title("Ping")
99 .title_alignment(Alignment::Center)
100 .border_type(BorderType::Thick),
101 )
102 .data(data)
103 .style(THEME.traceroute.ping)
104 .render(area, buf);
105}
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 title_position(self, position: Position) -> Self
pub const fn title_position(self, position: Position) -> Self
Sets the default Position
for all block titles.
Titles that explicitly set a Position
will ignore this.
§Example
This example positions all titles on the bottom except the “top” title which explicitly sets
Position::Top
.
use ratatui::widgets::{block::Position, Block};
Block::new()
.title_position(Position::Bottom)
// This title won't be aligned in the center
.title_top("top")
.title("foo")
.title("bar");
Sourcepub fn border_style<S: Into<Style>>(self, style: S) -> Self
pub fn border_style<S: Into<Style>>(self, style: S) -> Self
Defines the style of the borders.
This style is applied only to the areas covered by borders, and is applied to the block
after any Block::style
is applied.
See Style
for more information on how merging styles works.
style
accepts any type that is convertible to Style
(e.g. Style
, Color
, or
your own type that implements Into<Style>
).
§Example
This example shows a Block
with blue borders.
use ratatui::{
style::{Style, Stylize},
widgets::Block,
};
Block::bordered().border_style(Style::new().blue());
Examples found in repository?
More examples
434 fn render_2px(&self, area: Rect, buf: &mut Buffer) {
435 let lighter_color = ConstraintName::from(self.constraint).lighter_color();
436 let main_color = ConstraintName::from(self.constraint).color();
437 let selected_color = if self.selected {
438 lighter_color
439 } else {
440 main_color
441 };
442 Block::bordered()
443 .border_set(symbols::border::QUADRANT_OUTSIDE)
444 .border_style(Style::reset().fg(selected_color).reversed())
445 .render(area, buf);
446 }
447
448 fn render_4px(&self, area: Rect, buf: &mut Buffer) {
449 let lighter_color = ConstraintName::from(self.constraint).lighter_color();
450 let main_color = ConstraintName::from(self.constraint).color();
451 let selected_color = if self.selected {
452 lighter_color
453 } else {
454 main_color
455 };
456 let color = if self.legend {
457 selected_color
458 } else {
459 main_color
460 };
461 let label = self.label(area.width);
462 let block = Block::bordered()
463 .border_set(symbols::border::QUADRANT_OUTSIDE)
464 .border_style(Style::reset().fg(color).reversed())
465 .fg(Self::TEXT_COLOR)
466 .bg(color);
467 Paragraph::new(label)
468 .centered()
469 .fg(Self::TEXT_COLOR)
470 .bg(color)
471 .block(block)
472 .render(area, buf);
473
474 if !self.legend {
475 let border_color = if self.selected {
476 lighter_color
477 } else {
478 main_color
479 };
480 if let Some(last_row) = area.rows().last() {
481 buf.set_style(last_row, border_color);
482 }
483 }
484 }
485}
486
487impl Widget for SpacerBlock {
488 fn render(self, area: Rect, buf: &mut Buffer) {
489 match area.height {
490 1 => (),
491 2 => Self::render_2px(area, buf),
492 3 => Self::render_3px(area, buf),
493 _ => Self::render_4px(area, buf),
494 }
495 }
496}
497
498impl SpacerBlock {
499 const TEXT_COLOR: Color = SLATE.c500;
500 const BORDER_COLOR: Color = SLATE.c600;
501
502 /// A block with a corner borders
503 fn block() -> impl Widget {
504 let corners_only = symbols::border::Set {
505 top_left: line::NORMAL.top_left,
506 top_right: line::NORMAL.top_right,
507 bottom_left: line::NORMAL.bottom_left,
508 bottom_right: line::NORMAL.bottom_right,
509 vertical_left: " ",
510 vertical_right: " ",
511 horizontal_top: " ",
512 horizontal_bottom: " ",
513 };
514 Block::bordered()
515 .border_set(corners_only)
516 .border_style(Self::BORDER_COLOR)
517 }
283 fn render_footer(&self, frame: &mut Frame, area: Rect) {
284 let info_footer = Paragraph::new(Text::from_iter(INFO_TEXT))
285 .style(
286 Style::new()
287 .fg(self.colors.row_fg)
288 .bg(self.colors.buffer_bg),
289 )
290 .centered()
291 .block(
292 Block::bordered()
293 .border_type(BorderType::Double)
294 .border_style(Style::new().fg(self.colors.footer_border_color)),
295 );
296 frame.render_widget(info_footer, area);
297 }
146fn render_example_combination(
147 frame: &mut Frame,
148 area: Rect,
149 title: &str,
150 constraints: impl ExactSizeIterator<Item = (Constraint, Constraint)>,
151) {
152 let block = Block::bordered()
153 .title(title.gray())
154 .style(Style::reset())
155 .border_style(Style::default().fg(Color::DarkGray));
156 let inner = block.inner(area);
157 frame.render_widget(block, area);
158 let layout = Layout::vertical(vec![Length(1); constraints.len() + 1]).split(inner);
159 for ((a, b), &area) in constraints.into_iter().zip(layout.iter()) {
160 render_single_example(frame, area, vec![a, b, Min(0)]);
161 }
162 // This is to make it easy to visually see the alignment of the examples
163 // with the constraints.
164 frame.render_widget(Paragraph::new("123456789012"), layout[6]);
165}
70fn render_crate_description(area: Rect, buf: &mut Buffer) {
71 let area = area.inner(Margin {
72 vertical: 4,
73 horizontal: 2,
74 });
75 Clear.render(area, buf); // clear out the color swatches
76 Block::new().style(THEME.content).render(area, buf);
77 let area = area.inner(Margin {
78 vertical: 1,
79 horizontal: 2,
80 });
81 let text = "- cooking up terminal user interfaces -
82
83 Ratatui is a Rust crate that provides widgets (e.g. Paragraph, Table) and draws them to the \
84 screen efficiently every frame.";
85 Paragraph::new(text)
86 .style(THEME.description)
87 .block(
88 Block::new()
89 .title(" Ratatui ")
90 .title_alignment(Alignment::Center)
91 .borders(Borders::TOP)
92 .border_style(THEME.description_title)
93 .padding(Padding::new(0, 0, 0, 0)),
94 )
95 .wrap(Wrap { trim: true })
96 .scroll((0, 0))
97 .render(area, buf);
98}
Sourcepub fn style<S: Into<Style>>(self, style: S) -> Self
pub fn style<S: Into<Style>>(self, style: S) -> Self
Defines the style of the entire block.
This is the most generic Style
a block can receive, it will be merged with any other
more specific styles. Elements can be styled further with Block::title_style
and
Block::border_style
, which will be applied on top of this style. If the block is used as
a container for another widget (e.g. a Paragraph
), then the style of the widget is
generally applied before this style.
See Style
for more information on how merging styles works.
style
accepts any type that is convertible to Style
(e.g. Style
, Color
, or
your own type that implements Into<Style>
).
§Example
use ratatui::{
style::{Color, Style, Stylize},
widgets::{Block, Paragraph},
};
let block = Block::new().style(Style::new().red().on_black());
// For border and title you can additionally apply styles on top of the block level style.
let block = Block::new()
.style(Style::new().red().bold().italic())
.border_style(Style::new().not_italic()) // will be red and bold
.title_style(Style::new().not_bold()) // will be red and italic
.title("Title");
// To style the inner widget, you can style the widget itself.
let paragraph = Paragraph::new("Content")
.block(block)
.style(Style::new().white().not_bold()); // will be white, and italic
Examples found in repository?
More examples
141 fn render(self, area: Rect, buf: &mut Buffer) {
142 let vertical = Layout::vertical([
143 Constraint::Length(1),
144 Constraint::Min(0),
145 Constraint::Length(1),
146 ]);
147 let [title_bar, tab, bottom_bar] = vertical.areas(area);
148
149 Block::new().style(THEME.root).render(area, buf);
150 self.render_title_bar(title_bar, buf);
151 self.render_selected_tab(tab, buf);
152 App::render_bottom_bar(bottom_bar, buf);
153 }
497 fn illustration(constraint: Constraint, width: u16) -> impl Widget {
498 let main_color = color_for_constraint(constraint);
499 let fg_color = Color::White;
500 let title = format!("{constraint}");
501 let content = format!("{width} px");
502 let text = format!("{title}\n{content}");
503 let block = Block::bordered()
504 .border_set(symbols::border::QUADRANT_OUTSIDE)
505 .border_style(Style::reset().fg(main_color).reversed())
506 .style(Style::default().fg(fg_color).bg(main_color));
507 Paragraph::new(text).centered().block(block)
508 }
34 fn render(self, area: Rect, buf: &mut Buffer) {
35 RgbSwatch.render(area, buf);
36 let area = area.inner(Margin {
37 vertical: 1,
38 horizontal: 2,
39 });
40 Clear.render(area, buf);
41 Block::new().style(THEME.content).render(area, buf);
42 let horizontal = Layout::horizontal([Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)]);
43 let vertical = Layout::vertical([Constraint::Min(0), Constraint::Length(3)]);
44 let [left, map] = horizontal.areas(area);
45 let [hops, pings] = vertical.areas(left);
46
47 render_hops(self.row_index, hops, buf);
48 render_ping(self.row_index, pings, buf);
49 render_map(self.row_index, map, buf);
50 }
51}
52
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}
86
87pub fn render_ping(progress: usize, area: Rect, buf: &mut Buffer) {
88 let mut data = [
89 8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 4, 3, 3, 2, 2, 1, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 8, 7,
90 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 2, 4, 6, 7, 8, 8, 8, 8, 6, 4, 2, 1, 1, 1, 1, 2, 2, 2, 3,
91 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
92 ];
93 let mid = progress % data.len();
94 data.rotate_left(mid);
95 Sparkline::default()
96 .block(
97 Block::new()
98 .title("Ping")
99 .title_alignment(Alignment::Center)
100 .border_type(BorderType::Thick),
101 )
102 .data(data)
103 .style(THEME.traceroute.ping)
104 .render(area, buf);
105}
106
107fn render_map(selected_row: usize, area: Rect, buf: &mut Buffer) {
108 let theme = THEME.traceroute.map;
109 let path: Option<(&Hop, &Hop)> = HOPS.iter().tuple_windows().nth(selected_row);
110 let map = Map {
111 resolution: MapResolution::High,
112 color: theme.color,
113 };
114 Canvas::default()
115 .background_color(theme.background_color)
116 .block(
117 Block::new()
118 .padding(Padding::new(1, 0, 1, 0))
119 .style(theme.style),
120 )
121 .marker(Marker::HalfBlock)
122 // picked to show Australia for the demo as it's the most interesting part of the map
123 // (and the only part with hops ;))
124 .x_bounds([112.0, 155.0])
125 .y_bounds([-46.0, -11.0])
126 .paint(|context| {
127 context.draw(&map);
128 if let Some(path) = path {
129 context.draw(&canvas::Line::new(
130 path.0.location.0,
131 path.0.location.1,
132 path.1.location.0,
133 path.1.location.1,
134 theme.path,
135 ));
136 context.draw(&Points {
137 color: theme.source,
138 coords: &[path.0.location], // sydney
139 });
140 context.draw(&Points {
141 color: theme.destination,
142 coords: &[path.1.location], // perth
143 });
144 }
145 })
146 .render(area, buf);
147}
146fn render_example_combination(
147 frame: &mut Frame,
148 area: Rect,
149 title: &str,
150 constraints: impl ExactSizeIterator<Item = (Constraint, Constraint)>,
151) {
152 let block = Block::bordered()
153 .title(title.gray())
154 .style(Style::reset())
155 .border_style(Style::default().fg(Color::DarkGray));
156 let inner = block.inner(area);
157 frame.render_widget(block, area);
158 let layout = Layout::vertical(vec![Length(1); constraints.len() + 1]).split(inner);
159 for ((a, b), &area) in constraints.into_iter().zip(layout.iter()) {
160 render_single_example(frame, area, vec![a, b, Min(0)]);
161 }
162 // This is to make it easy to visually see the alignment of the examples
163 // with the constraints.
164 frame.render_widget(Paragraph::new("123456789012"), layout[6]);
165}
70fn render_crate_description(area: Rect, buf: &mut Buffer) {
71 let area = area.inner(Margin {
72 vertical: 4,
73 horizontal: 2,
74 });
75 Clear.render(area, buf); // clear out the color swatches
76 Block::new().style(THEME.content).render(area, buf);
77 let area = area.inner(Margin {
78 vertical: 1,
79 horizontal: 2,
80 });
81 let text = "- cooking up terminal user interfaces -
82
83 Ratatui is a Rust crate that provides widgets (e.g. Paragraph, Table) and draws them to the \
84 screen efficiently every frame.";
85 Paragraph::new(text)
86 .style(THEME.description)
87 .block(
88 Block::new()
89 .title(" Ratatui ")
90 .title_alignment(Alignment::Center)
91 .borders(Borders::TOP)
92 .border_style(THEME.description_title)
93 .padding(Padding::new(0, 0, 0, 0)),
94 )
95 .wrap(Wrap { trim: true })
96 .scroll((0, 0))
97 .render(area, buf);
98}
Sourcepub const fn borders(self, flag: Borders) -> Self
pub const fn borders(self, flag: Borders) -> Self
Defines which borders to display.
Borders
can also be styled with Block::border_style
and Block::border_type
.
§Examples
Display left and right borders.
use ratatui::widgets::{Block, Borders};
Block::new().borders(Borders::LEFT | Borders::RIGHT);
To show all borders you can abbreviate this with Block::bordered
Examples found in repository?
More examples
70fn render_crate_description(area: Rect, buf: &mut Buffer) {
71 let area = area.inner(Margin {
72 vertical: 4,
73 horizontal: 2,
74 });
75 Clear.render(area, buf); // clear out the color swatches
76 Block::new().style(THEME.content).render(area, buf);
77 let area = area.inner(Margin {
78 vertical: 1,
79 horizontal: 2,
80 });
81 let text = "- cooking up terminal user interfaces -
82
83 Ratatui is a Rust crate that provides widgets (e.g. Paragraph, Table) and draws them to the \
84 screen efficiently every frame.";
85 Paragraph::new(text)
86 .style(THEME.description)
87 .block(
88 Block::new()
89 .title(" Ratatui ")
90 .title_alignment(Alignment::Center)
91 .borders(Borders::TOP)
92 .border_style(THEME.description_title)
93 .padding(Padding::new(0, 0, 0, 0)),
94 )
95 .wrap(Wrap { trim: true })
96 .scroll((0, 0))
97 .render(area, buf);
98}
208 fn render_list(&mut self, area: Rect, buf: &mut Buffer) {
209 let block = Block::new()
210 .title(Line::raw("TODO List").centered())
211 .borders(Borders::TOP)
212 .border_set(symbols::border::EMPTY)
213 .border_style(TODO_HEADER_STYLE)
214 .bg(NORMAL_ROW_BG);
215
216 // Iterate through all elements in the `items` and stylize them.
217 let items: Vec<ListItem> = self
218 .todo_list
219 .items
220 .iter()
221 .enumerate()
222 .map(|(i, todo_item)| {
223 let color = alternate_colors(i);
224 ListItem::from(todo_item).bg(color)
225 })
226 .collect();
227
228 // Create a List from all list items and highlight the currently selected one
229 let list = List::new(items)
230 .block(block)
231 .highlight_style(SELECTED_STYLE)
232 .highlight_symbol(">")
233 .highlight_spacing(HighlightSpacing::Always);
234
235 // We need to disambiguate this trait method as both `Widget` and `StatefulWidget` share the
236 // same method name `render`.
237 StatefulWidget::render(list, area, buf, &mut self.todo_list.state);
238 }
239
240 fn render_selected_item(&self, area: Rect, buf: &mut Buffer) {
241 // We get the info depending on the item's state.
242 let info = if let Some(i) = self.todo_list.state.selected() {
243 match self.todo_list.items[i].status {
244 Status::Completed => format!("✓ DONE: {}", self.todo_list.items[i].info),
245 Status::Todo => format!("☐ TODO: {}", self.todo_list.items[i].info),
246 }
247 } else {
248 "Nothing selected...".to_string()
249 };
250
251 // We show the list item's info under the list in this paragraph
252 let block = Block::new()
253 .title(Line::raw("TODO Info").centered())
254 .borders(Borders::TOP)
255 .border_set(symbols::border::EMPTY)
256 .border_style(TODO_HEADER_STYLE)
257 .bg(NORMAL_ROW_BG)
258 .padding(Padding::horizontal(1));
259
260 // We can now render the item info
261 Paragraph::new(info)
262 .block(block)
263 .fg(TEXT_FG_COLOR)
264 .wrap(Wrap { trim: false })
265 .render(area, buf);
266 }
116 fn draw(&self, frame: &mut Frame) {
117 let chunks = Layout::vertical([
118 Constraint::Length(3),
119 Constraint::Length(3),
120 Constraint::Min(0),
121 ])
122 .split(frame.area());
123 let sparkline = Sparkline::default()
124 .block(
125 Block::new()
126 .borders(Borders::LEFT | Borders::RIGHT)
127 .title("Data1"),
128 )
129 .data(&self.data1)
130 .style(Style::default().fg(Color::Yellow));
131 frame.render_widget(sparkline, chunks[0]);
132 let sparkline = Sparkline::default()
133 .block(
134 Block::new()
135 .borders(Borders::LEFT | Borders::RIGHT)
136 .title("Data2"),
137 )
138 .data(&self.data2)
139 .style(Style::default().bg(Color::Green));
140 frame.render_widget(sparkline, chunks[1]);
141 // Multiline
142 let sparkline = Sparkline::default()
143 .block(
144 Block::new()
145 .borders(Borders::LEFT | Borders::RIGHT)
146 .title("Data3"),
147 )
148 .data(&self.data3)
149 .style(Style::default().fg(Color::Red));
150 frame.render_widget(sparkline, chunks[2]);
151 }
Sourcepub const fn border_type(self, border_type: BorderType) -> Self
pub const fn border_type(self, border_type: BorderType) -> Self
Sets the symbols used to display the border (e.g. single line, double line, thick or rounded borders).
Setting this overwrites any custom border_set
that was set.
See BorderType
for the full list of available symbols.
§Examples
use ratatui::widgets::{Block, BorderType};
Block::bordered()
.border_type(BorderType::Rounded)
.title("Block");
// Renders
// ╭Block╮
// │ │
// ╰─────╯
Examples found in repository?
More examples
283 fn render_footer(&self, frame: &mut Frame, area: Rect) {
284 let info_footer = Paragraph::new(Text::from_iter(INFO_TEXT))
285 .style(
286 Style::new()
287 .fg(self.colors.row_fg)
288 .bg(self.colors.buffer_bg),
289 )
290 .centered()
291 .block(
292 Block::bordered()
293 .border_type(BorderType::Double)
294 .border_style(Style::new().fg(self.colors.footer_border_color)),
295 );
296 frame.render_widget(info_footer, area);
297 }
87pub fn render_ping(progress: usize, area: Rect, buf: &mut Buffer) {
88 let mut data = [
89 8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 4, 3, 3, 2, 2, 1, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 8, 7,
90 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 2, 4, 6, 7, 8, 8, 8, 8, 6, 4, 2, 1, 1, 1, 1, 2, 2, 2, 3,
91 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
92 ];
93 let mid = progress % data.len();
94 data.rotate_left(mid);
95 Sparkline::default()
96 .block(
97 Block::new()
98 .title("Ping")
99 .title_alignment(Alignment::Center)
100 .border_type(BorderType::Thick),
101 )
102 .data(data)
103 .style(THEME.traceroute.ping)
104 .render(area, buf);
105}
124fn render_email(selected_index: usize, area: Rect, buf: &mut Buffer) {
125 let theme = THEME.email;
126 let email = EMAILS.get(selected_index);
127 let block = Block::new()
128 .style(theme.body)
129 .padding(Padding::new(2, 2, 0, 0))
130 .borders(Borders::TOP)
131 .border_type(BorderType::Thick);
132 let inner = block.inner(area);
133 block.render(area, buf);
134 if let Some(email) = email {
135 let vertical = Layout::vertical([Constraint::Length(3), Constraint::Min(0)]);
136 let [headers_area, body_area] = vertical.areas(inner);
137 let headers = vec![
138 Line::from(vec![
139 "From: ".set_style(theme.header),
140 email.from.set_style(theme.header_value),
141 ]),
142 Line::from(vec![
143 "Subject: ".set_style(theme.header),
144 email.subject.set_style(theme.header_value),
145 ]),
146 "-".repeat(inner.width as usize).dim().into(),
147 ];
148 Paragraph::new(headers)
149 .style(theme.body)
150 .render(headers_area, buf);
151 let body = email.body.lines().map(Line::from).collect_vec();
152 Paragraph::new(body)
153 .style(theme.body)
154 .render(body_area, buf);
155 } else {
156 Paragraph::new("No email selected").render(inner, buf);
157 }
158}
Sourcepub const fn border_set(self, border_set: Set) -> Self
pub const fn border_set(self, border_set: Set) -> Self
Sets the symbols used to display the border as a crate::symbols::border::Set
.
Setting this overwrites any border_type
that was set.
§Examples
use ratatui::{widgets::Block, symbols};
Block::bordered().border_set(symbols::border::DOUBLE).title("Block");
// Renders
// ╔Block╗
// ║ ║
// ╚═════╝
Examples found in repository?
More examples
434 fn render_2px(&self, area: Rect, buf: &mut Buffer) {
435 let lighter_color = ConstraintName::from(self.constraint).lighter_color();
436 let main_color = ConstraintName::from(self.constraint).color();
437 let selected_color = if self.selected {
438 lighter_color
439 } else {
440 main_color
441 };
442 Block::bordered()
443 .border_set(symbols::border::QUADRANT_OUTSIDE)
444 .border_style(Style::reset().fg(selected_color).reversed())
445 .render(area, buf);
446 }
447
448 fn render_4px(&self, area: Rect, buf: &mut Buffer) {
449 let lighter_color = ConstraintName::from(self.constraint).lighter_color();
450 let main_color = ConstraintName::from(self.constraint).color();
451 let selected_color = if self.selected {
452 lighter_color
453 } else {
454 main_color
455 };
456 let color = if self.legend {
457 selected_color
458 } else {
459 main_color
460 };
461 let label = self.label(area.width);
462 let block = Block::bordered()
463 .border_set(symbols::border::QUADRANT_OUTSIDE)
464 .border_style(Style::reset().fg(color).reversed())
465 .fg(Self::TEXT_COLOR)
466 .bg(color);
467 Paragraph::new(label)
468 .centered()
469 .fg(Self::TEXT_COLOR)
470 .bg(color)
471 .block(block)
472 .render(area, buf);
473
474 if !self.legend {
475 let border_color = if self.selected {
476 lighter_color
477 } else {
478 main_color
479 };
480 if let Some(last_row) = area.rows().last() {
481 buf.set_style(last_row, border_color);
482 }
483 }
484 }
485}
486
487impl Widget for SpacerBlock {
488 fn render(self, area: Rect, buf: &mut Buffer) {
489 match area.height {
490 1 => (),
491 2 => Self::render_2px(area, buf),
492 3 => Self::render_3px(area, buf),
493 _ => Self::render_4px(area, buf),
494 }
495 }
496}
497
498impl SpacerBlock {
499 const TEXT_COLOR: Color = SLATE.c500;
500 const BORDER_COLOR: Color = SLATE.c600;
501
502 /// A block with a corner borders
503 fn block() -> impl Widget {
504 let corners_only = symbols::border::Set {
505 top_left: line::NORMAL.top_left,
506 top_right: line::NORMAL.top_right,
507 bottom_left: line::NORMAL.bottom_left,
508 bottom_right: line::NORMAL.bottom_right,
509 vertical_left: " ",
510 vertical_right: " ",
511 horizontal_top: " ",
512 horizontal_bottom: " ",
513 };
514 Block::bordered()
515 .border_set(corners_only)
516 .border_style(Self::BORDER_COLOR)
517 }
208 fn render_list(&mut self, area: Rect, buf: &mut Buffer) {
209 let block = Block::new()
210 .title(Line::raw("TODO List").centered())
211 .borders(Borders::TOP)
212 .border_set(symbols::border::EMPTY)
213 .border_style(TODO_HEADER_STYLE)
214 .bg(NORMAL_ROW_BG);
215
216 // Iterate through all elements in the `items` and stylize them.
217 let items: Vec<ListItem> = self
218 .todo_list
219 .items
220 .iter()
221 .enumerate()
222 .map(|(i, todo_item)| {
223 let color = alternate_colors(i);
224 ListItem::from(todo_item).bg(color)
225 })
226 .collect();
227
228 // Create a List from all list items and highlight the currently selected one
229 let list = List::new(items)
230 .block(block)
231 .highlight_style(SELECTED_STYLE)
232 .highlight_symbol(">")
233 .highlight_spacing(HighlightSpacing::Always);
234
235 // We need to disambiguate this trait method as both `Widget` and `StatefulWidget` share the
236 // same method name `render`.
237 StatefulWidget::render(list, area, buf, &mut self.todo_list.state);
238 }
239
240 fn render_selected_item(&self, area: Rect, buf: &mut Buffer) {
241 // We get the info depending on the item's state.
242 let info = if let Some(i) = self.todo_list.state.selected() {
243 match self.todo_list.items[i].status {
244 Status::Completed => format!("✓ DONE: {}", self.todo_list.items[i].info),
245 Status::Todo => format!("☐ TODO: {}", self.todo_list.items[i].info),
246 }
247 } else {
248 "Nothing selected...".to_string()
249 };
250
251 // We show the list item's info under the list in this paragraph
252 let block = Block::new()
253 .title(Line::raw("TODO Info").centered())
254 .borders(Borders::TOP)
255 .border_set(symbols::border::EMPTY)
256 .border_style(TODO_HEADER_STYLE)
257 .bg(NORMAL_ROW_BG)
258 .padding(Padding::horizontal(1));
259
260 // We can now render the item info
261 Paragraph::new(info)
262 .block(block)
263 .fg(TEXT_FG_COLOR)
264 .wrap(Wrap { trim: false })
265 .render(area, buf);
266 }
452 fn render_spacer(spacer: Rect, buf: &mut Buffer) {
453 if spacer.width > 1 {
454 let corners_only = symbols::border::Set {
455 top_left: line::NORMAL.top_left,
456 top_right: line::NORMAL.top_right,
457 bottom_left: line::NORMAL.bottom_left,
458 bottom_right: line::NORMAL.bottom_right,
459 vertical_left: " ",
460 vertical_right: " ",
461 horizontal_top: " ",
462 horizontal_bottom: " ",
463 };
464 Block::bordered()
465 .border_set(corners_only)
466 .border_style(Style::reset().dark_gray())
467 .render(spacer, buf);
468 } else {
469 Paragraph::new(Text::from(vec![
470 Line::from(""),
471 Line::from("│"),
472 Line::from("│"),
473 Line::from(""),
474 ]))
475 .style(Style::reset().dark_gray())
476 .render(spacer, buf);
477 }
478 let width = spacer.width;
479 let label = if width > 4 {
480 format!("{width} px")
481 } else if width > 2 {
482 format!("{width}")
483 } else {
484 String::new()
485 };
486 let text = Text::from(vec![
487 Line::raw(""),
488 Line::raw(""),
489 Line::styled(label, Style::reset().dark_gray()),
490 ]);
491 Paragraph::new(text)
492 .style(Style::reset().dark_gray())
493 .alignment(Alignment::Center)
494 .render(spacer, buf);
495 }
496
497 fn illustration(constraint: Constraint, width: u16) -> impl Widget {
498 let main_color = color_for_constraint(constraint);
499 let fg_color = Color::White;
500 let title = format!("{constraint}");
501 let content = format!("{width} px");
502 let text = format!("{title}\n{content}");
503 let block = Block::bordered()
504 .border_set(symbols::border::QUADRANT_OUTSIDE)
505 .border_style(Style::reset().fg(main_color).reversed())
506 .style(Style::default().fg(fg_color).bg(main_color));
507 Paragraph::new(text).centered().block(block)
508 }
Sourcepub const fn padding(self, padding: Padding) -> Self
pub const fn padding(self, padding: Padding) -> Self
Defines the padding inside a Block
.
See Padding
for more information.
§Examples
This renders a Block
with no padding (the default).
use ratatui::widgets::{Block, Padding};
Block::bordered().padding(Padding::ZERO);
// Renders
// ┌───────┐
// │content│
// └───────┘
This example shows a Block
with padding left and right (Padding::horizontal
).
Notice the two spaces before and after the content.
use ratatui::widgets::{Block, Padding};
Block::bordered().padding(Padding::horizontal(2));
// Renders
// ┌───────────┐
// │ content │
// └───────────┘
Examples found in repository?
More examples
66fn render_calendar(area: Rect, buf: &mut Buffer) {
67 let date = OffsetDateTime::now_utc().date();
68 Monthly::new(date, CalendarEventStore::today(Style::new().red().bold()))
69 .block(Block::new().padding(Padding::new(0, 0, 2, 0)))
70 .show_month_header(Style::new().bold())
71 .show_weekdays_header(Style::new().italic())
72 .render(area, buf);
73}
74
75fn render_simple_barchart(area: Rect, buf: &mut Buffer) {
76 let data = [
77 ("Sat", 76),
78 ("Sun", 69),
79 ("Mon", 65),
80 ("Tue", 67),
81 ("Wed", 65),
82 ("Thu", 69),
83 ("Fri", 73),
84 ];
85 let data = data
86 .into_iter()
87 .map(|(label, value)| {
88 Bar::default()
89 .value(value)
90 // This doesn't actually render correctly as the text is too wide for the bar
91 // See https://github.com/ratatui/ratatui/issues/513 for more info
92 // (the demo GIFs hack around this by hacking the calculation in bars.rs)
93 .text_value(format!("{value}°"))
94 .style(if value > 70 {
95 Style::new().fg(Color::Red)
96 } else {
97 Style::new().fg(Color::Yellow)
98 })
99 .value_style(if value > 70 {
100 Style::new().fg(Color::Gray).bg(Color::Red).bold()
101 } else {
102 Style::new().fg(Color::DarkGray).bg(Color::Yellow).bold()
103 })
104 .label(label.into())
105 })
106 .collect_vec();
107 let group = BarGroup::default().bars(&data);
108 BarChart::default()
109 .data(group)
110 .bar_width(3)
111 .bar_gap(1)
112 .render(area, buf);
113}
114
115fn render_horizontal_barchart(area: Rect, buf: &mut Buffer) {
116 let bg = Color::Rgb(32, 48, 96);
117 let data = [
118 Bar::default().text_value("Winter 37-51".into()).value(51),
119 Bar::default().text_value("Spring 40-65".into()).value(65),
120 Bar::default().text_value("Summer 54-77".into()).value(77),
121 Bar::default()
122 .text_value("Fall 41-71".into())
123 .value(71)
124 .value_style(Style::new().bold()), // current season
125 ];
126 let group = BarGroup::default().label("GPU".into()).bars(&data);
127 BarChart::default()
128 .block(Block::new().padding(Padding::new(0, 0, 2, 0)))
129 .direction(Direction::Horizontal)
130 .data(group)
131 .bar_gap(1)
132 .bar_style(Style::new().fg(bg))
133 .value_style(Style::new().bg(bg).fg(Color::Gray))
134 .render(area, buf);
135}
70fn render_crate_description(area: Rect, buf: &mut Buffer) {
71 let area = area.inner(Margin {
72 vertical: 4,
73 horizontal: 2,
74 });
75 Clear.render(area, buf); // clear out the color swatches
76 Block::new().style(THEME.content).render(area, buf);
77 let area = area.inner(Margin {
78 vertical: 1,
79 horizontal: 2,
80 });
81 let text = "- cooking up terminal user interfaces -
82
83 Ratatui is a Rust crate that provides widgets (e.g. Paragraph, Table) and draws them to the \
84 screen efficiently every frame.";
85 Paragraph::new(text)
86 .style(THEME.description)
87 .block(
88 Block::new()
89 .title(" Ratatui ")
90 .title_alignment(Alignment::Center)
91 .borders(Borders::TOP)
92 .border_style(THEME.description_title)
93 .padding(Padding::new(0, 0, 0, 0)),
94 )
95 .wrap(Wrap { trim: true })
96 .scroll((0, 0))
97 .render(area, buf);
98}
Sourcepub fn inner(&self, area: Rect) -> Rect
pub fn inner(&self, area: Rect) -> Rect
Compute the inner area of a block based on its border visibility rules.
§Examples
Draw a block nested within another block
use ratatui::{widgets::Block, Frame};
let outer_block = Block::bordered().title("Outer");
let inner_block = Block::bordered().title("Inner");
let outer_area = frame.area();
let inner_area = outer_block.inner(outer_area);
frame.render_widget(outer_block, outer_area);
frame.render_widget(inner_block, inner_area);
// Renders
// ┌Outer────────┐
// │┌Inner──────┐│
// ││ ││
// │└───────────┘│
// └─────────────┘
Examples found in repository?
More examples
146fn render_example_combination(
147 frame: &mut Frame,
148 area: Rect,
149 title: &str,
150 constraints: impl ExactSizeIterator<Item = (Constraint, Constraint)>,
151) {
152 let block = Block::bordered()
153 .title(title.gray())
154 .style(Style::reset())
155 .border_style(Style::default().fg(Color::DarkGray));
156 let inner = block.inner(area);
157 frame.render_widget(block, area);
158 let layout = Layout::vertical(vec![Length(1); constraints.len() + 1]).split(inner);
159 for ((a, b), &area) in constraints.into_iter().zip(layout.iter()) {
160 render_single_example(frame, area, vec![a, b, Min(0)]);
161 }
162 // This is to make it easy to visually see the alignment of the examples
163 // with the constraints.
164 frame.render_widget(Paragraph::new("123456789012"), layout[6]);
165}
124fn render_email(selected_index: usize, area: Rect, buf: &mut Buffer) {
125 let theme = THEME.email;
126 let email = EMAILS.get(selected_index);
127 let block = Block::new()
128 .style(theme.body)
129 .padding(Padding::new(2, 2, 0, 0))
130 .borders(Borders::TOP)
131 .border_type(BorderType::Thick);
132 let inner = block.inner(area);
133 block.render(area, buf);
134 if let Some(email) = email {
135 let vertical = Layout::vertical([Constraint::Length(3), Constraint::Min(0)]);
136 let [headers_area, body_area] = vertical.areas(inner);
137 let headers = vec![
138 Line::from(vec![
139 "From: ".set_style(theme.header),
140 email.from.set_style(theme.header_value),
141 ]),
142 Line::from(vec![
143 "Subject: ".set_style(theme.header),
144 email.subject.set_style(theme.header_value),
145 ]),
146 "-".repeat(inner.width as usize).dim().into(),
147 ];
148 Paragraph::new(headers)
149 .style(theme.body)
150 .render(headers_area, buf);
151 let body = email.body.lines().map(Line::from).collect_vec();
152 Paragraph::new(body)
153 .style(theme.body)
154 .render(body_area, buf);
155 } else {
156 Paragraph::new("No email selected").render(inner, buf);
157 }
158}
Trait Implementations§
Source§impl WidgetRef for Block<'_>
impl WidgetRef for Block<'_>
Source§fn render_ref(&self, area: Rect, buf: &mut Buffer)
fn render_ref(&self, area: Rect, buf: &mut Buffer)
unstable-widget-ref
only.impl<'a> Eq for Block<'a>
impl<'a> StructuralPartialEq for Block<'a>
Auto Trait Implementations§
impl<'a> Freeze for Block<'a>
impl<'a> RefUnwindSafe for Block<'a>
impl<'a> Send for Block<'a>
impl<'a> Sync for Block<'a>
impl<'a> Unpin for Block<'a>
impl<'a> UnwindSafe for Block<'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<'a, T, U> Stylize<'a, T> for Uwhere
U: Styled<Item = T>,
impl<'a, T, U> Stylize<'a, T> for Uwhere
U: Styled<Item = T>,
fn bg<C>(self, color: C) -> T
fn fg<C>(self, color: C) -> T
fn add_modifier(self, modifier: Modifier) -> T
fn remove_modifier(self, modifier: Modifier) -> T
fn reset(self) -> T
Source§fn on_magenta(self) -> T
fn on_magenta(self) -> T
magenta
.Source§fn on_dark_gray(self) -> T
fn on_dark_gray(self) -> T
dark_gray
.Source§fn on_light_red(self) -> T
fn on_light_red(self) -> T
light_red
.Source§fn light_green(self) -> T
fn light_green(self) -> T
light_green
.Source§fn on_light_green(self) -> T
fn on_light_green(self) -> T
light_green
.Source§fn light_yellow(self) -> T
fn light_yellow(self) -> T
light_yellow
.Source§fn on_light_yellow(self) -> T
fn on_light_yellow(self) -> T
light_yellow
.Source§fn light_blue(self) -> T
fn light_blue(self) -> T
light_blue
.Source§fn on_light_blue(self) -> T
fn on_light_blue(self) -> T
light_blue
.Source§fn light_magenta(self) -> T
fn light_magenta(self) -> T
light_magenta
.Source§fn on_light_magenta(self) -> T
fn on_light_magenta(self) -> T
light_magenta
.Source§fn light_cyan(self) -> T
fn light_cyan(self) -> T
light_cyan
.Source§fn on_light_cyan(self) -> T
fn on_light_cyan(self) -> T
light_cyan
.Source§fn not_italic(self) -> T
fn not_italic(self) -> T
ITALIC
modifier.Source§fn underlined(self) -> T
fn underlined(self) -> T
UNDERLINED
modifier.Source§fn not_underlined(self) -> T
fn not_underlined(self) -> T
UNDERLINED
modifier.Source§fn slow_blink(self) -> T
fn slow_blink(self) -> T
SLOW_BLINK
modifier.Source§fn not_slow_blink(self) -> T
fn not_slow_blink(self) -> T
SLOW_BLINK
modifier.Source§fn rapid_blink(self) -> T
fn rapid_blink(self) -> T
RAPID_BLINK
modifier.Source§fn not_rapid_blink(self) -> T
fn not_rapid_blink(self) -> T
RAPID_BLINK
modifier.Source§fn not_reversed(self) -> T
fn not_reversed(self) -> T
REVERSED
modifier.HIDDEN
modifier.HIDDEN
modifier.Source§fn crossed_out(self) -> T
fn crossed_out(self) -> T
CROSSED_OUT
modifier.Source§fn not_crossed_out(self) -> T
fn not_crossed_out(self) -> T
CROSSED_OUT
modifier.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