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

UI Building Blocks and Styles #1

Closed

Conversation

alice-i-cecile
Copy link
Member

@alice-i-cecile alice-i-cecile commented Apr 14, 2021

RENDERED

A vision for the basic building blocks, data structures and interaction paradigms for Bevy-native UI. Determining a styling strategy as part of this RFC allows us to make sure the data model works in a more complex use cases.

Previously developed at: alice-i-cecile/bevy-temp-rfc#4

```rust
commands.spawn_bundle(ButtonBundle::default())
.with_children(|parent| {
parent.spawn_bundle(TextBundle::default())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to have a sugar over it, so instead of spawning bundles I as an user will write less code by invoking a member function with_text/add_text for TextBundle, for example.

trait SpawnText {
    fn spawn_text(&mut self, /* ... */) -> &mut Self
}

impl<'a, b'>  SpawnText for ChildBuilder<'a, 'b> {
    // ...
}
commands.spawn_bundle(ButtonBundle::default())
  .with_children(|parent| {
    parent.spawn_text("Hello, World!")
  });

Not sure that it's possible now due to lack of optional named parameter support.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with your dislike of the parent-child API. It's not great, but I copied the existing syntax to keep the scope of this RFC sane.

I'd like to avoid custom builder functions everywhere (like for spawn_text); they're a lot of boilerplate to have to write and maintain, and really obscure what's happening here in a way that makes it harder for people to develop an accurate mental model.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if I correctly understand you, the current API won't be touched by the proposal at all and what I'm asking is for another discussion, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. The parent-child API and the strategy for composing widgets is a separate discussion. IMO it should use relations (bevyengine/bevy#1627), but there's a fair bit of design and then implementation work left to do there.

@jihiggins
Copy link

One thing I've found is it's helpful to have Add/RemoveStyle EntityCommands, so that you don't have to pass Res around to any widget building functions
(Something like commands.entity(my_entity).add_style("my_style").remove_style("default_style") )

@YohDeadfall
Copy link
Member

While I like the idea of add_style/remove_style, there's a thing I'm concerned about. These methods may be used for any entity even if it doesn't represent a widget.

@alice-i-cecile
Copy link
Member Author

While I like the idea of add_style/remove_style, there's a thing I'm concerned about. These methods may be used for any entity even if it doesn't represent a widget.

Yes, you see this sort of problem crop up a lot. IMO, kinded entities (bevyengine/bevy#1634) should be up-prioritized and then used aggressively if we end up using this approach to avoid confusing bugs for end users.

@anchpop
Copy link

anchpop commented Apr 17, 2021

I'd like to be able to use this to style things besides UI widgets. For example, if I produce three "texture packs" for all the models in my game, it would be nice if I could use the style system to easily propagate the current texture-pack everywhere I need a texture.

You can almost think of it as a generic way of propagating data through an application. I could imagine a slightly more general system than the one you describe also working for localization, which is a similar problem - you have one value (the current language) which you want to be able to easily change and have that change propagated to lots of components scattered around the application.

@alice-i-cecile
Copy link
Member Author

Thanks @anchpop; I've made the appropriate changes to ensure that everything Just Works for that, and mentioned the application of styling to other domains in Future Work :)

@mirkoRainer
Copy link

I'd like to be able to use this to style things besides UI widgets. For example, if I produce three "texture packs" for all the models in my game, it would be nice if I could use the style system to easily propagate the current texture-pack everywhere I need a texture.

You can almost think of it as a generic way of propagating data through an application. I could imagine a slightly more general system than the one you describe also working for localization, which is a similar problem - you have one value (the current language) which you want to be able to easily change and have that change propagated to lots of components scattered around the application.

Wouldn't this fall outside the scope of UI?
Is there a clear definition of what Bevy UI means?

Entities with the `ScreenSpace` component are drawn by the UI camera; all others are drawn with ordinary cameras.
2. `Layout`, which tells Bevy's built-in layout systems to control its positioning relative to other `Layout` entities.
The values of this component's fields determine exactly how this is done.
3. `Widget`, a general purpose marker component that designates an entity as "part of the UI".

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would UIComponent be more appropriate for this naming convention? Or just UI? Or... UserInterface?
Widget seems here to make this domain specific just to Bevy. Is that desired?

An instance of when disambiguation might be needed with the term "widget":
iOS widgets and Android widgets already exist. Would there ever be a future for Bevy where both of these "widget" terms come into conflict? Or need disambiguation?

attributes are stored as components, and serve to control some element of its presentation, such as the font, background color or text alignment.
attributes can be reused across disparate widget types, with functionality achieved through systems that query for the relevant components.
The type of the attribute components determines which behavior it controls,
while the value returned by `.get()` controls the final behavior of the widget.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unclear to me what type this .get() method is on?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants