diff --git a/benches/main/block.rs b/benches/main/block.rs index abd3da7f..fa2d173b 100644 --- a/benches/main/block.rs +++ b/benches/main/block.rs @@ -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), ); } diff --git a/examples/block.rs b/examples/block.rs index 0297d643..251831ac 100644 --- a/examples/block.rs +++ b/examples/block.rs @@ -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); } diff --git a/examples/chart.rs b/examples/chart.rs index 18dec88c..5bf56409 100644 --- a/examples/chart.rs +++ b/examples/chart.rs @@ -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") diff --git a/examples/flex.rs b/examples/flex.rs index bfa2dcc9..b7665901 100644 --- a/examples/flex.rs +++ b/examples/flex.rs @@ -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) diff --git a/examples/gauge.rs b/examples/gauge.rs index f72916cb..1b4a5ddf 100644 --- a/examples/gauge.rs +++ b/examples/gauge.rs @@ -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)) diff --git a/examples/inline.rs b/examples/inline.rs index 5e21e980..c71df892 100644 --- a/examples/inline.rs +++ b/examples/inline.rs @@ -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); diff --git a/examples/line_gauge.rs b/examples/line_gauge.rs index ee40696f..d9118b48 100644 --- a/examples/line_gauge.rs +++ b/examples/line_gauge.rs @@ -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)) diff --git a/src/widgets/block.rs b/src/widgets/block.rs index 4203f1bd..eb9562a8 100644 --- a/src/widgets/block.rs +++ b/src/widgets/block.rs @@ -243,9 +243,9 @@ impl<'a> Block<'a> { /// [spans](crate::text::Span) (`Vec`). /// /// 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,6 +288,13 @@ impl<'a> Block<'a> { /// - [`Block::title_alignment`] /// - [`Block::title_position`] /// + /// # Future improvements + /// + /// In a future release of Ratatui (likely 0.31) this method will be changed to accept + /// `Into` instead of `Into`. 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 @@ -393,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"); /// ``` @@ -423,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"); /// ``` @@ -648,7 +655,7 @@ impl<'a> Block<'a> { fn has_title_at_position(&self, position: Position) -> bool { self.titles .iter() - .any(|(pos, _)| pos.unwrap_or(self.titles_position.into()) == position) + .any(|(pos, _)| pos.unwrap_or(self.titles_position) == position) } } @@ -894,7 +901,7 @@ impl Block<'_> { ) -> impl DoubleEndedIterator<Item = &Line> { self.titles .iter() - .filter(move |(pos, _)| pos.unwrap_or(self.titles_position.into()) == position.into()) + .filter(move |(pos, _)| pos.unwrap_or(self.titles_position) == position) .filter(move |(_, line)| line.alignment.unwrap_or(self.titles_alignment) == alignment) .map(|(_, line)| line) } @@ -1030,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); } @@ -1057,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")) @@ -1090,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)) @@ -1137,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)); } @@ -1165,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); } @@ -1317,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)) @@ -1382,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])); } diff --git a/src/widgets/block/title.rs b/src/widgets/block/title.rs index f07fff6b..bf877815 100644 --- a/src/widgets/block/title.rs +++ b/src/widgets/block/title.rs @@ -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 (likely 0.31). 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 (likely 0.31)."] impl<'a> Title<'a> { /// Set the title content. #[must_use = "method moves the value of self and returns the modified value"] diff --git a/tests/widgets_block.rs b/tests/widgets_block.rs index 245d5d95..d5e0c8cb 100644 --- a/tests/widgets_block.rs +++ b/tests/widgets_block.rs @@ -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