-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Text input support #20326
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
base: main
Are you sure you want to change the base?
Text input support #20326
Conversation
Added `Clipboard` and `ClipboardContents` to the prelude.
… support for platform.
Added `TextInputCommands` component that wraps a `TextInputCommand` queue.
`load_font_to_fontdb` now has a parameter for the font handle instead of the text_font component.
It should be trivial to create a basic virtual keyboard by spawning a button for each key and on button presses sending the corresponding |
On the web, a multi-line text input is called a "textarea" - I think that might be a better name, or at least one that users will be more familiar with. The problem I have with the word "box" is that it doesn't immediately suggest multi-line-ness to me (since both multi-line and single-line inputs are technically "boxes" as well as "fields"). (And, yes, you can also argue that the word "area" applies to both as well - but the long-established convention in HTML is that area is multi-line.) |
I patched in the PR to my local workspace and ran the examples. One of the first things I did was to try and paste in some arabic text (just go to any arabic website and copy) but then I realized we don't have clipboard support yet. Doh! Note that even if we did have clipboard support, I wouldn't expect non-latin scripts to work out of the box unless we used a font with support for that language. |
I want to merge #20336 first in time for 0.17, then rebase and land this for the start of Bevy 0.18. |
Since this missed the 0.17 cutoff, I might as well merge in the |
All right. There is another advantage (for me) to doing the widgets post-0.17, which is that by then we should have a preliminary version of BSN in-tree. Since all of the feathers widgets are going to be converted to BSN, if I am going to write a feathers text input based on this I'd rather it be BSN from the start. I attempted to merge cart's BSN branch with this PR, and the merge mostly went OK, but there are some sticking points as cart's branch is about two weeks old, and there are some other conflicts:
I did run all the examples, and things look really good overall. I haven't yet gone through the PR line-by-line. |
BTW, a site I discovered today is "arabic lorem ipsum": https://www.loremipzum.com/ar/ |
I'm not in love with the name "TextBox" either, I've changed it multiple times already. "TextArea" seems like it would be fine and it makes sense to pick something familiar. |
…nd paste actions.
…into text-input-widget
Added the system clipboard support just now, seems to work but I'll clean it up and test it properly tomorrow. |
I'm less concerned right now that we get the correct behavior, as long as some Bevy developer that is familiar with these input methods can hack on it without having to re-invent the whole framework from scratch. I'll ask on Discord to see if anyone knows about this. |
There are some subtle issues with selection rects. For the multi-line widget, when I select a line ending in either a soft or hard break (that is, either a space or newline), the selection rect does not include the whitespace character. This creates an ambiguous situation whereby the user cannot tell whether the selection includes the line ending or not. It used to be the case that for most desktop operating systems, when a selection included whitespace at the end of a line, the selection rect would be extended all the way to the right margin of the text input widget. However, this rule is not consistently enforced: VSCode and Chrome don't do this, but Scrivener (which is the only word-processor-like app I currently have installed) does. For bidirectional text, the example video posted in the discord channel makes me think that perhaps we're not properly handling discontiguous selection rects in the single-line case. If I have a run of text consisting of 10 characters of LTR script, followed by 10 characters of RTL script, and if the selection extends from character index 5 to 15, then there should be two separate selection rects:
In the single-line case, there can be at most 3 separate selection rects. I am OK if these issues are addressed in a follow-up PR or even a point release, as they are not critical for most users. |
Objective
Add support for text inputs using cosmic text's
Editor
API.Solution
Two new UI widgets,
TextBox
andTextField
.TextBox
is for full multi-line text editing.TextField
is for single line text editing and supports numerical and password modes.There are three new modules:
bevy_text::input
: Contains the text buffer, undo history and layout components, handles their updates and dispatchesTextInputEvent
s.bevy_ui::widgets::text_box
: Contains common shared UI text input systems and components and theTextBox
input widget implementation.bevy_ui::widgets::text_field
: Contains theTextField
specific components and systems.Rendering is handled by
extract_text_input_nodes
in thebevy_ui_render
crate.TextBox
andTextField
have their own pluginTextInputPlugin
that isn't included by default because they require theInputDispatchPlugin
to work.Not very satisfied with the implementation but needed to stop wasting time fussing around with it. There are too many features for a single PR and some parts still feel a bit chaotic and over complicated. In particular state management is a bit all over the place. Each text input widget has a queue of
TextInputActions
that are applied to the cosmic-text buffer inPostUpdate
after layout updates. There is aTextInputValue
component that, if present, is updated each frame with the current text from the buffer. Inserting a newTextInputValue
overwrites the current contents of the buffer. Maybe it needs aCallback
somewhere as well, possibly replacing theTextInputValue
component, I'm not sure.The widget modules were put in the
bevy_ui
crate rather thanbevy_core_widgets
orbevy_feathers
. Was very indecisive about this butbevy_core_widgets
is for widgets with no inherent styling and the text input widgets are inherently styled because of the fonts.Features
Bugs
Not supported yet
Text
entities.bevy_2d
input using text2dTesting
Four examples:
text_input
line_input_node
password_input
text_box
The
text_input
example is the most complete, the others are rougher ones I was using for testing. Needs an example to make sure that the widgets update correctly and don't get stuck in an invalid state after multiple changes to the font sizes, line height, visible lines, target size etc..Showcase
I'll complete the migration guides and release notes a bit later, going to take a break for a few hours.