Skip to content
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

Mixing Text and non-Text content in UIs #9944

Open
viridia opened this issue Sep 27, 2023 · 2 comments
Open

Mixing Text and non-Text content in UIs #9944

viridia opened this issue Sep 27, 2023 · 2 comments
Labels
A-Text Rendering and layout for characters A-UI Graphical user interfaces, styles, layouts, and widgets C-Usability A targeted quality-of-life change that makes Bevy easier to use

Comments

@viridia
Copy link
Contributor

viridia commented Sep 27, 2023

What problem does this solve or what need does it fill?

Currently Bevy UI text nodes are segregated from other kinds of UI nodes - text spans can only live inside of a Text component. I understand the reasons for this - it makes the layout engine simpler, since things like word-wrap calculations only apply to Text components and not UI components generally.

However, there are some use cases where you would like to mix text and non-text content in a single context. A classic example is a button that has both an icon and a text caption. Yes, you can make a button that has a dedicated "slot" for an icon, but only if the button component is specifically built for this. The same logic holds for menu items, dialog titles, basically anything that accepts a text string - it's better if these can accept a variety of renderable elements.

What solution would you like?

I'm not sure what's the right solution. We all know what the web does, but that's an ambitious target, Bevy is never going to have parity with Firefox when it comes to layout. The two most interesting web cases are flex and inline - that is, either the text and images are laid out in a row with gaps between them, or they are laid out fluidly with word-wrap.

What alternative(s) have you considered?

The flex use case can be done by wrapping everything in an extra UI component. The word-wrap case I'm not sure how you would do.

Additional context

This is likely to be relevant in the context of future Bevy UI / Scene Graph assets.

@viridia viridia added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Sep 27, 2023
@ickshonpe
Copy link
Contributor

ickshonpe commented Sep 28, 2023

Text rendering just draws glyph sprites from the list of glyphs in TextLayoutInfo. For a simple implementation, maybe there is some way we could add the image to the list as a really big glyph and it would just work.

I think once #9415 and #9923 are merged the glyph_brush_layout text wrapping implementation should work without any more problems (fingers crossed). There are a still number of other critical open issues with Text atm that won't be resolved by the cosmic text adoption: #9278 (should be fixed by #9471), #7714, #6967, and the limitations with font size, texture atlases and scaling etc (I think there is an issue somewhere but can't find it).

It is already possible (albeit a bit inefficiently) to mix text and images. The idea is that you set FlexWrap::Wrap on the parent node, split up your text into individual words and then spawn a separate TextBundle for each word. Then you can insert an image bundle in between the text bundles and it will be laid out along with the text as though it is just another word.

@alice-i-cecile alice-i-cecile added A-UI Graphical user interfaces, styles, layouts, and widgets C-Usability A targeted quality-of-life change that makes Bevy easier to use and removed S-Needs-Triage This issue needs to be labelled C-Feature A new feature, making something new possible labels Sep 28, 2023
@viridia
Copy link
Contributor Author

viridia commented Oct 13, 2023

I should mention that my real motivation for wanting this is not what I wrote in the OP - I was trying to make the best possible argument rather than accurately describing my needs.

The real use case I'm concerned about is UI templating: that is, making it easy to write "React-like" components. In HTML, text and non-text elements can be freely intermixed, and the browser just does the right thing, depending on whether the containing element has an "inline", "block" or "flex" layout. Most coders find this fairly natural.

However, in current Bevy, a templating language for UI would require the user add an extra wrapper around text spans in their templates. This means that the templating language now has to understand two different container contexts, each having different constraints on what kind of children they can contain. "Text" objects can only contain text spans, and "Node" or "Element" objects cannot contain text spans, and can only contain block-level elements. This is not much of a hardship for templates that are embedded within Rust source code using macros, but it adds complexity to UI layouts which are parsed via asset loaders - it means that now that your loader needs not just a type system, but two type systems, to represent a Bevy UI layout.

You could of course create a templating language that has both text spans and blocks, and then partition the result into inline and non-inline segments, automatically adding the wrappers as needed, but if you are going to do all that work, you might as well just add it to the UI framework itself, so that everyone can reap the benefits and not just UIs that are generated from templates.

@alice-i-cecile alice-i-cecile moved this to Todo in Editor Oct 16, 2023
@alice-i-cecile alice-i-cecile moved this from Todo to bevy_ui Improvements in Editor Jan 4, 2024
@viridia viridia added the A-Text Rendering and layout for characters label Apr 17, 2024
@alice-i-cecile alice-i-cecile removed this from Editor Aug 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Text Rendering and layout for characters A-UI Graphical user interfaces, styles, layouts, and widgets C-Usability A targeted quality-of-life change that makes Bevy easier to use
Projects
None yet
Development

No branches or pull requests

3 participants