Skip to content

Commit c4a1d98

Browse files
authored
Use Bevy's built-in scrolling (#88)
1 parent 352a3dc commit c4a1d98

File tree

1 file changed

+27
-26
lines changed

1 file changed

+27
-26
lines changed

src/lib.rs

+27-26
Original file line numberDiff line numberDiff line change
@@ -470,36 +470,38 @@ fn update_value(
470470

471471
fn scroll_with_cursor(
472472
mut inner_text_query: Query<
473-
(&TextLayoutInfo, &mut Node, &ComputedNode, &Parent),
473+
(&TextLayoutInfo, &ComputedNode, &Parent),
474474
(With<TextInputInner>, Changed<TextLayoutInfo>),
475475
>,
476-
mut style_query: Query<(&ComputedNode, &mut Node), Without<TextInputInner>>,
476+
mut style_query: Query<
477+
(&ComputedNode, &mut Node, &mut ScrollPosition),
478+
Without<TextInputInner>,
479+
>,
477480
) {
478-
for (layout, mut style, child_node, parent) in inner_text_query.iter_mut() {
479-
let Ok((parent_node, mut parent_style)) = style_query.get_mut(parent.get()) else {
481+
for (layout, computed, parent) in inner_text_query.iter_mut() {
482+
let Ok((overflow_computed, mut overflow_style, mut overflow_scroll)) =
483+
style_query.get_mut(parent.get())
484+
else {
480485
continue;
481486
};
482487

483488
match layout.glyphs.last().map(|g| g.span_index) {
484-
// no text -> do nothing
489+
// No text, nothing to do.
485490
None => continue,
486-
// if cursor is at the end, position at FlexEnd so newly typed text does not take a frame
487-
// to move into view
491+
// If cursor is at the end, we can use FlexEnd so newly typed text does not take a
492+
// frame to move into view
488493
Some(1) => {
489-
style.left = Val::Auto;
490-
parent_style.justify_content = JustifyContent::FlexEnd;
494+
overflow_scroll.offset_x = 0.0;
495+
overflow_style.justify_content = JustifyContent::FlexEnd;
491496
continue;
492497
}
493498
_ => (),
494499
}
495500

496-
// if cursor is in the middle, we use FlexStart + `left` px for consistent behaviour when
497-
// typing the middle
498-
499-
let inverse_scale_factor = child_node.inverse_scale_factor();
501+
let inverse_scale_factor = computed.inverse_scale_factor();
500502

501-
let child_size = child_node.size().x * inverse_scale_factor;
502-
let parent_size = parent_node.size().x * inverse_scale_factor;
503+
let text_size = computed.size().x * inverse_scale_factor;
504+
let overflow_size = overflow_computed.size().x * inverse_scale_factor;
503505

504506
let Some(cursor_pos) = layout
505507
.glyphs
@@ -510,18 +512,17 @@ fn scroll_with_cursor(
510512
continue;
511513
};
512514

513-
let box_pos = match style.left {
514-
Val::Px(px) => -px,
515-
_ => child_size - parent_size,
516-
};
515+
let relative_pos = cursor_pos - overflow_scroll.offset_x;
516+
517+
if relative_pos < 0.0 || relative_pos > overflow_size {
518+
let req_px = overflow_size * 0.5 - cursor_pos;
519+
let req_px = req_px.clamp(overflow_size - text_size, 0.0);
517520

518-
let relative_pos = cursor_pos - box_pos;
521+
// If the cursor is not at the end, we use have to use FlexStart.
522+
// See https://github.com/bevyengine/bevy/issues/17129.
519523

520-
if relative_pos < 0.0 || relative_pos > parent_size {
521-
let req_px = parent_size * 0.5 - cursor_pos;
522-
let req_px = req_px.clamp(parent_size - child_size, 0.0);
523-
style.left = Val::Px(req_px);
524-
parent_style.justify_content = JustifyContent::FlexStart;
524+
overflow_scroll.offset_x = -req_px;
525+
overflow_style.justify_content = JustifyContent::FlexStart;
525526
}
526527
}
527528
}
@@ -629,7 +630,7 @@ fn create(
629630
let overflow_container = commands
630631
.spawn((
631632
Node {
632-
overflow: Overflow::clip(),
633+
overflow: Overflow::scroll_x(),
633634
justify_content: JustifyContent::FlexEnd,
634635
max_width: Val::Percent(100.),
635636
..default()

0 commit comments

Comments
 (0)