From d125f5ce815ac1d6e277d2b600177c1c6e7ee7d3 Mon Sep 17 00:00:00 2001 From: Chris Bouchard Date: Sat, 26 Nov 2022 23:20:24 -0500 Subject: [PATCH 1/5] Move the `Text` component into a submodule I want to introduce a submodule for alignment, but then I'll need to make the `text` module public, which will expose the public `Text` component definition, resulting in it appearing in two different modules. To avoid confusion, I've moved it to a new `text::component` submodule, only visible to super, like we have with `stack::horizontal` and `stack::vertical`. I'm not at all sold on the name `component`, but I can't think of anything better at the moment -- I thought of using the component name, but `text::text` seemed more confusing than helpful (and Clippy warns about it). --- intuitive/src/components/mod.rs | 2 +- intuitive/src/components/text/component.rs | 45 +++++++++++++++++++++ intuitive/src/components/text/mod.rs | 46 +--------------------- 3 files changed, 48 insertions(+), 45 deletions(-) create mode 100644 intuitive/src/components/text/component.rs diff --git a/intuitive/src/components/mod.rs b/intuitive/src/components/mod.rs index d2cf283..2e19bb0 100644 --- a/intuitive/src/components/mod.rs +++ b/intuitive/src/components/mod.rs @@ -212,7 +212,7 @@ pub use self::{ empty::Empty, section::Section, stack::{horizontal::Stack as HStack, vertical::Stack as VStack}, - text::Text, + text::component::Text, }; use crate::element::Any as AnyElement; diff --git a/intuitive/src/components/text/component.rs b/intuitive/src/components/text/component.rs new file mode 100644 index 0000000..2dae214 --- /dev/null +++ b/intuitive/src/components/text/component.rs @@ -0,0 +1,45 @@ +use tui::{text::Spans as TuiSpans, widgets::Paragraph}; + +use crate::{ + component, + element::{Any as AnyElement, Element}, + event::{KeyEvent, KeyHandler, MouseEvent, MouseHandler}, + terminal::{Frame, Rect}, + text::Lines, +}; + +/// A component that displays text. +/// +/// `Text` renders the [`Lines`] passed into it. +/// +/// [`Lines`]: ../text/struct.Lines.html +#[component(Text)] +pub fn render(text: Lines, on_key: KeyHandler, on_mouse: MouseHandler) { + AnyElement::new(Frozen { + lines: text.clone(), + on_key: on_key.clone(), + on_mouse: on_mouse.clone(), + }) +} + +struct Frozen { + lines: Lines, + on_key: KeyHandler, + on_mouse: MouseHandler, +} + +impl Element for Frozen { + fn on_key(&self, event: KeyEvent) { + self.on_key.handle(event); + } + + fn on_mouse(&self, _rect: Rect, event: MouseEvent) { + self.on_mouse.handle(event); + } + + fn draw(&self, rect: Rect, frame: &mut Frame) { + let widget = Paragraph::new::>(self.lines.0.iter().cloned().map(TuiSpans::from).collect()); + + frame.render_widget(widget, rect); + } +} diff --git a/intuitive/src/components/text/mod.rs b/intuitive/src/components/text/mod.rs index 2dae214..6dcdd57 100644 --- a/intuitive/src/components/text/mod.rs +++ b/intuitive/src/components/text/mod.rs @@ -1,45 +1,3 @@ -use tui::{text::Spans as TuiSpans, widgets::Paragraph}; +//! Structures relating to the `Text` component. -use crate::{ - component, - element::{Any as AnyElement, Element}, - event::{KeyEvent, KeyHandler, MouseEvent, MouseHandler}, - terminal::{Frame, Rect}, - text::Lines, -}; - -/// A component that displays text. -/// -/// `Text` renders the [`Lines`] passed into it. -/// -/// [`Lines`]: ../text/struct.Lines.html -#[component(Text)] -pub fn render(text: Lines, on_key: KeyHandler, on_mouse: MouseHandler) { - AnyElement::new(Frozen { - lines: text.clone(), - on_key: on_key.clone(), - on_mouse: on_mouse.clone(), - }) -} - -struct Frozen { - lines: Lines, - on_key: KeyHandler, - on_mouse: MouseHandler, -} - -impl Element for Frozen { - fn on_key(&self, event: KeyEvent) { - self.on_key.handle(event); - } - - fn on_mouse(&self, _rect: Rect, event: MouseEvent) { - self.on_mouse.handle(event); - } - - fn draw(&self, rect: Rect, frame: &mut Frame) { - let widget = Paragraph::new::>(self.lines.0.iter().cloned().map(TuiSpans::from).collect()); - - frame.render_widget(widget, rect); - } -} +pub(super) mod component; From 54be2e6166b86f99d259567cb0c2e9a54331654e Mon Sep 17 00:00:00 2001 From: Chris Bouchard Date: Sat, 26 Nov 2022 23:34:53 -0500 Subject: [PATCH 2/5] Add `text::alignment::Alignment` for text alignment Nothing's using it yet, but the `Text` component will soon. --- intuitive/src/components/text/alignment.rs | 27 ++++++++++++++++++++++ intuitive/src/components/text/mod.rs | 1 + 2 files changed, 28 insertions(+) create mode 100644 intuitive/src/components/text/alignment.rs diff --git a/intuitive/src/components/text/alignment.rs b/intuitive/src/components/text/alignment.rs new file mode 100644 index 0000000..e47c84d --- /dev/null +++ b/intuitive/src/components/text/alignment.rs @@ -0,0 +1,27 @@ +use tui::layout::Alignment as TuiAlignment; + +/// Control how the text in a [`Text`] component is aligned. +/// +/// [`Text`]: ../struct.Text.html +#[derive(Clone, Copy)] +pub enum Alignment { + Left, + Center, + Right, +} + +impl Default for Alignment { + fn default() -> Self { + Self::Left + } +} + +impl From for TuiAlignment { + fn from(alignment: Alignment) -> Self { + match alignment { + Alignment::Left => Self::Left, + Alignment::Center => Self::Center, + Alignment::Right => Self::Right, + } + } +} diff --git a/intuitive/src/components/text/mod.rs b/intuitive/src/components/text/mod.rs index 6dcdd57..4f695fc 100644 --- a/intuitive/src/components/text/mod.rs +++ b/intuitive/src/components/text/mod.rs @@ -1,3 +1,4 @@ //! Structures relating to the `Text` component. +mod alignment; pub(super) mod component; From eaa63757fbd6b7bc5eadd67280a2e05d08695d15 Mon Sep 17 00:00:00 2001 From: Chris Bouchard Date: Sat, 26 Nov 2022 23:37:17 -0500 Subject: [PATCH 3/5] Expose `Alignment` struct --- intuitive/src/components/text/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/intuitive/src/components/text/mod.rs b/intuitive/src/components/text/mod.rs index 4f695fc..2a66b90 100644 --- a/intuitive/src/components/text/mod.rs +++ b/intuitive/src/components/text/mod.rs @@ -2,3 +2,5 @@ mod alignment; pub(super) mod component; + +pub use alignment::Alignment; From 81cba88488107445f9edd84f65b6376b2806ab48 Mon Sep 17 00:00:00 2001 From: Chris Bouchard Date: Sat, 26 Nov 2022 23:41:10 -0500 Subject: [PATCH 4/5] Add alignment property for `Text` And pass it through to the underlying `Paragraph`. Since property order doesn't matter for anyone using `render!`, and any call to `Text::new` is going to break with an added parameter anyway, I've added the new parameter at the beginning to preserve alphabetical order. --- intuitive/src/components/text/component.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/intuitive/src/components/text/component.rs b/intuitive/src/components/text/component.rs index 2dae214..5b8cf0a 100644 --- a/intuitive/src/components/text/component.rs +++ b/intuitive/src/components/text/component.rs @@ -1,5 +1,6 @@ use tui::{text::Spans as TuiSpans, widgets::Paragraph}; +use super::Alignment; use crate::{ component, element::{Any as AnyElement, Element}, @@ -14,8 +15,9 @@ use crate::{ /// /// [`Lines`]: ../text/struct.Lines.html #[component(Text)] -pub fn render(text: Lines, on_key: KeyHandler, on_mouse: MouseHandler) { +pub fn render(alignment: Alignment, text: Lines, on_key: KeyHandler, on_mouse: MouseHandler) { AnyElement::new(Frozen { + alignment: *alignment, lines: text.clone(), on_key: on_key.clone(), on_mouse: on_mouse.clone(), @@ -23,6 +25,7 @@ pub fn render(text: Lines, on_key: KeyHandler, on_mouse: MouseHandler) { } struct Frozen { + alignment: Alignment, lines: Lines, on_key: KeyHandler, on_mouse: MouseHandler, @@ -38,7 +41,8 @@ impl Element for Frozen { } fn draw(&self, rect: Rect, frame: &mut Frame) { - let widget = Paragraph::new::>(self.lines.0.iter().cloned().map(TuiSpans::from).collect()); + let widget = + Paragraph::new::>(self.lines.0.iter().cloned().map(TuiSpans::from).collect()).alignment(self.alignment.into()); frame.render_widget(widget, rect); } From bafd65b352c3596e55cc8afd40964762086ee771 Mon Sep 17 00:00:00 2001 From: Chris Bouchard Date: Sat, 26 Nov 2022 23:54:27 -0500 Subject: [PATCH 5/5] Expose the `components::text` module Now that the `Text` component won't appear twice, we can make the module public to expose `Alignment`. --- intuitive/src/components/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intuitive/src/components/mod.rs b/intuitive/src/components/mod.rs index 2e19bb0..a611407 100644 --- a/intuitive/src/components/mod.rs +++ b/intuitive/src/components/mod.rs @@ -185,6 +185,7 @@ pub mod children; pub mod stack; +pub mod text; mod experimental_components; #[doc_cfg::doc_cfg(feature = "experimental")] @@ -203,7 +204,6 @@ mod centered; mod embed; mod empty; mod section; -mod text; pub use self::{ any::Any,