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}