bevy icon indicating copy to clipboard operation
bevy copied to clipboard

Add proper border support for UI nodes

Open TimJentzsch opened this issue 3 years ago • 4 comments

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

Adding borders to UI elements is a common need, both for design and debugging. Currently, we can only set the width of the border, but not the color. So it doesn't have a real visual effect at the moment.

What solution would you like?

Ideally, we should be able to define the following properties:

  • Border color
  • Border width (this is already possible)
  • Border radius (i.e. round corners; both pixel and percent values should be possible here)

We could also think about supporting more complex styles, like dashed borders.

Once #5513 is merged, it probably makes sense to have all of these together in a style component.

Additionally, we could think about supporting outlines as well. These are essentially additional borders around the normal borders and can be used for accessibility features like visualizing keyboard focus.

What alternative(s) have you considered?

Currently it's sort of possible to make "borders" by wrapping the node in another node that is slightly larger and has a background color.

This approach is very limited and not ergonomic at all.

Additional context

TimJentzsch avatar Sep 09 '22 14:09 TimJentzsch

Previously attempted in #3991.

alice-i-cecile avatar Sep 09 '22 14:09 alice-i-cecile

I'm willing to revisit this at some point when #5513 is merged. I think one big concern was the amount of changes that was necessary in the UI rendering to implement it. Another concern for me was the anti-aliasing for borders which was implemented directly in the shader by fading the borders a little bit.

As someone with limited experience writing rendering code, I'm down to try and write something that works, but I would prefer that it goes through thorough review to find the most optimal solution.

#90 would offer a completely different and much more flexible approach to do this, but I think we would gain from having both be available since one is a simple way to define border properties while the other would be a full drawing API.

oceantume avatar Sep 09 '22 15:09 oceantume

https://github.com/bevyengine/bevy/issues/90 would offer a completely different and much more flexible approach to do this, but I think we would gain from having both be available since one is a simple way to define border properties while the other would be a full drawing API.

Agreed, I'd be frustrated if the only way to draw simple borders was a canvas API.

alice-i-cecile avatar Sep 09 '22 16:09 alice-i-cecile

Also, first https://github.com/DioxusLabs/taffy/issues/223 needs to be done, since it's not possible to differentiate between border and margin calculated values.

afonsolage avatar Sep 10 '22 06:09 afonsolage

Also, first DioxusLabs/taffy#223 needs to be done, since it's not possible to differentiate between border and margin calculated values.

This could potentially be exposed by Taffy as an output, but it is possible to differentiate by referring to the input styles. Where the style is a pixel value this can be taken as-is. Where the style is a percentage, this can be resolved against the width of the parent node (as computed by Taffy)

nicoburns avatar Feb 23 '23 11:02 nicoburns

@ickshonpe @JMS55 So, on the one hand I really want rounded corners. I want them NOW.

However, I also realize that rounded corners are only useful within the context of a particular visual style. Specifically, the style of a web app, where most UI elements are flat-shaded. Since the advent of Material UI, most web sites, and some productivity apps, have converged on a particular look that has rounded corners. The Bevy editor mockups make liberal use of rounded corners, because it's trying to look like Unity.

But many games will have a visual style that has no use for rounded corners (or shadows for that matter). A lot of games will use nine-patches, custom shaders, or other techniques to produce widgets that are novel and flashy.

Rather than building in support for rounded corners in Bevy, we could consider a different option: custom ui materials. Someone building an editor is likely going to rely on a widget library that has an opinionated look, and this library could include custom shaders that render rounded corners and shadows. This means extra work for the widget author, but not much if there are examples showing how to do it. It won't be extra work for people actually using the widgets in their apps.

If I had an example showing how to render rounded corners in a custom ui material, my problems would be solved :) And it wouldn't require a change to Bevy.

Also, adding rounded corners and shadows to Bevy UI nodes entails a number of web-centric assumptions. For example, it assumes that shadows are not separate entities, but are an extension of normal UI nodes. But for someone building a widget library, it's not especially burdensome to add an extra entity for the drop-shadow, which is ordered so that it renders beneath the element.

However, there's one aspect to all this that a custom material cannot easily provide: clipping. A custom material has no effect on child elements, so child elements can't be clipped to the rounded corners. However, I think the solution here is to allow custom clipping regions to be defined, because (again) not all games are going to use rounded corners, but some of them might want to use other shapes besides rectangles.

viridia avatar Feb 03 '24 22:02 viridia

I'd like to note that Bevy already supports most of what you would want to use for "game" UIs:

  • Border with border color
  • Nine-Patch for custom image-based borders
  • Custom UI Materials, so you can do whatever you want in a shader

The only notable thing missing, out of all the things mentioned in this issue, are rounded corners. To me, they seem unimportant, given that Nine-Patch is supported. You can draw your own rounded corners and make them look how you like. Bevy already gives you everything to have fully-themable / skinnable UIs.

I do agree with the previous comment that having a CSS-like rounded corner property feels needlessly web-centric, making assumptions about visual style that do not necessarily hold for most games. If you are making a quick and dirty UI, you don't need round corners. If you are making a pretty-looking UI, might as well go all the way and create Nine-Patch assets.

Should we close this issue?

inodentry avatar Apr 29 '24 11:04 inodentry

The only notable thing missing, out of all the things mentioned in this issue, are rounded corners.

I believe rounded corners are actually already supported as of https://github.com/bevyengine/bevy/pull/12500

nicoburns avatar Apr 29 '24 11:04 nicoburns

Agreed, the important parts of this issue have already been tackled, I'll close it out.

If we see the need for more advanced features like shadows or outlines, they probably warrant a separate issue as they are more controversial.

TimJentzsch avatar Apr 29 '24 12:04 TimJentzsch

I just want to add my agreement to closing this issue. I don't think Bevy should support shadows as a built-in feature, because:

  • Drop-shadows in game or editor UIs aren't common. For example, the editor mocks I have seen don't use any shadows.
  • It's relatively easy to implement with an auxiliary absolute-positioned rectangle, possibly with a custom UiMaterial to handle the blur.
  • It adds additional complexity to the UI rendering pipeline for an extremely rare use case.

viridia avatar May 22 '24 00:05 viridia