Skip to content

Commit 4745f4a

Browse files
committed
add TextBuilderExt for EntityCommands
1 parent 520f5a9 commit 4745f4a

File tree

4 files changed

+102
-34
lines changed

4 files changed

+102
-34
lines changed

crates/bevy_text/src/text.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use bevy_asset::Handle;
22
use bevy_color::Color;
33
use bevy_derive::{Deref, DerefMut};
44
use bevy_ecs::{prelude::*, reflect::ReflectComponent};
5-
use bevy_hierarchy::{Children, Parent};
5+
use bevy_hierarchy::{BuildChildren, Children, Parent};
66
use bevy_reflect::prelude::*;
77
use bevy_utils::warn_once;
88
use cosmic_text::{Buffer, Metrics};
@@ -279,6 +279,21 @@ pub enum FontSmoothing {
279279
// SubpixelAntiAliased,
280280
}
281281

282+
/// Provides convenience methods for constructing text blocks.
283+
pub trait TextBuilderExt {
284+
/// Adds a flat list of spans as children of the current entity.
285+
fn with_spans<S: Component>(&mut self, spans: Vec<(S, TextStyle)>) -> &mut Self;
286+
}
287+
288+
impl TextBuilderExt for EntityCommands<'_> {
289+
fn with_spans<S: Component>(&mut self, mut spans: Vec<(S, TextStyle)>) -> &mut Self {
290+
for (span, style) in spans.drain(..) {
291+
self.with_child((span, style));
292+
}
293+
self
294+
}
295+
}
296+
282297
/// System that detects changes to text blocks and sets `ComputedTextBlock::should_rerender`.
283298
///
284299
/// Generic over the root text component and text span component. For example, [`Text2d`]/[`TextSpan2d`] for 2d or
@@ -299,13 +314,14 @@ pub fn detect_text_needs_rerender<Root: Component, Span: Component>(
299314
),
300315
>,
301316
changed_spans: Query<
317+
(Entity, &Parent, Has<TextBlock>),
302318
(
303-
Entity,
304-
&Parent,
305-
Has<TextBlock>
306-
),
307-
(
308-
Or<(Changed<Span>, Changed<TextStyle>, Changed<Children>, Added<TextBlock>)>,
319+
Or<(
320+
Changed<Span>,
321+
Changed<TextStyle>,
322+
Changed<Children>,
323+
Added<TextBlock>,
324+
)>,
309325
With<Span>,
310326
With<TextStyle>,
311327
),

