Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
21fd041
Added scroll module, with scroll rules and the `TextViewport` type.
ickshonpe Jun 12, 2026
761fd4f
Added new `ScrollBy`, `ScrollTo`, and `ScrollByLines` `TextEdit`s
ickshonpe Jun 12, 2026
6b08d77
Added scrolling calculations and tests
ickshonpe Jun 12, 2026
e1105c6
Added `viewport: TextViewport` field to `EditableText`
ickshonpe Jun 13, 2026
bf8ebdb
Added `cursor_margin: Vec2` field to `EditableText`.
ickshonpe Jun 13, 2026
d931470
Added binds for the ScrollByLines TextEdit.
ickshonpe Jun 13, 2026
81b3403
Removed `TextScroll` component.
ickshonpe Jun 13, 2026
5f5afa1
Removed `TextScroll` component
ickshonpe Jun 13, 2026
dcf2031
updated testbed_ui
ickshonpe Jun 13, 2026
2f376a9
Combined minimal changes to move scrolling into bevy_text
ickshonpe Jun 15, 2026
d6bdf5d
Merge branch 'editable-text-viewport' into editable-text-scroll
ickshonpe Jun 15, 2026
2955c01
Merge branch 'main' into editable-text-scroll
ickshonpe Jun 15, 2026
b313462
Split borrow in update_editable_text_layout to avoid collecting lines.
ickshonpe Jun 15, 2026
c6dce10
Remove need to collect and smallvec dependency from scroll functions …
ickshonpe Jun 15, 2026
887e5f0
Moved IME composing guard back before local_pos calculated in on_poin…
ickshonpe Jun 15, 2026
877471c
Disable click propagation before the IME composing guard.
ickshonpe Jun 15, 2026
ce95792
Also always set focused if an `EditableText` found in `on_pointer_pre…
ickshonpe Jun 15, 2026
9275e82
Removed .chain() on single system.
ickshonpe Jun 15, 2026
a6316f4
Added failing test in `scroll` module with `LineBreak::WordBoundary`
ickshonpe Jun 15, 2026
ef43813
Extend scrollable_width with LineBreak::Boundary so cursor space adde…
ickshonpe Jun 15, 2026
fc1b140
Renamed scrollable_content_width to scrollable_text_layout_width.
ickshonpe Jun 15, 2026
53f029c
Remove Justify condition for `scrollable_text_width` cursor width.
ickshonpe Jun 15, 2026
97e1e56
Removed the unused justify parameter from scrollable_text_layout_width
ickshonpe Jun 15, 2026
c1bfd72
Removed redundant explicit link target
ickshonpe Jun 15, 2026
b8c00d4
Merge branch 'main' into editable-text-scroll
ickshonpe Jun 17, 2026
9dd71e9
used `Rect` `clamp_point` function instead of `Vec2` clamp
ickshonpe Jun 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 35 additions & 7 deletions crates/bevy_text/src/editing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,15 @@
// and `bevy_ui`, such as text layout and font management.

use crate::{
text_edit::{poll_and_apply_paste, TextEdit},
scroll::TextViewport,
text_edit::{poll_and_apply_paste, reveal_cursor, TextEdit},
FontCx, FontHinting, LayoutCx, LineHeight, TextBrush, TextColor, TextFont, TextLayout,
};
use alloc::sync::Arc;
use bevy_clipboard::ClipboardRead;
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::prelude::*;
use bevy_math::Vec2;
use core::time::Duration;
use parley::{FontContext, LayoutContext, PlainEditor, SplitString};

Expand Down Expand Up @@ -115,6 +117,8 @@ pub struct EditableText {
/// These operations should generally be batched together to avoid redundant layout work.
// The B: Brush generic here must match the brush used by `ComputedTextBlock` to ensure that the font system is compatible.
pub editor: PlainEditor<TextBrush>,
/// The bounds of the visible portion of the text layout.
pub viewport: TextViewport,
/// Text edit actions that have been requested but not yet applied.
///
/// These edits are processed in first-in, first-out order.
Expand All @@ -128,6 +132,11 @@ pub struct EditableText {
/// rather than draining further edits, so that everything after the paste stays correctly ordered *behind* it.
// TODO: this may cause unexpected stalls if the clipboard read takes too long. We may want to add a timeout.
pub pending_paste: Option<ClipboardRead>,
/// Cursor reveal margins as fractions of the viewport size.
///
/// Each component is applied to both edges of its axis. Values are clamped
/// to `0.0..=0.5`, and non-finite values are treated as zero.
pub cursor_margin: Vec2,
/// Cursor width, relative to font size
pub cursor_width: f32,
/// Cursor blink period in seconds.
Expand All @@ -151,6 +160,8 @@ impl Default for EditableText {
Self {
// Defaults selected to match `Text::default()`
editor: PlainEditor::new(100.),
viewport: TextViewport::default(),
cursor_margin: Vec2::splat(0.2),
pending_edits: Vec::new(),
pending_paste: None,
cursor_width: 0.2,
Expand Down Expand Up @@ -217,6 +228,8 @@ impl EditableText {
pending_edits,
pending_paste,
max_characters,
viewport,
cursor_margin,
..
} = self;

Expand All @@ -225,11 +238,15 @@ impl EditableText {
// First: resolve any paste carried over from a previous frame. If it's still
// pending, hold the remaining edits (untouched in `pending_edits`) for next frame
// so ordering relative to the paste is preserved.
if let Some(mut read) = pending_paste.take()
&& !poll_and_apply_paste(&mut read, &mut driver, *max_characters, &char_filter)
{
*pending_paste = Some(read);
return;
if let Some(mut read) = pending_paste.take() {
let generation = driver.editor.generation();
if !poll_and_apply_paste(&mut read, &mut driver, *max_characters, &char_filter) {
*pending_paste = Some(read);
return;
}
if generation != driver.editor.generation() {
reveal_cursor(&mut driver, viewport, *cursor_margin);
}
}

// Drain edits one at a time. A paste that resolves synchronously (always the case
Expand All @@ -239,15 +256,26 @@ impl EditableText {
while let Some(edit) = edits.next() {
match edit {
TextEdit::Paste => {
let generation = driver.editor.generation();
let mut read = clipboard.fetch_text();
if !poll_and_apply_paste(&mut read, &mut driver, *max_characters, &char_filter)
{
*pending_paste = Some(read);
pending_edits.extend(edits);
return;
}
if generation != driver.editor.generation() {
reveal_cursor(&mut driver, viewport, *cursor_margin);
}
}
other => other.apply(&mut driver, clipboard, *max_characters, &char_filter),
other => other.apply(
&mut driver,
viewport,
*cursor_margin,
clipboard,
*max_characters,
&char_filter,
),
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_text/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ mod font_loader;
mod glyph;
mod parley_context;
mod pipeline;
mod scroll;
mod text;
mod text_access;
mod text_edit;
Expand All @@ -57,6 +58,7 @@ pub use font_loader::*;
pub use glyph::*;
pub use parley_context::*;
pub use pipeline::*;
pub use scroll::*;
pub use text::*;
pub use text_access::*;
pub use text_edit::*;
Expand Down
Loading
Loading