From d726e928d2004d2a99caeeb00b95ce27dbc04bc0 Mon Sep 17 00:00:00 2001 From: Eeelco <43313055+Eeelco@users.noreply.github.com> Date: Wed, 24 Jan 2024 12:31:52 +0100 Subject: [PATCH] feat(Paragraph): add alignment convenience functions (#866) Added convenience functions left_aligned(), centered() and right_aligned() plus unit tests. Updated example code. Signed-off-by: Eelco Empting --- examples/colors_rgb.rs | 3 +- examples/constraints.rs | 6 ++-- examples/demo2/root.rs | 2 +- examples/flex.rs | 6 ++-- examples/list.rs | 4 +-- examples/panic.rs | 2 +- examples/paragraph.rs | 4 +-- examples/popup.rs | 2 +- examples/table.rs | 2 +- src/widgets/paragraph.rs | 65 +++++++++++++++++++++++++++++++++++++++- 10 files changed, 77 insertions(+), 19 deletions(-) diff --git a/examples/colors_rgb.rs b/examples/colors_rgb.rs index 2de989c9..75850789 100644 --- a/examples/colors_rgb.rs +++ b/examples/colors_rgb.rs @@ -143,8 +143,7 @@ impl Default for Fps { impl<'a> AppWidget<'a> { fn new(app: &'a App) -> Self { - let title = - Paragraph::new("colors_rgb example. Press q to quit").alignment(Alignment::Center); + let title = Paragraph::new("colors_rgb example. Press q to quit").centered(); Self { title, fps_widget: FpsWidget { fps: &app.fps }, diff --git a/examples/constraints.rs b/examples/constraints.rs index c012104c..e48e164c 100644 --- a/examples/constraints.rs +++ b/examples/constraints.rs @@ -183,7 +183,7 @@ impl App { width = width - width_label.len() / 2 ); Paragraph::new(width_bar.dark_gray()) - .alignment(Alignment::Center) + .centered() .block(Block::default().padding(Padding { left: 0, right: 0, @@ -418,9 +418,7 @@ impl Example { .border_set(symbols::border::QUADRANT_OUTSIDE) .border_style(Style::reset().fg(color).reversed()) .style(Style::default().fg(fg).bg(color)); - Paragraph::new(text) - .alignment(Alignment::Center) - .block(block) + Paragraph::new(text).centered().block(block) } } diff --git a/examples/demo2/root.rs b/examples/demo2/root.rs index 64de1cb6..57833cd9 100644 --- a/examples/demo2/root.rs +++ b/examples/demo2/root.rs @@ -71,7 +71,7 @@ impl Root<'_> { }) .collect_vec(); Paragraph::new(Line::from(spans)) - .alignment(Alignment::Center) + .centered() .fg(Color::Indexed(236)) .bg(Color::Indexed(232)) .render(area, buf); diff --git a/examples/flex.rs b/examples/flex.rs index 2d7854ad..31b2b23f 100644 --- a/examples/flex.rs +++ b/examples/flex.rs @@ -251,7 +251,7 @@ impl App { }; let bar_width = width - 2; // we want to `<` and `>` at the ends let width_bar = format!("<{label:-^bar_width$}>"); - Paragraph::new(width_bar.dark_gray()).alignment(Alignment::Center) + Paragraph::new(width_bar.dark_gray()).centered() } /// Render the demo content @@ -416,9 +416,7 @@ impl Example { .border_set(symbols::border::QUADRANT_OUTSIDE) .border_style(Style::reset().fg(main_color).reversed()) .style(Style::default().fg(fg_color).bg(main_color)); - Paragraph::new(text) - .alignment(Alignment::Center) - .block(block) + Paragraph::new(text).centered().block(block) } } diff --git a/examples/list.rs b/examples/list.rs index 64af79a1..3f49afea 100644 --- a/examples/list.rs +++ b/examples/list.rs @@ -173,7 +173,7 @@ impl App<'_> { fn render_title(&self, area: Rect, buf: &mut Buffer) { Paragraph::new("Ratatui List Example") .bold() - .alignment(Alignment::Center) + .centered() .render(area, buf); } @@ -268,7 +268,7 @@ impl App<'_> { Paragraph::new( "\nUse ↓↑ to move, ← to unselect, → to change status, g/G to go top/bottom.", ) - .alignment(Alignment::Center) + .centered() .render(area, buf); } } diff --git a/examples/panic.rs b/examples/panic.rs index 33a8b27a..ae8562ae 100644 --- a/examples/panic.rs +++ b/examples/panic.rs @@ -128,7 +128,7 @@ fn ui(f: &mut Frame, app: &App) { .title("Panic Handler Demo") .borders(Borders::ALL); - let p = Paragraph::new(text).block(b).alignment(Alignment::Center); + let p = Paragraph::new(text).block(b).centered(); f.render_widget(p, f.size()); } diff --git a/examples/paragraph.rs b/examples/paragraph.rs index 8b8a9709..66066f5d 100644 --- a/examples/paragraph.rs +++ b/examples/paragraph.rs @@ -132,14 +132,14 @@ fn ui(f: &mut Frame, app: &App) { let paragraph = Paragraph::new(text.clone()) .style(Style::default().fg(Color::Gray)) .block(create_block("Right alignment, with wrap")) - .alignment(Alignment::Right) + .right_aligned() .wrap(Wrap { trim: true }); f.render_widget(paragraph, layout[2]); let paragraph = Paragraph::new(text) .style(Style::default().fg(Color::Gray)) .block(create_block("Center alignment, with wrap, with scroll")) - .alignment(Alignment::Center) + .centered() .wrap(Wrap { trim: true }) .scroll((app.scroll, 0)); f.render_widget(paragraph, layout[3]); diff --git a/examples/popup.rs b/examples/popup.rs index 26ac49d3..912a13dc 100644 --- a/examples/popup.rs +++ b/examples/popup.rs @@ -73,7 +73,7 @@ fn ui(f: &mut Frame, app: &App) { "Press p to show the popup" }; let paragraph = Paragraph::new(text.slow_blink()) - .alignment(Alignment::Center) + .centered() .wrap(Wrap { trim: true }); f.render_widget(paragraph, instructions); diff --git a/examples/table.rs b/examples/table.rs index b2ec5767..aaf63e71 100644 --- a/examples/table.rs +++ b/examples/table.rs @@ -313,7 +313,7 @@ fn render_scrollbar(f: &mut Frame, app: &mut App, area: Rect) { fn render_footer(f: &mut Frame, app: &mut App, area: Rect) { let info_footer = Paragraph::new(Line::from(INFO_TEXT)) .style(Style::new().fg(app.colors.row_fg).bg(app.colors.buffer_bg)) - .alignment(Alignment::Center) + .centered() .block( Block::default() .borders(Borders::ALL) diff --git a/src/widgets/paragraph.rs b/src/widgets/paragraph.rs index 80a41623..299c6b98 100644 --- a/src/widgets/paragraph.rs +++ b/src/widgets/paragraph.rs @@ -194,7 +194,7 @@ impl<'a> Paragraph<'a> { /// Set the text alignment for the given paragraph /// /// The alignment is a variant of the [`Alignment`] enum which can be one of Left, Right, or - /// Center. + /// Center. If no alignment is specified, the text in a paragraph will be left-aligned. /// /// # Example /// @@ -208,6 +208,51 @@ impl<'a> Paragraph<'a> { self } + /// Left-aligns the text in the given paragraph. + /// + /// Convenience shortcut for `Paragraph::alignment(Alignment::Left)`. + /// + /// # Examples + /// + /// ```rust + /// # use ratatui::{prelude::*, widgets::*}; + /// let paragraph = Paragraph::new("Hello World").left_aligned(); + /// ``` + #[must_use = "method moves the value of self and returns the modified value"] + pub fn left_aligned(self) -> Self { + self.alignment(Alignment::Left) + } + + /// Center-aligns the text in the given paragraph. + /// + /// Convenience shortcut for `Paragraph::alignment(Alignment::Center)`. + /// + /// # Examples + /// + /// ```rust + /// # use ratatui::{prelude::*, widgets::*}; + /// let paragraph = Paragraph::new("Hello World").centered(); + /// ``` + #[must_use = "method moves the value of self and returns the modified value"] + pub fn centered(self) -> Self { + self.alignment(Alignment::Center) + } + + /// Right-aligns the text in the given paragraph. + /// + /// Convenience shortcut for `Paragraph::alignment(Alignment::Right)`. + /// + /// # Examples + /// + /// ```rust + /// # use ratatui::{prelude::*, widgets::*}; + /// let paragraph = Paragraph::new("Hello World").right_aligned(); + /// ``` + #[must_use = "method moves the value of self and returns the modified value"] + pub fn right_aligned(self) -> Self { + self.alignment(Alignment::Right) + } + /// Calculates the number of lines needed to fully render. /// /// Given a max line width, this method calculates the number of lines that a paragraph will @@ -922,4 +967,22 @@ mod test { let paragraph = paragraph.wrap(Wrap { trim: true }); assert_eq!(paragraph.line_width(), 1200); } + + #[test] + fn left_aligned() { + let p = Paragraph::new("Hello, world!").left_aligned(); + assert_eq!(p.alignment, Alignment::Left); + } + + #[test] + fn centered() { + let p = Paragraph::new("Hello, world!").centered(); + assert_eq!(p.alignment, Alignment::Center); + } + + #[test] + fn right_aligned() { + let p = Paragraph::new("Hello, world!").right_aligned(); + assert_eq!(p.alignment, Alignment::Right); + } }