-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make each TextSection
its own entity.
#14572
Conversation
Context for why this should be done, from Discord |
This work was previously mentioned in #14437. As discussed above, bringing text sections into the entity hierarchy is required to make them play nicely with scenes, and thus the BSN entity-spawning tools. |
I think I will wait with porting over all examples for two reasons:
I did port some of the examples to show the new API, and those will be kept up to date for any changes that happen. |
crates/bevy_ui/src/widget/text.rs
Outdated
let sections = if let Some(children) = children { | ||
children_changed = children.is_changed(); | ||
|
||
text2d_section_query.iter_many(&children).collect() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This vec can be cached in a Local
. Then use .clear()
and .extend()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right, will do that!
crates/bevy_ui/src/widget/text.rs
Outdated
let sections = if let Some(children) = children { | ||
children_changed = children.is_changed(); | ||
text_section_query.iter_many(&children).collect() | ||
} else { | ||
vec![] | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, cache the vec.
let section = text2d_section_query | ||
.get(children.unwrap()[*section_index]) | ||
.unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not valid to access via []
here, because non-TextSection children may be interleaved. You need to find the position in the children that filters for entities with TextSection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I guess that's true. What would be the best approach for that?
crates/bevy_text/src/text2d.rs
Outdated
let sections = if let Some(children) = children { | ||
children_changed = children.is_changed(); | ||
section_query.iter_many(children.iter()).collect() | ||
} else { | ||
vec![] | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here as well, cache the vec.
let section = text2d_section_query | ||
.get(children.unwrap()[*section_index]) | ||
.unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invalid children access, need to filter for entities with TextSection.
crates/bevy_ui/src/accessibility.rs
Outdated
let values = text | ||
.sections | ||
if let Ok(maybe_children) = texts.get(*child) { | ||
let mut sections = Vec::new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cache this vec if possible. Or convert to a chained iterator for the values
collection.
examples/2d/2d_shapes.rs
Outdated
.spawn(TextBundle { | ||
style: Style { | ||
position_type: PositionType::Absolute, | ||
top: Val::Px(12.0), | ||
left: Val::Px(12.0), | ||
..default() | ||
}), | ||
); | ||
}, | ||
..default() | ||
}) | ||
.with_child(TextSection::new( | ||
"Press space to toggle wireframes", | ||
TextStyle::default(), | ||
)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be nice if you could optionally put the first text section on the parent entity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We initially had this supported, but in discord we decided to not do it.
Marking this as ready for review, the main thing that we still need to do is find a way to prevent repeated allocations in the systems where the text is enqueued. |
TextSection
its own entity.TextSection
its own entity.
@@ -127,7 +52,7 @@ impl Text { | |||
} | |||
|
|||
/// Contains the value of the text in a section and how it should be styled. | |||
#[derive(Debug, Default, Clone, Reflect)] | |||
#[derive(Component, Debug, Default, Clone, Reflect)] | |||
#[reflect(Default)] | |||
pub struct TextSection { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be split up I think, TextStyle
needs to be a separate elidable component imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how I feel about that, it would require a LOT more changes, that I don't want to update 100 examples for again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know but I think it's really necessary.
Maybe if TextSection
is made into a bundle with Text
(and rename the existing component, I agree with TotalKrill that it's potentially confusing) and TextStyle
components it would just work without any changes to most of the examples?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
honestly great idea!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know but I think it's really necessary.
Could you elaborate on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know but I think it's really necessary.
Could you elaborate on this?
Different styling options, with Text2d style propagation and responsive sizes might not make sense or need different solutions. More granular change detection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ickshonpe
That sounds good to me, but it also sounds like something that should be discussed/designed. Would be it acceptable to catalog this in an issue and implement it in a followup PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally agree on splitting this, strongly feel this should be moved to followup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep I've no problem with moving this to a followup, it would be good if we can avoid multiple rewrites of the api and examples though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It probably should be split up more even, previously it's really bugged me how changing the colour of a single section causes a relayout of the whole text node. Separate TextColor
component disappears that problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docs should really indicate the new relationship between the components. And the component should be renamed since it has completely changed its meaning with this change.
And the newly created issue for this should indicate what was lost and point to this PR so it can be tracked
@@ -127,7 +52,7 @@ impl Text { | |||
} | |||
|
|||
/// Contains the value of the text in a section and how it should be styled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the first time we are adding a parent/child hierarchy requirement as far as I know, the docs should indicate this relationship on the related components.
Also with this change, the name "Text" is actually more confusing than helping, since it only contains the information for how text will be justified, and contains no text whatsoever
@@ -127,7 +52,7 @@ impl Text { | |||
} | |||
|
|||
/// Contains the value of the text in a section and how it should be styled. | |||
#[derive(Debug, Default, Clone, Reflect)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same on this component, should probably indicate that this component is required to be a child of the other Component.
@@ -207,26 +205,6 @@ pub struct TextBundle { | |||
|
|||
#[cfg(feature = "bevy_text")] | |||
impl TextBundle { | |||
/// Create a [`TextBundle`] from a single section. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed in discord.
The removal of these ergonomics is a huge loss. both on TextBundle
and on Text
and should be addressed before 0.15 if this PR is to land
@@ -29,8 +29,6 @@ impl Default for CosmicBuffer { | |||
#[derive(Component, Debug, Clone, Default, Reflect)] | |||
#[reflect(Component, Default)] | |||
pub struct Text { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pub struct Text { | |
pub struct TextNode { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This suggestion seems confusing because the component is also used in Text2dBundle
, and we don't use this naming convention in any other UI bundles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do we think of TextLayout
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll go with TextLayout
, makes the most sense to me.
There are currently warnings about the children of a UI node not having UI components themselves, how do I fix these?
|
Not tested it but changing these queries in
to filter for the text bundle's marker component with:
should be sufficient. |
Can you do a pass on the comments and resolve those that are addressed to make this easier to review? :) |
Is this the right time to rename sections to spans? |
|
Text entity tidy
See this discussion for a required-components-based redesign. |
Merging #15591, which continued this work. |
Objective
This change makes each
TextSection
its own entity, which was discussed to be the next step forbevy_text
in Discord.Fixes #7714
Solution
Text
component to hold no sections instead of aVec
ofTextSection
.TextSection
a component that should be added to children of aText
.Testing
Tested out some of the examples that I ported to the new API, they all look fine.
Migration Guide
Any usage of
TextBundle::from_section
orText::from_section
should be replaced with something like this:Same goes for the
from_sections
methods.