bevy_editor_prototypes
bevy_editor_prototypes copied to clipboard
Simple single line text field
trafficstars
Motivation
Currently, we don't have any widget that allows editing text or component values. So I decided to create a simple version of such a field.
Proposal
I created two components
LineTextField
- Single-line text editing
- Cursor positioning and text selection
- Clipboard operations (copy, cut, paste, select all | Ctrl-C,X,V,A)
- Support for text longer than field width
- Customizable allowed characters
NumericField<T>
- Supports multiple numeric types (u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64)
- Text-based input for precise value entry
- Mouse drag functionality for quick value adjustments
- Configurable min/max value constraints
- Customizable drag step (drag step can be less then 1 val per logical pixel)
And three crates
bevy_focus
This crate contains input focus managment
bevy_text_field
This crate contains text field logic. Builded on top of bevy_focus.
bevy_numeric_field
This crate builded on top of bevy_text_field and contains logic for NumericField<T>
Usage
// LineTextField
commands.spawn((
NodeBundle { /* ... */ },
LineTextField::new("Initial text"),
)).observ(|trigger: Trigger<TextChanged>| {
let text = trigger.event().0; //Do whatever with text
});
// Update text
let mut text_field = LineTextField::default();
text_field.set_text("bla bla bla");
// NumericField
commands.spawn((
NodeBundle { /* ... */ },
NumericField::<f32>::new(0.0),
)).observe(|trigger: Trigger<NewValue<f32>>| {
let new_value = trigger.event().0;
// Handle value change
});
// Update number
// We must use trigger because its contains complex logic for updating
commands.trigger_targets(SetValue(0.0), translation_x);
Testing
I created three examples for manual testing:
- single_line_text_field.rs - contains three size different single line text fields
- many_fields - contains all supported numeric fields
- transform.rs - contains mvp for changing transform with new numeric fields
- NumericField uses LineTextField in this work
The following features are not planned for this PR
- Multi-line editing
- Precise cursor positioning by clicking on the text field with the mouse
Followed work
- Move to i-cant-belive-this-is-not-bsn crate
- Move to Required components
- Create new SerializedField component, which allow to use LineTextField for any strut that support serialize/deserialize
- Create design for split huge LineTextField to nice sub components, which will allow to huge customization of this text field
- Unhardcode key bindings for copy/paste/cut
- Change cursor from byte position into char number position for more safety for non-english text
- Found a way to avoid invisible text nodes and text splitting