swoop_ui/
text.rs

1use bevy_asset::Handle;
2use bevy_color::prelude::*;
3use bevy_ecs::bundle::Bundle;
4use bevy_text::{FontSmoothing, LineHeight, prelude::*};
5use bevy_ui::prelude::*;
6
7use crate::View;
8
9pub mod swoop_text;
10
11pub mod prelude {
12    pub use super::TextView;
13    pub use super::swoop_text::{SText, SwoopText};
14}
15
16/// A bundle representing styled text appearance and layout configuration.
17///
18/// `TextStyle` encapsulates layout, content, font, and color properties typically used
19/// in rendering text elements within a UI system.
20///
21/// This bundle is intended to be used in UI components that require customizable
22/// textual styling such as font sizing, alignment, line breaking, and color.
23///
24/// # Fields
25/// - `layout`: Controls text alignment, line breaking, and justification rules.
26/// - `text`: The actual string content to be displayed.
27/// - `color`: The color of the rendered text.
28/// - `font`: Font face, size, and smoothing attributes.
29///
30/// ```
31#[derive(Bundle, Debug, Clone)]
32pub struct TextStyle {
33    /// Layout preferences such as alignment and line-breaking behavior.
34    layout: TextLayout,
35
36    /// The textual content to render.
37    text: Text,
38
39    /// The color used to draw the text.
40    color: TextColor,
41
42    /// Font properties including handle, size, and smoothing settings.
43    font: TextFont,
44}
45
46impl Default for TextStyle {
47    fn default() -> Self {
48        Self {
49            layout: TextLayout {
50                justify: JustifyText::Center,
51                linebreak: LineBreak::NoWrap,
52            },
53            text: Text::default(),
54            color: TextColor(Srgba::BLACK.into()),
55            font: TextFont {
56                font_size: 16.0,
57                ..Default::default()
58            },
59        }
60    }
61}
62
63impl TextStyle {
64    pub fn button() -> Self {
65        Self {
66            layout: TextLayout {
67                justify: JustifyText::Center,
68                linebreak: LineBreak::NoWrap,
69            },
70            ..Default::default()
71        }
72    }
73}
74
75/// A trait for views that support styled text content using a `TextStyle` bundle.
76pub trait TextView: View {
77    /// Returns a mutable reference to the inner `TextStyle` node used for text styling.
78    fn text_node(&mut self) -> &mut TextStyle;
79
80    /// Sets the text alignment mode within the layout container.
81    ///
82    /// Controls horizontal alignment of multiline text, such as left-aligned, right-aligned,
83    /// centered, or justified.
84    ///
85    /// # Arguments
86    /// * `justify_text` - A [`JustifyText`] variant indicating the desired alignment mode.
87    ///
88    /// # Example
89    /// ```ignore
90    /// view.text_alignment(JustifyText::Center);
91    /// ```
92    fn text_alignment(mut self, justify_text: JustifyText) -> Self {
93        self.text_node().layout.justify = justify_text;
94        self
95    }
96
97    /// Sets the line-breaking behavior of the text content.
98    ///
99    /// Determines how and when lines wrap, such as breaking on word boundaries,
100    /// characters, or disabling wrapping altogether.
101    ///
102    /// # Arguments
103    /// * `line_break` - A [`LineBreak`] variant specifying the wrapping strategy.
104    ///
105    /// # Example
106    /// ```ignore
107    /// view.text_linebreak(LineBreak::WordWrap);
108    /// ```
109    fn text_linebreak(mut self, line_break: LineBreak) -> Self {
110        self.text_node().layout.linebreak = line_break;
111        self
112    }
113
114    /// Sets the string content of the text node.
115    ///
116    /// # Arguments
117    /// * `text` - A string or string-like value representing the text to display.
118    ///
119    /// # Example
120    /// ```
121    /// view.text("Hello, world!");
122    /// ```
123    fn text(mut self, text: impl Into<String>) -> Self {
124        self.text_node().text.0 = text.into();
125        self
126    }
127
128    /// Sets the text color of the node.
129    ///
130    /// # Arguments
131    /// * `color` - A color value (e.g., `Color::WHITE`, `Color::rgb(...)`).
132    fn text_color(mut self, color: impl Into<Color>) -> Self {
133        self.text_node().color.0 = color.into();
134        self
135    }
136
137    /// Sets the font asset used for rendering the text.
138    ///
139    /// # Arguments
140    /// * `font` - A handle to a `Font` asset.
141    fn font(mut self, font: Handle<Font>) -> Self {
142        self.text_node().font.font = font;
143        self
144    }
145
146    /// Sets the size of the font in logical pixels.
147    ///
148    /// # Arguments
149    /// * `font_size` - The font size, typically in points or pixels.
150    fn font_size(mut self, font_size: f32) -> Self {
151        self.text_node().font.font_size = font_size;
152        self
153    }
154
155    /// Sets the line height for the text, controlling vertical spacing between lines.
156    ///
157    /// # Arguments
158    /// * `line_height` - A `LineHeight` value representing relative or absolute spacing.
159    fn line_height(mut self, line_height: LineHeight) -> Self {
160        self.text_node().font.line_height = line_height;
161        self
162    }
163
164    /// Sets the font smoothing mode for the text.
165    ///
166    /// # Arguments
167    /// * `font_smoothing` - A `FontSmoothing` strategy (e.g., `FontSmoothing::None`, `Subpixel`).
168    fn font_smoothing(mut self, font_smoothing: FontSmoothing) -> Self {
169        self.text_node().font.font_smoothing = font_smoothing;
170        self
171    }
172}