Resolve EditableText's scrolling per edit in bevy_text#24634
Resolve EditableText's scrolling per edit in bevy_text#24634ickshonpe wants to merge 26 commits into
EditableText's scrolling per edit in bevy_text#24634Conversation
Added viewport and margin params to `TextEdit::apply`
…by changing iterator trait bounds
…d after long unbroken words.
|
Your PR caused a change in the graphical output of an example or rendering test. This might be intentional, but it could also mean that something broke! If it's expected, please add the M-Deliberate-Rendering-Change label. If this change seems unrelated to your PR, you can consider updating your PR to target the latest main branch, either by rebasing or merging main into it. |
|
It looks like your PR is a breaking change, but you didn't provide a migration guide. Please review the instructions for writing migration guides, then expand or revise the content in the migration guides directory to reflect your changes. |
| TextEdit::Backspace => { | ||
| driver.backdelete(); | ||
| reveal_cursor(driver, viewport, cursor_margin); | ||
| } |
There was a problem hiding this comment.
Could you do a single if generation change then reveal_cursor at the end of the system?
There was a problem hiding this comment.
Not every editor change that updates the generation requires reveal_cursor afterwards. I thought about having a method needs_reveal_cursor on TextEdit but it felt less clear and explicit then calling it per match branch.
Also some edits that don't update the generation may still require reveal_cursor. Down when the cursor is on the last line, for instance.
There was a problem hiding this comment.
Another option I considered was adding a wrapper type containing the driver, viewport, and any options. Then we could reimplement the PlainDriver API over it but with the functions automatically updating the viewport as needed. Didn't want to make the PR any larger though.
Objective
Scrolling for `EditableText' is resolved per frame with different cases handled over a couple of systems. This makes it hard to reason about and test and puts the responsibility on widget authors to handle scrolling resolution which can get quite complicated when you have to consider different wrapping, justification, linebreak, and text direction settings.
Drag scrolling is framerate dependent, should be independent.
Scrolling and cursor behaviour is inconsistant, depending on layout settings.
Solution
New module
bevy_text::scroll. Includes a write up of the basic scrolling rules and a new structTextViewportalong with methods and helper functions and tests.TextViewportrepresents the region of the editable text layout visible to the user.EditableTexthas a newviewport: TextViewportfield.The
TextScrollcomponent is removed (replaced byTextViewport).There are three new
TextEdits:ScrollTo(Vec2)ScrollBy(Vec2)ScrollByLines(f32)Having scrolling controlled through
TextEdits makesEditableText's much easier to test. You can just apply a sequence ofTextEdits to anEditableText, no need to setup a full text pipeline.A new system
sync_editable_text_viewportsupdates eachTextViewport's size when anEditableTextnode's size is changed byui_layout_system.Drag scrolling is no longer event based and framerate independent. A new system
text_input_autoscroll_systemscrolls the viewport each frame when the input is being dragged with the point outside the viewport's bounds.Initially this also included a larger number of changes that split up
EditableTextinto multiple components and moved more functionality intobevy_text, but it was too much for one PR, so I split off just the scrolling work, which is the most important part.There are still some problems with RTL and non-left justified text, fixing at least some of those will need changes in Parley: #24587.
Testing
There a bunch of new tests included in
bevy_text::scroll,bevy_text::text_editandbevy_ui_widgets::text_input.Also
testbed_ui'sEditableTextscene has been updated:cargo run --example testbed_ui -- EditableText