Skip to content

Commit

Permalink
Rename TextBlock to TextLayout (#15797)
Browse files Browse the repository at this point in the history
# Objective

- Improve clarity when spawning a text block. See [this
discussion](#15591).

## Solution

- Rename `TextBlock` to `TextLayout`.
  • Loading branch information
UkoeHB authored Oct 9, 2024
1 parent b4071ca commit a6be9b4
Show file tree
Hide file tree
Showing 27 changed files with 89 additions and 87 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_text/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub use text_access::*;
pub mod prelude {
#[doc(hidden)]
pub use crate::{
Font, JustifyText, LineBreak, Text2d, TextBlock, TextError, TextReader2d, TextSpan,
Font, JustifyText, LineBreak, Text2d, TextError, TextLayout, TextReader2d, TextSpan,
TextStyle, TextWriter2d,
};
}
Expand Down
16 changes: 8 additions & 8 deletions crates/bevy_text/src/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use cosmic_text::{Attrs, Buffer, Family, Metrics, Shaping, Wrap};

use crate::{
error::TextError, ComputedTextBlock, Font, FontAtlasSets, FontSmoothing, JustifyText,
LineBreak, PositionedGlyph, TextBlock, TextBounds, TextEntity, TextStyle, YAxisOrientation,
LineBreak, PositionedGlyph, TextBounds, TextEntity, TextLayout, TextStyle, YAxisOrientation,
};

/// A wrapper resource around a [`cosmic_text::FontSystem`]
Expand Down Expand Up @@ -203,7 +203,7 @@ impl TextPipeline {
fonts: &Assets<Font>,
text_spans: impl Iterator<Item = (Entity, usize, &'a str, &'a TextStyle)>,
scale_factor: f64,
block: &TextBlock,
layout: &TextLayout,
bounds: TextBounds,
font_atlas_sets: &mut FontAtlasSets,
texture_atlases: &mut Assets<TextureAtlasLayout>,
Expand All @@ -229,8 +229,8 @@ impl TextPipeline {
let update_result = self.update_buffer(
fonts,
text_spans,
block.linebreak,
block.justify,
layout.linebreak,
layout.justify,
bounds,
scale_factor,
computed,
Expand Down Expand Up @@ -337,7 +337,7 @@ impl TextPipeline {
fonts: &Assets<Font>,
text_spans: impl Iterator<Item = (Entity, usize, &'a str, &'a TextStyle)>,
scale_factor: f64,
block: &TextBlock,
layout: &TextLayout,
computed: &mut ComputedTextBlock,
font_system: &mut CosmicFontSystem,
) -> Result<TextMeasureInfo, TextError> {
Expand All @@ -350,8 +350,8 @@ impl TextPipeline {
self.update_buffer(
fonts,
text_spans,
block.linebreak,
block.justify,
layout.linebreak,
layout.justify,
MIN_WIDTH_CONTENT_BOUNDS,
scale_factor,
computed,
Expand Down Expand Up @@ -386,7 +386,7 @@ impl TextPipeline {
/// Render information for a corresponding text block.
///
/// Contains scaled glyphs and their size. Generated via [`TextPipeline::queue_text`] when an entity has
/// [`TextBlock`] and [`ComputedTextBlock`] components.
/// [`TextLayout`] and [`ComputedTextBlock`] components.
#[derive(Component, Clone, Default, Debug, Reflect)]
#[reflect(Component, Default, Debug)]
pub struct TextLayoutInfo {
Expand Down
54 changes: 28 additions & 26 deletions crates/bevy_text/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,20 @@ impl Default for CosmicBuffer {
}
}

/// A sub-entity of a [`TextBlock`].
/// A sub-entity of a [`ComputedTextBlock`].
///
/// Returned by [`ComputedTextBlock::entities`].
#[derive(Debug, Copy, Clone)]
pub struct TextEntity {
/// The entity.
pub entity: Entity,
/// Records the hierarchy depth of the entity within a `TextBlock`.
/// Records the hierarchy depth of the entity within a `TextLayout`.
pub depth: usize,
}

/// Computed information for a [`TextBlock`].
/// Computed information for a text block.
///
/// See [`TextLayout`].
///
/// Automatically updated by 2d and UI text systems.
#[derive(Component, Debug, Clone)]
Expand All @@ -45,7 +47,7 @@ pub struct ComputedTextBlock {
///
/// This is private because buffer contents are always refreshed from ECS state when writing glyphs to
/// `TextLayoutInfo`. If you want to control the buffer contents manually or use the `cosmic-text`
/// editor, then you need to not use `TextBlock` and instead manually implement the conversion to
/// editor, then you need to not use `TextLayout` and instead manually implement the conversion to
/// `TextLayoutInfo`.
pub(crate) buffer: CosmicBuffer,
/// Entities for all text spans in the block, including the root-level text.
Expand All @@ -55,12 +57,12 @@ pub struct ComputedTextBlock {
/// Flag set when any change has been made to this block that should cause it to be rerendered.
///
/// Includes:
/// - [`TextBlock`] changes.
/// - [`TextLayout`] changes.
/// - [`TextStyle`] or `Text2d`/`Text`/`TextSpan` changes anywhere in the block's entity hierarchy.
// TODO: This encompasses both structural changes like font size or justification and non-structural
// changes like text color and font smoothing. This field currently causes UI to 'remeasure' text, even if
// the actual changes are non-structural and can be handled by only rerendering and not remeasuring. A full
// solution would probably require splitting TextBlock and TextStyle into structural/non-structural
// solution would probably require splitting TextLayout and TextStyle into structural/non-structural
// components for more granular change detection. A cost/benefit analysis is needed.
pub(crate) needs_rerender: bool,
}
Expand Down Expand Up @@ -103,57 +105,57 @@ impl Default for ComputedTextBlock {
#[derive(Component, Debug, Copy, Clone, Default, Reflect)]
#[reflect(Component, Default, Debug)]
#[require(ComputedTextBlock, TextLayoutInfo)]
pub struct TextBlock {
pub struct TextLayout {
/// The text's internal alignment.
/// Should not affect its position within a container.
pub justify: JustifyText,
/// How the text should linebreak when running out of the bounds determined by `max_size`.
pub linebreak: LineBreak,
}

impl TextBlock {
/// Makes a new [`TextBlock`].
impl TextLayout {
/// Makes a new [`TextLayout`].
pub const fn new(justify: JustifyText, linebreak: LineBreak) -> Self {
Self { justify, linebreak }
}

/// Makes a new [`TextBlock`] with the specified [`JustifyText`].
/// Makes a new [`TextLayout`] with the specified [`JustifyText`].
pub fn new_with_justify(justify: JustifyText) -> Self {
Self::default().with_justify(justify)
}

/// Makes a new [`TextBlock`] with the specified [`LineBreak`].
/// Makes a new [`TextLayout`] with the specified [`LineBreak`].
pub fn new_with_linebreak(linebreak: LineBreak) -> Self {
Self::default().with_linebreak(linebreak)
}

/// Makes a new [`TextBlock`] with soft wrapping disabled.
/// Makes a new [`TextLayout`] with soft wrapping disabled.
/// Hard wrapping, where text contains an explicit linebreak such as the escape sequence `\n`, will still occur.
pub fn new_with_no_wrap() -> Self {
Self::default().with_no_wrap()
}

/// Returns this [`TextBlock`] with the specified [`JustifyText`].
/// Returns this [`TextLayout`] with the specified [`JustifyText`].
pub const fn with_justify(mut self, justify: JustifyText) -> Self {
self.justify = justify;
self
}

/// Returns this [`TextBlock`] with the specified [`LineBreak`].
/// Returns this [`TextLayout`] with the specified [`LineBreak`].
pub const fn with_linebreak(mut self, linebreak: LineBreak) -> Self {
self.linebreak = linebreak;
self
}

/// Returns this [`TextBlock`] with soft wrapping disabled.
/// Returns this [`TextLayout`] with soft wrapping disabled.
/// Hard wrapping, where text contains an explicit linebreak such as the escape sequence `\n`, will still occur.
pub const fn with_no_wrap(mut self) -> Self {
self.linebreak = LineBreak::NoWrap;
self
}
}

/// A span of UI text in a tree of spans under an entity with [`TextBlock`], such as `Text` or `Text2d`.
/// A span of UI text in a tree of spans under an entity with [`TextLayout`] and `Text` or `Text2d`.
///
/// Spans are collected in hierarchy traversal order into a [`ComputedTextBlock`] for layout.
///
Expand All @@ -163,13 +165,13 @@ impl TextBlock {
# use bevy_color::Color;
# use bevy_color::palettes::basic::{RED, BLUE};
# use bevy_ecs::World;
# use bevy_text::{Font, TextBlock, TextStyle, TextSection};
# use bevy_text::{Font, TextLayout, TextStyle, TextSection};
# let font_handle: Handle<Font> = Default::default();
# let mut world = World::default();
#
world.spawn((
TextBlock::default(),
TextLayout::default(),
TextStyle {
font: font_handle.clone().into(),
font_size: 60.0,
Expand Down Expand Up @@ -257,7 +259,7 @@ impl From<JustifyText> for cosmic_text::Align {
}
}

/// `TextStyle` determines the style of a text span within a [`TextBlock`], specifically
/// `TextStyle` determines the style of a text span within a [`ComputedTextBlock`], specifically
/// the font face, the font size, and the color.
#[derive(Component, Clone, Debug, Reflect)]
#[reflect(Component, Default, Debug)]
Expand Down Expand Up @@ -285,7 +287,7 @@ pub struct TextStyle {
}

impl TextStyle {
/// Returns this [`TextBlock`] with the specified [`FontSmoothing`].
/// Returns this [`TextStyle`] with the specified [`FontSmoothing`].
pub const fn with_font_smoothing(mut self, font_smoothing: FontSmoothing) -> Self {
self.font_smoothing = font_smoothing;
self
Expand Down Expand Up @@ -358,23 +360,23 @@ pub fn detect_text_needs_rerender<Root: Component>(
Or<(
Changed<Root>,
Changed<TextStyle>,
Changed<TextBlock>,
Changed<TextLayout>,
Changed<Children>,
)>,
With<Root>,
With<TextStyle>,
With<TextBlock>,
With<TextLayout>,
),
>,
changed_spans: Query<
(Entity, Option<&Parent>, Has<TextBlock>),
(Entity, Option<&Parent>, Has<TextLayout>),
(
Or<(
Changed<TextSpan>,
Changed<TextStyle>,
Changed<Children>,
Changed<Parent>, // Included to detect broken text block hierarchies.
Added<TextBlock>,
Added<TextLayout>,
)>,
With<TextSpan>,
With<TextStyle>,
Expand All @@ -389,7 +391,7 @@ pub fn detect_text_needs_rerender<Root: Component>(
// Root entity:
// - Root component changed.
// - TextStyle on root changed.
// - TextBlock changed.
// - TextLayout changed.
// - Root children changed (can include additions and removals).
for root in changed_roots.iter() {
let Ok((_, Some(mut computed), _)) = computed.get_mut(root) else {
Expand All @@ -406,7 +408,7 @@ pub fn detect_text_needs_rerender<Root: Component>(
// - Span children changed (can include additions and removals).
for (entity, maybe_span_parent, has_text_block) in changed_spans.iter() {
if has_text_block {
warn_once!("found entity {:?} with a TextSpan that has a TextBlock, which should only be on root \
warn_once!("found entity {:?} with a TextSpan that has a TextLayout, which should only be on root \
text entities (that have {}); this warning only prints once",
entity, core::any::type_name::<Root>());
}
Expand Down
16 changes: 8 additions & 8 deletions crates/bevy_text/src/text2d.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::pipeline::CosmicFontSystem;
use crate::{
ComputedTextBlock, Font, FontAtlasSets, LineBreak, PositionedGlyph, SwashCache, TextBlock,
TextBounds, TextError, TextLayoutInfo, TextPipeline, TextReader, TextRoot, TextSpanAccess,
ComputedTextBlock, Font, FontAtlasSets, LineBreak, PositionedGlyph, SwashCache, TextBounds,
TextError, TextLayout, TextLayoutInfo, TextPipeline, TextReader, TextRoot, TextSpanAccess,
TextStyle, TextWriter, YAxisOrientation,
};
use bevy_asset::Assets;
Expand Down Expand Up @@ -38,9 +38,9 @@ use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged};
/// [Example usage.](https://github.com/bevyengine/bevy/blob/latest/examples/2d/text2d.rs)
///
/// The string in this component is the first 'text span' in a hierarchy of text spans that are collected into
/// a [`TextBlock`]. See [`TextSpan`](crate::TextSpan) for the component used by children of entities with [`Text2d`].
/// a [`ComputedTextBlock`]. See [`TextSpan`](crate::TextSpan) for the component used by children of entities with [`Text2d`].
///
/// With `Text2d` the `justify` field of [`TextBlock`] only affects the internal alignment of a block of text and not its
/// With `Text2d` the `justify` field of [`TextLayout`] only affects the internal alignment of a block of text and not its
/// relative position, which is controlled by the [`Anchor`] component.
/// This means that for a block of text consisting of only one line that doesn't wrap, the `justify` field will have no effect.
///
Expand All @@ -50,7 +50,7 @@ use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged};
# use bevy_color::Color;
# use bevy_color::palettes::basic::BLUE;
# use bevy_ecs::World;
# use bevy_text::{Font, JustifyText, Text2d, TextBlock, TextStyle};
# use bevy_text::{Font, JustifyText, Text2d, TextLayout, TextStyle};
#
# let font_handle: Handle<Font> = Default::default();
# let mut world = World::default();
Expand All @@ -71,14 +71,14 @@ world.spawn((
// With text justification.
world.spawn((
Text2d::new("hello world\nand bevy!"),
TextBlock::new_with_justify(JustifyText::Center)
TextLayout::new_with_justify(JustifyText::Center)
));
```
*/
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect)]
#[reflect(Component, Default, Debug)]
#[require(
TextBlock,
TextLayout,
TextStyle,
TextBounds,
Anchor,
Expand Down Expand Up @@ -230,7 +230,7 @@ pub fn update_text2d_layout(
mut text_pipeline: ResMut<TextPipeline>,
mut text_query: Query<(
Entity,
Ref<TextBlock>,
Ref<TextLayout>,
Ref<TextBounds>,
&mut TextLayoutInfo,
&mut ComputedTextBlock,
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_text/src/text_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl TextIterScratch {
}
}

/// System parameter for reading text spans in a [`TextBlock`](crate::TextBlock).
/// System parameter for reading text spans in a text block.
///
/// `R` is the root text component, and `S` is the text span component on children.
#[derive(SystemParam)]
Expand Down Expand Up @@ -184,7 +184,7 @@ impl<'a, R: TextRoot> Drop for TextSpanIter<'a, R> {
}
}

/// System parameter for reading and writing text spans in a [`TextBlock`](crate::TextBlock).
/// System parameter for reading and writing text spans in a text block.
///
/// `R` is the root text component, and `S` is the text span component on children.
#[derive(SystemParam)]
Expand Down
Loading

0 comments on commit a6be9b4

Please sign in to comment.