Replies: 1 comment 2 replies
-
I prefer the secret Option 3: enable the plugin by default, but make input bubbling a configurable, on-by-default setting. Plugins can be overridden with new settings by users who really want to customize the behavior / reduce overhead using |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
@ickshonpe recently implemented a text input widget that works with Bevy's cosmic-text integration. I would like to see this work upstreamed: I see it as an important part of the "core widgets" collection. However, there are some open questions.
Input Focus Integration
One issue is how the input widget should depend on the input focus crate.
Normally, when you have multiple input fields, input focus determines which input field is active and accepting input. Focusing a widget affects it in two ways: it causes input events to be routed to that widget, and it causes the cursor/selection highlight to be shown.
For the first of these two effects (routing input events), the actual widget does not need a direct dependency on the input focus crate, because the routing is handled by the focus framework. However, if the focus framework is absent (because the plugin has not been initialized) then the widget will not get any events and will not work.
For the second effect - showing and hiding the selection highlight - the widget needs to examine the
InputFocus
resource to see whether it has focus. This requires a direct dependency.The issue that was brought up on Discord is that our input focus plugin is not enabled by default. This means that a text input widget that has a dependency on the
InputFocus
resource can't function unless the plugin is enabled.There is a reason why input focus is not enabled by default. In addition to registering the resources (
InputFocus
andInputFocusVisible
), the plugin also enables bubbling of input events. Without the plugin, input events are just global events in an event queue. Since bubbling has a small but non-zero cost, some games might not want to enable this. Particularly, many games don't use input focus: instead, keyboard and gamepad events are directly mapped to game actions, there are no "widgets".Alternatively, if there is only one widget on the screen (such as "enter character name") there is also no need for input focus - you can just route keyboard events to the widget unconditionally via an event reader system.
The question is whether the text input widget can be decoupled from input focus. There are several possible approaches:
Option 1: split the plugin. Currently the input focus plugin has two jobs: registering the resources, and enabling bubbling of input events. We could divide this into two separate plugins, so that the resources were always registered by default (since the costs are small), but bubbling would be optional.
Note that with this option, a user who wants to use text input, but doesn't want to enable tab navigation behavior, would be required to manually set the
InputFocus
resource to the entity id of the text widget so that selection highlights are shown.Option 2: we could make a "headless" version of the text input widget. The philosophy of core widgets is that core widgets are agnostic with regards to appearance: it's up to the user to decide how they want to display things. The other core widgets like button and checkbox don't directly depend on input focus, because the focus highlight is purely a visual effect and doesn't impact the widget's behavior. Instead, it's the responsibility of the styled/opinionated widget that is built on the foundation of the core widget to display focus highlights, which means the styled widget would need to have a reference to focus - but that styled widget is not built into Bevy so we don't care about the dependency.
Unfortunately, it's much more complicated to make a headless text input widget than it is to make a headless checkbox or slider. The display of text requires a tight integration between the editing code and the display code. Selection rectangles, in a bidi world, aren't just simple rectangular regions, but may contain multiple discontiguous rectangles. Splitting the text input widget into a "core" part and a "styled" part would require a complex API surface between them.
Text Input on Consoles and Mobile Devices
For Xbox, Playstation, iOS and Android platforms, we generally don't want to have a text input widget at all - instead, we want to use the platform's native text input dialog. On these platforms, the Bevy "text widget" would be swapped out for a static text field which, when activated, would bring up the native input dialog.
I don't think that this "swapping out" behavior should be integrated into the core text input widget directly. Instead, I think that there should be some higher-level, opinionated widget, controlled by feature flags, which invokes the core widget, or not, depending on the current platform. This gives the user the option to use the core widget if they really want to, even on platforms where it is not the recommended practice.
One open challenge here is how to activate the platform's text input dialog at all - I don't know if there's existing Rust code capable of doing this. We would need some kind of support library for console- and mobile-specific APIs. A secondary challenge is how to abstract this functionality into a common API so that users don't have to write a bunch of platform-specific code for editing text.
@alice-i-cecile
Beta Was this translation helpful? Give feedback.
All reactions