crates/bevy_text/src/text2d.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,18 @@ world.spawn((
158158
#[require(TextStyle, Visibility(visibility_hidden), Transform)]
159159
pub struct TextSpan2d(pub String);
160160

161+
impl TextSpan2d {
162+
/// Makes a new 2d span text component.
163+
pub fn new(text: impl Into<String>) -> Self {
164+
Self(text.into())
165+
}
166+
167+
/// Makes an empty 2d span text component.
168+
pub fn empty() -> Self {
169+
Self::new("")
170+
}
171+
}
172+
161173
impl TextSpanAccess for TextSpan2d {
162174
fn read_span(&self) -> &str {
163175
self.as_str()
@@ -167,6 +179,18 @@ impl TextSpanAccess for TextSpan2d {
167179
}
168180
}
169181

182+
impl From<&str> for TextSpan2d {
183+
fn from(value: &str) -> Self {
184+
Self(String::from(value))
185+
}
186+
}
187+
188+
impl From<String> for TextSpan2d {
189+
fn from(value: String) -> Self {
190+
Self(value)
191+
}
192+
}
193+
170194
fn visibility_hidden() -> Visibility {
171195
Visibility::Hidden
172196
}

crates/bevy_ui/src/widget/text.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
2-
ContentSize, DefaultUiCamera, FixedMeasure, FocusPolicy, GhostNode, Measure,
3-
MeasureArgs, Node, NodeMeasure, Style, TargetCamera, UiScale, ZIndex,
2+
ContentSize, DefaultUiCamera, FixedMeasure, FocusPolicy, GhostNode, Measure, MeasureArgs, Node,
3+
NodeMeasure, Style, TargetCamera, UiScale, ZIndex,
44
};
55
use bevy_asset::Assets;
66
use bevy_derive::{Deref, DerefMut};
@@ -110,7 +110,7 @@ impl TextNEW {
110110
Self(text.into())
111111
}
112112

113-
/// Makes an empty 2d text component.
113+
/// Makes an empty UI text component.
114114
pub fn empty() -> Self {
115115
Self::new("")
116116
}
@@ -181,6 +181,11 @@ impl TextSpan {
181181
pub fn new(text: impl Into<String>) -> Self {
182182
Self(text.into())
183183
}
184+
185+
/// Makes an empty UI text span component.
186+
pub fn empty() -> Self {
187+
Self::new("")
188+
}
184189
}
185190

186191
impl TextSpanAccess for TextSpan {
@@ -192,6 +197,18 @@ impl TextSpanAccess for TextSpan {
192197
}
193198
}
194199

200+
impl From<&str> for TextSpan {
201+
fn from(value: &str) -> Self {
202+
Self(String::from(value))
203+
}
204+
}
205+
206+
impl From<String> for TextSpan {
207+
fn from(value: String) -> Self {
208+
Self(value)
209+
}
210+
}
211+
195212
fn hidden_visibility() -> Visibility {
196213
Visibility::Hidden
197214
}

examples/ui/text_debug.rs

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use bevy::{
66
color::palettes::css::*,
77
diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin},
88
prelude::*,
9+
text::TextBuilderExt,
910
ui::widget::UiTextWriter,
1011
window::PresentMode,
1112
};
@@ -161,77 +162,87 @@ fn infotext_system(mut commands: Commands, asset_server: Res<AssetServer>) {
161162
},
162163
TextChanges
163164
))
164-
.with_child((
165-
TextSpan::new("\nThis text changes in the bottom right"),
165+
.with_spans::<TextSpan>(vec![
166+
(
167+
"\nThis text changes in the bottom right".into(),
168+
TextStyle {
169+
font: font.clone(),
170+
font_size: 21.0,
171+
..default()
172+
}
173+
),
174+
(
175+
"\nThis text changes in the bottom right".into(),
166176
TextStyle {
167177
font: font.clone(),
168178
font_size: 21.0,
169179
..default()
170180
},
171-
))
172-
.with_child((
173-
TextSpan::new(" this text has zero fontsize"),
181+
),
182+
(
183+
" this text has zero fontsize".into(),
174184
TextStyle {
175185
font: font.clone(),
176186
font_size: 0.0,
177187
color: BLUE.into(),
178188
..default()
179189
},
180-
))
181-
.with_child((
182-
TextSpan::new("\nThis text changes in the bottom right - "),
190+
),
191+
(
192+
"\nThis text changes in the bottom right - ".into(),
183193
TextStyle {
184194
font: font.clone(),
185195
font_size: 21.0,
186196
color: RED.into(),
187197
..default()
188198
},
189-
))
190-
.with_child((
191-
TextSpan::default(),
199+
),
200+
(
201+
TextSpan::empty(),
192202
TextStyle {
193203
font: font.clone(),
194204
font_size: 21.0,
195205
color: ORANGE_RED.into(),
196206
..default()
197207
}
198-
))
199-
.with_child((
200-
TextSpan::new(" fps, "),
208+
),
209+
(
210+
" fps, ".into(),
201211
TextStyle {
202212
font: font.clone(),
203213
font_size: 10.0,
204214
color: YELLOW.into(),
205215
..default()
206216
},
207-
))
208-
.with_child((
209-
TextSpan::default(),
217+
),
218+
(
219+
TextSpan::empty(),
210220
TextStyle {
211221
font: font.clone(),
212222
font_size: 21.0,
213223
color: LIME.into(),
214224
..default()
215225
}
216-
))
217-
.with_child((
218-
TextSpan::new(" ms/frame"),
226+
),
227+
(
228+
" ms/frame".into(),
219229
TextStyle {
220230
font: font.clone(),
221231
font_size: 42.0,
222232
color: BLUE.into(),
223233
..default()
224234
},
225-
))
226-
.with_child((
227-
TextSpan::new(" this text has negative fontsize"),
235+
),
236+
(
237+
" this text has negative fontsize".into(),
228238
TextStyle {
229239
font: font.clone(),
230240
font_size: -42.0,
231241
color: BLUE.into(),
232242
..default()
233243
},
234-
));
244+
)
245+
]);
235246
})
236247
.id();
237248

0 commit comments

Comments
 (0)