mirror of
https://github.com/ratatui-org/ratatui
synced 2024-11-22 04:33:13 +00:00
chore(block): deprecate block::Title (#1372)
`ratatui::widgets::block::Title` is deprecated in favor of using `Line` to represent titles. This removes an unnecessary layer of wrapping (string -> Span -> Line -> Title). This struct will be removed in a future release of Ratatui (likely 0.31). For more information see: <https://github.com/ratatui/ratatui/issues/738> To update your code: ```rust Block::new().title(Title::from("foo")); // becomes any of Block::new().title("foo"); Block::new().title(Line::from("foo")); Block::new().title(Title::from("foo").position(Position::TOP)); // becomes any of Block::new().title_top("foo"); Block::new().title_top(Line::from("foo")); Block::new().title(Title::from("foo").position(Position::BOTTOM)); // becomes any of Block::new().title_bottom("foo"); Block::new().title_bottom(Line::from("foo")); ```
This commit is contained in:
parent
b9653ba05a
commit
67c0ea243b
10 changed files with 133 additions and 176 deletions
|
@ -2,10 +2,8 @@ use criterion::{criterion_group, BatchSize, Bencher, Criterion};
|
|||
use ratatui::{
|
||||
buffer::Buffer,
|
||||
layout::{Alignment, Rect},
|
||||
widgets::{
|
||||
block::{Position, Title},
|
||||
Block, Padding, Widget,
|
||||
},
|
||||
text::Line,
|
||||
widgets::{Block, Padding, Widget},
|
||||
};
|
||||
|
||||
/// Benchmark for rendering a block.
|
||||
|
@ -32,11 +30,7 @@ fn block(c: &mut Criterion) {
|
|||
&Block::bordered()
|
||||
.padding(Padding::new(5, 5, 2, 2))
|
||||
.title("test title")
|
||||
.title(
|
||||
Title::from("bottom left title")
|
||||
.alignment(Alignment::Right)
|
||||
.position(Position::Bottom),
|
||||
),
|
||||
.title_bottom(Line::from("bottom left title").alignment(Alignment::Right)),
|
||||
|b, block| render(b, block, buffer_size),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -19,10 +19,7 @@ use ratatui::{
|
|||
layout::{Alignment, Constraint, Layout, Rect},
|
||||
style::{Style, Stylize},
|
||||
text::Line,
|
||||
widgets::{
|
||||
block::{Position, Title},
|
||||
Block, BorderType, Borders, Padding, Paragraph, Wrap,
|
||||
},
|
||||
widgets::{Block, BorderType, Borders, Padding, Paragraph, Wrap},
|
||||
DefaultTerminal, Frame,
|
||||
};
|
||||
|
||||
|
@ -164,36 +161,12 @@ fn render_multiple_titles(paragraph: &Paragraph, frame: &mut Frame, area: Rect)
|
|||
|
||||
fn render_multiple_title_positions(paragraph: &Paragraph, frame: &mut Frame, area: Rect) {
|
||||
let block = Block::bordered()
|
||||
.title(
|
||||
Title::from("top left")
|
||||
.position(Position::Top)
|
||||
.alignment(Alignment::Left),
|
||||
)
|
||||
.title(
|
||||
Title::from("top center")
|
||||
.position(Position::Top)
|
||||
.alignment(Alignment::Center),
|
||||
)
|
||||
.title(
|
||||
Title::from("top right")
|
||||
.position(Position::Top)
|
||||
.alignment(Alignment::Right),
|
||||
)
|
||||
.title(
|
||||
Title::from("bottom left")
|
||||
.position(Position::Bottom)
|
||||
.alignment(Alignment::Left),
|
||||
)
|
||||
.title(
|
||||
Title::from("bottom center")
|
||||
.position(Position::Bottom)
|
||||
.alignment(Alignment::Center),
|
||||
)
|
||||
.title(
|
||||
Title::from("bottom right")
|
||||
.position(Position::Bottom)
|
||||
.alignment(Alignment::Right),
|
||||
);
|
||||
.title(Line::from("top left").left_aligned())
|
||||
.title(Line::from("top center").centered())
|
||||
.title(Line::from("top right").right_aligned())
|
||||
.title_bottom(Line::from("bottom left").left_aligned())
|
||||
.title_bottom(Line::from("bottom center").centered())
|
||||
.title_bottom(Line::from("bottom right").right_aligned());
|
||||
frame.render_widget(paragraph.clone().block(block), area);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@ use std::time::{Duration, Instant};
|
|||
use color_eyre::Result;
|
||||
use ratatui::{
|
||||
crossterm::event::{self, Event, KeyCode},
|
||||
layout::{Alignment, Constraint, Layout, Rect},
|
||||
layout::{Constraint, Layout, Rect},
|
||||
style::{Color, Modifier, Style, Stylize},
|
||||
symbols::{self, Marker},
|
||||
text::Span,
|
||||
widgets::{block::Title, Axis, Block, Chart, Dataset, GraphType, LegendPosition},
|
||||
text::{Line, Span},
|
||||
widgets::{Axis, Block, Chart, Dataset, GraphType, LegendPosition},
|
||||
DefaultTerminal, Frame,
|
||||
};
|
||||
|
||||
|
@ -196,13 +196,7 @@ fn render_barchart(frame: &mut Frame, bar_chart: Rect) {
|
|||
]);
|
||||
|
||||
let chart = Chart::new(vec![dataset])
|
||||
.block(
|
||||
Block::bordered().title(
|
||||
Title::default()
|
||||
.content("Bar chart".cyan().bold())
|
||||
.alignment(Alignment::Center),
|
||||
),
|
||||
)
|
||||
.block(Block::bordered().title_top(Line::from("Bar chart").cyan().bold().centered()))
|
||||
.x_axis(
|
||||
Axis::default()
|
||||
.style(Style::default().gray())
|
||||
|
@ -229,13 +223,7 @@ fn render_line_chart(frame: &mut Frame, area: Rect) {
|
|||
.data(&[(1., 1.), (4., 4.)])];
|
||||
|
||||
let chart = Chart::new(datasets)
|
||||
.block(
|
||||
Block::bordered().title(
|
||||
Title::default()
|
||||
.content("Line chart".cyan().bold())
|
||||
.alignment(Alignment::Center),
|
||||
),
|
||||
)
|
||||
.block(Block::bordered().title(Line::from("Line chart").cyan().bold().centered()))
|
||||
.x_axis(
|
||||
Axis::default()
|
||||
.title("X Axis")
|
||||
|
@ -279,13 +267,7 @@ fn render_scatter(frame: &mut Frame, area: Rect) {
|
|||
];
|
||||
|
||||
let chart = Chart::new(datasets)
|
||||
.block(
|
||||
Block::bordered().title(
|
||||
Title::default()
|
||||
.content("Scatter chart".cyan().bold())
|
||||
.alignment(Alignment::Center),
|
||||
),
|
||||
)
|
||||
.block(Block::bordered().title(Line::from("Scatter chart").cyan().bold().centered()))
|
||||
.x_axis(
|
||||
Axis::default()
|
||||
.title("Year")
|
||||
|
|
|
@ -28,8 +28,8 @@ use ratatui::{
|
|||
symbols::{self, line},
|
||||
text::{Line, Text},
|
||||
widgets::{
|
||||
block::Title, Block, Paragraph, Scrollbar, ScrollbarOrientation, ScrollbarState,
|
||||
StatefulWidget, Tabs, Widget,
|
||||
Block, Paragraph, Scrollbar, ScrollbarOrientation, ScrollbarState, StatefulWidget, Tabs,
|
||||
Widget,
|
||||
},
|
||||
DefaultTerminal,
|
||||
};
|
||||
|
@ -273,7 +273,7 @@ impl App {
|
|||
fn tabs(self) -> impl Widget {
|
||||
let tab_titles = SelectedTab::iter().map(SelectedTab::to_tab_title);
|
||||
let block = Block::new()
|
||||
.title(Title::from("Flex Layouts ".bold()))
|
||||
.title("Flex Layouts ".bold())
|
||||
.title(" Use ◄ ► to change tab, ▲ ▼ to scroll, - + to change spacing ");
|
||||
Tabs::new(tab_titles)
|
||||
.block(block)
|
||||
|
|
|
@ -21,8 +21,8 @@ use ratatui::{
|
|||
crossterm::event::{self, Event, KeyCode, KeyEventKind},
|
||||
layout::{Alignment, Constraint, Layout, Rect},
|
||||
style::{palette::tailwind, Color, Style, Stylize},
|
||||
text::Span,
|
||||
widgets::{block::Title, Block, Borders, Gauge, Padding, Paragraph, Widget},
|
||||
text::{Line, Span},
|
||||
widgets::{Block, Borders, Gauge, Padding, Paragraph, Widget},
|
||||
DefaultTerminal,
|
||||
};
|
||||
|
||||
|
@ -196,7 +196,7 @@ impl App {
|
|||
}
|
||||
|
||||
fn title_block(title: &str) -> Block {
|
||||
let title = Title::from(title).alignment(Alignment::Center);
|
||||
let title = Line::from(title).centered();
|
||||
Block::new()
|
||||
.borders(Borders::NONE)
|
||||
.padding(Padding::vertical(1))
|
||||
|
|
|
@ -25,11 +25,11 @@ use rand::distributions::{Distribution, Uniform};
|
|||
use ratatui::{
|
||||
backend::Backend,
|
||||
crossterm::event,
|
||||
layout::{Alignment, Constraint, Layout, Rect},
|
||||
layout::{Constraint, Layout, Rect},
|
||||
style::{Color, Modifier, Style},
|
||||
symbols,
|
||||
text::{Line, Span},
|
||||
widgets::{block, Block, Gauge, LineGauge, List, ListItem, Paragraph, Widget},
|
||||
widgets::{Block, Gauge, LineGauge, List, ListItem, Paragraph, Widget},
|
||||
Frame, Terminal, TerminalOptions, Viewport,
|
||||
};
|
||||
|
||||
|
@ -231,7 +231,7 @@ fn run(
|
|||
fn draw(frame: &mut Frame, downloads: &Downloads) {
|
||||
let area = frame.area();
|
||||
|
||||
let block = Block::new().title(block::Title::from("Progress").alignment(Alignment::Center));
|
||||
let block = Block::new().title(Line::from("Progress").centered());
|
||||
frame.render_widget(block, area);
|
||||
|
||||
let vertical = Layout::vertical([Constraint::Length(2), Constraint::Length(4)]).margin(1);
|
||||
|
|
|
@ -21,7 +21,8 @@ use ratatui::{
|
|||
crossterm::event::{self, Event, KeyCode, KeyEventKind},
|
||||
layout::{Alignment, Constraint, Layout, Rect},
|
||||
style::{palette::tailwind, Color, Style, Stylize},
|
||||
widgets::{block::Title, Block, Borders, LineGauge, Padding, Paragraph, Widget},
|
||||
text::Line,
|
||||
widgets::{Block, Borders, LineGauge, Padding, Paragraph, Widget},
|
||||
DefaultTerminal,
|
||||
};
|
||||
|
||||
|
@ -170,9 +171,8 @@ impl App {
|
|||
}
|
||||
|
||||
fn title_block(title: &str) -> Block {
|
||||
let title = Title::from(title).alignment(Alignment::Center);
|
||||
Block::default()
|
||||
.title(title)
|
||||
.title(Line::from(title).centered())
|
||||
.borders(Borders::NONE)
|
||||
.fg(CUSTOM_LABEL_COLOR)
|
||||
.padding(Padding::vertical(1))
|
||||
|
|
|
@ -108,7 +108,7 @@ pub use title::{Position, Title};
|
|||
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Block<'a> {
|
||||
/// List of titles
|
||||
titles: Vec<Title<'a>>,
|
||||
titles: Vec<(Option<Position>, Line<'a>)>,
|
||||
/// The style to be patched to all titles of the block
|
||||
titles_style: Style,
|
||||
/// The default alignment of the titles that don't have one
|
||||
|
@ -243,9 +243,9 @@ impl<'a> Block<'a> {
|
|||
/// [spans](crate::text::Span) (`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.
|
||||
/// 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.
|
||||
///
|
||||
/// ```plain
|
||||
/// ┌With at least a left border───
|
||||
|
@ -274,9 +274,9 @@ impl<'a> Block<'a> {
|
|||
///
|
||||
/// Block::new()
|
||||
/// .title("Title") // By default in the top left corner
|
||||
/// .title(Title::from("Left").alignment(Alignment::Left)) // also on the left
|
||||
/// .title(Title::from("Right").alignment(Alignment::Right))
|
||||
/// .title(Title::from("Center").alignment(Alignment::Center));
|
||||
/// .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┐
|
||||
/// ```
|
||||
|
@ -288,13 +288,26 @@ impl<'a> Block<'a> {
|
|||
/// - [`Block::title_alignment`]
|
||||
/// - [`Block::title_position`]
|
||||
///
|
||||
/// # 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>.
|
||||
///
|
||||
/// [Block example]: https://github.com/ratatui/ratatui/blob/main/examples/README.md#block
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn title<T>(mut self, title: T) -> Self
|
||||
where
|
||||
T: Into<Title<'a>>,
|
||||
{
|
||||
self.titles.push(title.into());
|
||||
let title = title.into();
|
||||
let position = title.position;
|
||||
let mut content = title.content;
|
||||
if let Some(alignment) = title.alignment {
|
||||
content = content.alignment(alignment);
|
||||
}
|
||||
self.titles.push((position, content));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -321,8 +334,8 @@ impl<'a> Block<'a> {
|
|||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn title_top<T: Into<Line<'a>>>(mut self, title: T) -> Self {
|
||||
let title = Title::from(title).position(Position::Top);
|
||||
self.titles.push(title);
|
||||
let line = title.into();
|
||||
self.titles.push((Some(Position::Top), line));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -349,8 +362,8 @@ impl<'a> Block<'a> {
|
|||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn title_bottom<T: Into<Line<'a>>>(mut self, title: T) -> Self {
|
||||
let title = Title::from(title).position(Position::Bottom);
|
||||
self.titles.push(title);
|
||||
let line = title.into();
|
||||
self.titles.push((Some(Position::Bottom), line));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -387,7 +400,7 @@ impl<'a> Block<'a> {
|
|||
/// Block::new()
|
||||
/// .title_alignment(Alignment::Center)
|
||||
/// // This title won't be aligned in the center
|
||||
/// .title(Title::from("right").alignment(Alignment::Right))
|
||||
/// .title(Line::from("right").right_aligned())
|
||||
/// .title("foo")
|
||||
/// .title("bar");
|
||||
/// ```
|
||||
|
@ -417,7 +430,7 @@ impl<'a> Block<'a> {
|
|||
/// Block::new()
|
||||
/// .title_position(Position::Bottom)
|
||||
/// // This title won't be aligned in the center
|
||||
/// .title(Title::from("top").position(Position::Top))
|
||||
/// .title_top("top")
|
||||
/// .title("foo")
|
||||
/// .title("bar");
|
||||
/// ```
|
||||
|
@ -642,7 +655,7 @@ impl<'a> Block<'a> {
|
|||
fn has_title_at_position(&self, position: Position) -> bool {
|
||||
self.titles
|
||||
.iter()
|
||||
.any(|title| title.position.unwrap_or(self.titles_position) == position)
|
||||
.any(|(pos, _)| pos.unwrap_or(self.titles_position) == position)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -798,7 +811,7 @@ impl Block<'_> {
|
|||
if titles_area.is_empty() {
|
||||
break;
|
||||
}
|
||||
let title_width = title.content.width() as u16;
|
||||
let title_width = title.width() as u16;
|
||||
let title_area = Rect {
|
||||
x: titles_area
|
||||
.right()
|
||||
|
@ -808,7 +821,7 @@ impl Block<'_> {
|
|||
..titles_area
|
||||
};
|
||||
buf.set_style(title_area, self.titles_style);
|
||||
title.content.render_ref(title_area, buf);
|
||||
title.render_ref(title_area, buf);
|
||||
|
||||
// bump the width of the titles area to the left
|
||||
titles_area.width = titles_area
|
||||
|
@ -830,7 +843,7 @@ impl Block<'_> {
|
|||
.collect_vec();
|
||||
let total_width = titles
|
||||
.iter()
|
||||
.map(|title| title.content.width() as u16 + 1) // space between titles
|
||||
.map(|title| title.width() as u16 + 1) // space between titles
|
||||
.sum::<u16>()
|
||||
.saturating_sub(1); // no space for the last title
|
||||
|
||||
|
@ -843,13 +856,13 @@ impl Block<'_> {
|
|||
if titles_area.is_empty() {
|
||||
break;
|
||||
}
|
||||
let title_width = title.content.width() as u16;
|
||||
let title_width = title.width() as u16;
|
||||
let title_area = Rect {
|
||||
width: title_width.min(titles_area.width),
|
||||
..titles_area
|
||||
};
|
||||
buf.set_style(title_area, self.titles_style);
|
||||
title.content.render_ref(title_area, buf);
|
||||
title.render_ref(title_area, buf);
|
||||
|
||||
// bump the titles area to the right and reduce its width
|
||||
titles_area.x = titles_area.x.saturating_add(title_width + 1);
|
||||
|
@ -866,13 +879,13 @@ impl Block<'_> {
|
|||
if titles_area.is_empty() {
|
||||
break;
|
||||
}
|
||||
let title_width = title.content.width() as u16;
|
||||
let title_width = title.width() as u16;
|
||||
let title_area = Rect {
|
||||
width: title_width.min(titles_area.width),
|
||||
..titles_area
|
||||
};
|
||||
buf.set_style(title_area, self.titles_style);
|
||||
title.content.render_ref(title_area, buf);
|
||||
title.render_ref(title_area, buf);
|
||||
|
||||
// bump the titles area to the right and reduce its width
|
||||
titles_area.x = titles_area.x.saturating_add(title_width + 1);
|
||||
|
@ -885,11 +898,12 @@ impl Block<'_> {
|
|||
&self,
|
||||
position: Position,
|
||||
alignment: Alignment,
|
||||
) -> impl DoubleEndedIterator<Item = &Title> {
|
||||
self.titles.iter().filter(move |title| {
|
||||
title.position.unwrap_or(self.titles_position) == position
|
||||
&& title.alignment.unwrap_or(self.titles_alignment) == alignment
|
||||
})
|
||||
) -> impl DoubleEndedIterator<Item = &Line> {
|
||||
self.titles
|
||||
.iter()
|
||||
.filter(move |(pos, _)| pos.unwrap_or(self.titles_position) == position)
|
||||
.filter(move |(_, line)| line.alignment.unwrap_or(self.titles_alignment) == alignment)
|
||||
.map(|(_, line)| line)
|
||||
}
|
||||
|
||||
/// An area that is one line tall and spans the width of the block excluding the borders and
|
||||
|
@ -1023,24 +1037,17 @@ mod tests {
|
|||
let area = Rect::new(0, 0, 0, 1);
|
||||
let expected = Rect::new(0, 1, 0, 0);
|
||||
|
||||
let block = Block::new().title(Title::from("Test").alignment(alignment));
|
||||
let block = Block::new().title(Line::from("Test").alignment(alignment));
|
||||
assert_eq!(block.inner(area), expected);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case::top_top(Borders::TOP, Position::Top, Rect::new(0, 1, 0, 1))]
|
||||
#[case::top_bot(Borders::BOTTOM, Position::Top, Rect::new(0, 1, 0, 0))]
|
||||
#[case::bot_top(Borders::TOP, Position::Bottom, Rect::new(0, 1, 0, 0))]
|
||||
#[case::top_top(Borders::BOTTOM, Position::Bottom, Rect::new(0, 0, 0, 1))]
|
||||
fn inner_takes_into_account_border_and_title(
|
||||
#[case] borders: Borders,
|
||||
#[case] position: Position,
|
||||
#[case] expected: Rect,
|
||||
) {
|
||||
#[case::top_top(Block::new().title_top("Test").borders(Borders::TOP), Rect::new(0, 1, 0, 1))]
|
||||
#[case::top_bot(Block::new().title_top("Test").borders(Borders::BOTTOM), Rect::new(0, 1, 0, 0))]
|
||||
#[case::bot_top(Block::new().title_bottom("Test").borders(Borders::TOP), Rect::new(0, 1, 0, 0))]
|
||||
#[case::bot_bot(Block::new().title_bottom("Test").borders(Borders::BOTTOM), Rect::new(0, 0, 0, 1))]
|
||||
fn inner_takes_into_account_border_and_title(#[case] block: Block, #[case] expected: Rect) {
|
||||
let area = Rect::new(0, 0, 0, 2);
|
||||
let block = Block::new()
|
||||
.borders(borders)
|
||||
.title(Title::from("Test").position(position));
|
||||
assert_eq!(block.inner(area), expected);
|
||||
}
|
||||
|
||||
|
@ -1050,32 +1057,33 @@ mod tests {
|
|||
assert!(!block.has_title_at_position(Position::Top));
|
||||
assert!(!block.has_title_at_position(Position::Bottom));
|
||||
|
||||
let block = Block::new().title(Title::from("Test").position(Position::Top));
|
||||
let block = Block::new().title_top("test");
|
||||
assert!(block.has_title_at_position(Position::Top));
|
||||
assert!(!block.has_title_at_position(Position::Bottom));
|
||||
|
||||
let block = Block::new().title(Title::from("Test").position(Position::Bottom));
|
||||
let block = Block::new().title_bottom("test");
|
||||
assert!(!block.has_title_at_position(Position::Top));
|
||||
assert!(block.has_title_at_position(Position::Bottom));
|
||||
|
||||
#[allow(deprecated)] // until Title is removed
|
||||
let block = Block::new()
|
||||
.title(Title::from("Test").position(Position::Top))
|
||||
.title_position(Position::Bottom);
|
||||
assert!(block.has_title_at_position(Position::Top));
|
||||
assert!(!block.has_title_at_position(Position::Bottom));
|
||||
|
||||
#[allow(deprecated)] // until Title is removed
|
||||
let block = Block::new()
|
||||
.title(Title::from("Test").position(Position::Bottom))
|
||||
.title_position(Position::Top);
|
||||
assert!(!block.has_title_at_position(Position::Top));
|
||||
assert!(block.has_title_at_position(Position::Bottom));
|
||||
|
||||
let block = Block::new()
|
||||
.title(Title::from("Test").position(Position::Top))
|
||||
.title(Title::from("Test").position(Position::Bottom));
|
||||
let block = Block::new().title_top("test").title_bottom("test");
|
||||
assert!(block.has_title_at_position(Position::Top));
|
||||
assert!(block.has_title_at_position(Position::Bottom));
|
||||
|
||||
#[allow(deprecated)] // until Title is removed
|
||||
let block = Block::new()
|
||||
.title(Title::from("Test").position(Position::Top))
|
||||
.title(Title::from("Test"))
|
||||
|
@ -1083,6 +1091,7 @@ mod tests {
|
|||
assert!(block.has_title_at_position(Position::Top));
|
||||
assert!(block.has_title_at_position(Position::Bottom));
|
||||
|
||||
#[allow(deprecated)] // until Title is removed
|
||||
let block = Block::new()
|
||||
.title(Title::from("Test"))
|
||||
.title(Title::from("Test").position(Position::Bottom))
|
||||
|
@ -1130,16 +1139,10 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn vertical_space_takes_into_account_titles() {
|
||||
let block = Block::new()
|
||||
.title_position(Position::Top)
|
||||
.title(Title::from("Test"));
|
||||
|
||||
let block = Block::new().title_top("Test");
|
||||
assert_eq!(block.vertical_space(), (1, 0));
|
||||
|
||||
let block = Block::new()
|
||||
.title_position(Position::Bottom)
|
||||
.title(Title::from("Test"));
|
||||
|
||||
let block = Block::new().title_bottom("Test");
|
||||
assert_eq!(block.vertical_space(), (0, 1));
|
||||
}
|
||||
|
||||
|
@ -1158,10 +1161,7 @@ mod tests {
|
|||
#[case] pos: Position,
|
||||
#[case] vertical_space: (u16, u16),
|
||||
) {
|
||||
let block = block
|
||||
.borders(borders)
|
||||
.title_position(pos)
|
||||
.title(Title::from("Test"));
|
||||
let block = block.borders(borders).title_position(pos).title("Test");
|
||||
assert_eq!(block.vertical_space(), vertical_space);
|
||||
}
|
||||
|
||||
|
@ -1310,6 +1310,7 @@ mod tests {
|
|||
use Alignment::*;
|
||||
use Position::*;
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 11, 3));
|
||||
#[allow(deprecated)] // until Title is removed
|
||||
Block::bordered()
|
||||
.title(Title::from("A").position(Top).alignment(Left))
|
||||
.title(Title::from("B").position(Top).alignment(Center))
|
||||
|
@ -1375,7 +1376,7 @@ mod tests {
|
|||
let mut buffer = Buffer::empty(Rect::new(0, 0, 8, 1));
|
||||
Block::new()
|
||||
.title_alignment(block_title_alignment)
|
||||
.title(Title::from("test").alignment(alignment))
|
||||
.title(Line::from("test").alignment(alignment))
|
||||
.render(buffer.area, &mut buffer);
|
||||
assert_eq!(buffer, Buffer::with_lines([expected]));
|
||||
}
|
||||
|
|
|
@ -9,6 +9,17 @@ use crate::{layout::Alignment, text::Line};
|
|||
///
|
||||
/// It can be aligned (see [`Alignment`]) and positioned (see [`Position`]).
|
||||
///
|
||||
/// # Future Deprecation
|
||||
///
|
||||
/// This type is deprecated and will be removed in a future release. The reason for this is that the
|
||||
/// position of the title should be stored in the block itself, not in the title. The `Line` type
|
||||
/// has an alignment method that can be used to align the title. For more information see
|
||||
/// <https://github.com/ratatui/ratatui/issues/738>.
|
||||
///
|
||||
/// Use [`Line`] instead, when the position is not defined as part of the title. When a specific
|
||||
/// position is needed, use [`Block::title_top`](crate::widgets::Block::title_top) or
|
||||
/// [`Block::title_bottom`](crate::widgets::Block::title_bottom) instead.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Title with no style.
|
||||
|
@ -88,6 +99,7 @@ pub enum Position {
|
|||
Bottom,
|
||||
}
|
||||
|
||||
#[deprecated = "use Block::title_top() or Block::title_bottom() instead. This will be removed in a future release."]
|
||||
impl<'a> Title<'a> {
|
||||
/// Set the title content.
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
|
|
|
@ -3,11 +3,8 @@ use ratatui::{
|
|||
buffer::Buffer,
|
||||
layout::{Alignment, Rect},
|
||||
style::{Color, Style},
|
||||
text::Span,
|
||||
widgets::{
|
||||
block::title::{Position, Title},
|
||||
Block, Borders,
|
||||
},
|
||||
text::{Line, Span},
|
||||
widgets::{Block, Borders},
|
||||
Terminal,
|
||||
};
|
||||
use rstest::rstest;
|
||||
|
@ -58,9 +55,9 @@ fn widgets_block_titles_overlap() {
|
|||
// Left overrides the center
|
||||
test_case(
|
||||
Block::new()
|
||||
.title(Title::from("aaaaa").alignment(Alignment::Left))
|
||||
.title(Title::from("bbb").alignment(Alignment::Center))
|
||||
.title(Title::from("ccc").alignment(Alignment::Right)),
|
||||
.title(Line::from("aaaaa").left_aligned())
|
||||
.title(Line::from("bbb").centered())
|
||||
.title(Line::from("ccc").right_aligned()),
|
||||
Rect::new(0, 0, 10, 1),
|
||||
["aaaaab ccc"],
|
||||
);
|
||||
|
@ -68,9 +65,9 @@ fn widgets_block_titles_overlap() {
|
|||
// Left alignment overrides the center alignment which overrides the right alignment
|
||||
test_case(
|
||||
Block::new()
|
||||
.title(Title::from("aaaaa").alignment(Alignment::Left))
|
||||
.title(Title::from("bbbbb").alignment(Alignment::Center))
|
||||
.title(Title::from("ccccc").alignment(Alignment::Right)),
|
||||
.title(Line::from("aaaaa").left_aligned())
|
||||
.title(Line::from("bbbbb").centered())
|
||||
.title(Line::from("ccccc").right_aligned()),
|
||||
Rect::new(0, 0, 11, 1),
|
||||
["aaaaabbbccc"],
|
||||
);
|
||||
|
@ -78,10 +75,10 @@ fn widgets_block_titles_overlap() {
|
|||
// Multiple left alignment overrides the center alignment and the right alignment
|
||||
test_case(
|
||||
Block::new()
|
||||
.title(Title::from("aaaaa").alignment(Alignment::Left))
|
||||
.title(Title::from("aaaaa").alignment(Alignment::Left))
|
||||
.title(Title::from("bbbbb").alignment(Alignment::Center))
|
||||
.title(Title::from("ccccc").alignment(Alignment::Right)),
|
||||
.title(Line::from("aaaaa").left_aligned())
|
||||
.title(Line::from("aaaaa").left_aligned())
|
||||
.title(Line::from("bbbbb").centered())
|
||||
.title(Line::from("ccccc").right_aligned()),
|
||||
Rect::new(0, 0, 11, 1),
|
||||
["aaaaabaaaaa"],
|
||||
);
|
||||
|
@ -89,8 +86,8 @@ fn widgets_block_titles_overlap() {
|
|||
// The right alignment doesn't override the center alignment, but pierces through it
|
||||
test_case(
|
||||
Block::new()
|
||||
.title(Title::from("bbbbb").alignment(Alignment::Center))
|
||||
.title(Title::from("ccccccccccc").alignment(Alignment::Right)),
|
||||
.title(Line::from("bbbbb").centered())
|
||||
.title(Line::from("ccccccccccc").right_aligned()),
|
||||
Rect::new(0, 0, 11, 1),
|
||||
["cccbbbbbccc"],
|
||||
);
|
||||
|
@ -275,7 +272,7 @@ fn widgets_block_title_alignment_top<'line, Lines>(
|
|||
|
||||
let block1 = Block::new()
|
||||
.borders(borders)
|
||||
.title(Title::from(Span::raw("Title")).alignment(alignment));
|
||||
.title(Line::from("Title").alignment(alignment));
|
||||
|
||||
let block2 = Block::new()
|
||||
.borders(borders)
|
||||
|
@ -379,10 +376,8 @@ fn widgets_block_title_alignment_bottom<'line, Lines>(
|
|||
let backend = TestBackend::new(15, 3);
|
||||
let mut terminal = Terminal::new(backend).unwrap();
|
||||
|
||||
let title = Title::from(Span::styled("Title", Style::default()))
|
||||
.alignment(alignment)
|
||||
.position(Position::Bottom);
|
||||
let block = Block::default().title(title).borders(borders);
|
||||
let title = Line::from("Title").alignment(alignment);
|
||||
let block = Block::default().title_bottom(title).borders(borders);
|
||||
let area = Rect::new(1, 0, 13, 3);
|
||||
terminal
|
||||
.draw(|frame| frame.render_widget(block, area))
|
||||
|
@ -391,84 +386,84 @@ fn widgets_block_title_alignment_bottom<'line, Lines>(
|
|||
}
|
||||
|
||||
#[rstest]
|
||||
#[case::left_with_all_borders(Title::from("foo"), Title::from("bar"), Borders::ALL, [
|
||||
#[case::left_with_all_borders(Line::from("foo"), Line::from("bar"), Borders::ALL, [
|
||||
" ┌foo─bar────┐ ",
|
||||
" │ │ ",
|
||||
" └───────────┘ ",
|
||||
])]
|
||||
#[case::left_without_top_border(Title::from("foo"), Title::from("bar"), Borders::LEFT | Borders::BOTTOM | Borders::RIGHT, [
|
||||
#[case::left_without_top_border(Line::from("foo"), Line::from("bar"), Borders::LEFT | Borders::BOTTOM | Borders::RIGHT, [
|
||||
" │foo bar │ ",
|
||||
" │ │ ",
|
||||
" └───────────┘ ",
|
||||
])]
|
||||
#[case::left_without_left_border(Title::from("foo"), Title::from("bar"), Borders::TOP | Borders::RIGHT | Borders::BOTTOM, [
|
||||
#[case::left_without_left_border(Line::from("foo"), Line::from("bar"), Borders::TOP | Borders::RIGHT | Borders::BOTTOM, [
|
||||
" foo─bar─────┐ ",
|
||||
" │ ",
|
||||
" ────────────┘ ",
|
||||
])]
|
||||
#[case::left_without_right_border(Title::from("foo"), Title::from("bar"), Borders::LEFT | Borders::TOP | Borders::BOTTOM, [
|
||||
#[case::left_without_right_border(Line::from("foo"), Line::from("bar"), Borders::LEFT | Borders::TOP | Borders::BOTTOM, [
|
||||
" ┌foo─bar───── ",
|
||||
" │ ",
|
||||
" └──────────── ",
|
||||
])]
|
||||
#[case::left_without_borders(Title::from("foo"), Title::from("bar"), Borders::NONE, [
|
||||
#[case::left_without_borders(Line::from("foo"), Line::from("bar"), Borders::NONE, [
|
||||
" foo bar ",
|
||||
" ",
|
||||
" ",
|
||||
])]
|
||||
#[case::center_with_borders(Title::from("foo").alignment(Alignment::Center), Title::from("bar").alignment(Alignment::Center), Borders::ALL, [
|
||||
#[case::center_with_borders(Line::from("foo").centered(), Line::from("bar").centered(), Borders::ALL, [
|
||||
" ┌──foo─bar──┐ ",
|
||||
" │ │ ",
|
||||
" └───────────┘ ",
|
||||
])]
|
||||
#[case::center_without_top_border(Title::from("foo").alignment(Alignment::Center), Title::from("bar").alignment(Alignment::Center), Borders::LEFT | Borders::BOTTOM | Borders::RIGHT, [
|
||||
#[case::center_without_top_border(Line::from("foo").centered(), Line::from("bar").centered(), Borders::LEFT | Borders::BOTTOM | Borders::RIGHT, [
|
||||
" │ foo bar │ ",
|
||||
" │ │ ",
|
||||
" └───────────┘ ",
|
||||
])]
|
||||
#[case::center_without_left_border(Title::from("foo").alignment(Alignment::Center), Title::from("bar").alignment(Alignment::Center), Borders::TOP | Borders::RIGHT | Borders::BOTTOM, [
|
||||
#[case::center_without_left_border(Line::from("foo").centered(), Line::from("bar").centered(), Borders::TOP | Borders::RIGHT | Borders::BOTTOM, [
|
||||
" ──foo─bar───┐ ",
|
||||
" │ ",
|
||||
" ────────────┘ ",
|
||||
])]
|
||||
#[case::center_without_right_border(Title::from("foo").alignment(Alignment::Center), Title::from("bar").alignment(Alignment::Center), Borders::LEFT | Borders::TOP | Borders::BOTTOM, [
|
||||
#[case::center_without_right_border(Line::from("foo").centered(), Line::from("bar").centered(), Borders::LEFT | Borders::TOP | Borders::BOTTOM, [
|
||||
" ┌──foo─bar─── ",
|
||||
" │ ",
|
||||
" └──────────── ",
|
||||
])]
|
||||
#[case::center_without_borders(Title::from("foo").alignment(Alignment::Center), Title::from("bar").alignment(Alignment::Center), Borders::NONE, [
|
||||
#[case::center_without_borders(Line::from("foo").centered(), Line::from("bar").centered(), Borders::NONE, [
|
||||
" foo bar ",
|
||||
" ",
|
||||
" ",
|
||||
])]
|
||||
#[case::right_with_all_borders(Title::from("foo").alignment(Alignment::Right), Title::from("bar").alignment(Alignment::Right), Borders::ALL, [
|
||||
#[case::right_with_all_borders(Line::from("foo").right_aligned(), Line::from("bar").right_aligned(), Borders::ALL, [
|
||||
" ┌────foo─bar┐ ",
|
||||
" │ │ ",
|
||||
" └───────────┘ ",
|
||||
])]
|
||||
#[case::right_without_top_border(Title::from("foo").alignment(Alignment::Right), Title::from("bar").alignment(Alignment::Right), Borders::LEFT | Borders::BOTTOM | Borders::RIGHT, [
|
||||
#[case::right_without_top_border(Line::from("foo").right_aligned(), Line::from("bar").right_aligned(), Borders::LEFT | Borders::BOTTOM | Borders::RIGHT, [
|
||||
" │ foo bar│ ",
|
||||
" │ │ ",
|
||||
" └───────────┘ ",
|
||||
])]
|
||||
#[case::right_without_left_border(Title::from("foo").alignment(Alignment::Right), Title::from("bar").alignment(Alignment::Right), Borders::TOP | Borders::RIGHT | Borders::BOTTOM, [
|
||||
#[case::right_without_left_border(Line::from("foo").right_aligned(), Line::from("bar").right_aligned(), Borders::TOP | Borders::RIGHT | Borders::BOTTOM, [
|
||||
" ─────foo─bar┐ ",
|
||||
" │ ",
|
||||
" ────────────┘ ",
|
||||
])]
|
||||
#[case::right_without_right_border(Title::from("foo").alignment(Alignment::Right), Title::from("bar").alignment(Alignment::Right), Borders::LEFT | Borders::TOP | Borders::BOTTOM, [
|
||||
#[case::right_without_right_border(Line::from("foo").right_aligned(), Line::from("bar").right_aligned(), Borders::LEFT | Borders::TOP | Borders::BOTTOM, [
|
||||
" ┌─────foo─bar ",
|
||||
" │ ",
|
||||
" └──────────── ",
|
||||
])]
|
||||
#[case::right_without_borders(Title::from("foo").alignment(Alignment::Right), Title::from("bar").alignment(Alignment::Right), Borders::NONE, [
|
||||
#[case::right_without_borders(Line::from("foo").right_aligned(), Line::from("bar").right_aligned(), Borders::NONE, [
|
||||
" foo bar ",
|
||||
" ",
|
||||
" ",
|
||||
])]
|
||||
fn widgets_block_multiple_titles<'line, Lines>(
|
||||
#[case] title_a: Title,
|
||||
#[case] title_b: Title,
|
||||
#[case] title_a: Line,
|
||||
#[case] title_b: Line,
|
||||
#[case] borders: Borders,
|
||||
#[case] expected: Lines,
|
||||
) where
|
||||
|
|
Loading…
Reference in a new issue