Skip to content

Commit 54fded3

Browse files
authored
Clamp text cursor positions in the same places where we used to (#7081)
Closes #7077. This fixes the problem shown in #7077 where clearing a `TextEdit` wouldn't reset its cursor position. I've fixed that by adding back the `TextCursorState::range` method, which clamps the selection range to that of the passed `Galley`, and calling it in the same places where it was called before #5785. (/cc @juancampa) * [x] I have followed the instructions in the PR template
1 parent df2c16e commit 54fded3

File tree

4 files changed

+24
-10
lines changed

4 files changed

+24
-10
lines changed

crates/egui/src/text_selection/label_text_selection.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ impl LabelSelectionState {
530530

531531
let mut cursor_state = self.cursor_for(ui, response, global_from_galley, galley);
532532

533-
let old_range = cursor_state.char_range();
533+
let old_range = cursor_state.range(galley);
534534

535535
if let Some(pointer_pos) = ui.ctx().pointer_interact_pos() {
536536
if response.contains_pointer() {
@@ -544,7 +544,7 @@ impl LabelSelectionState {
544544
}
545545
}
546546

547-
if let Some(mut cursor_range) = cursor_state.char_range() {
547+
if let Some(mut cursor_range) = cursor_state.range(galley) {
548548
let galley_rect = global_from_galley * Rect::from_min_size(Pos2::ZERO, galley.size());
549549
self.selection_bbox_this_frame = self.selection_bbox_this_frame.union(galley_rect);
550550

@@ -562,7 +562,7 @@ impl LabelSelectionState {
562562
}
563563

564564
// Look for changes due to keyboard and/or mouse interaction:
565-
let new_range = cursor_state.char_range();
565+
let new_range = cursor_state.range(galley);
566566
let selection_changed = old_range != new_range;
567567

568568
if let (true, Some(range)) = (selection_changed, new_range) {
@@ -632,7 +632,7 @@ impl LabelSelectionState {
632632
}
633633
}
634634

635-
let cursor_range = cursor_state.char_range();
635+
let cursor_range = cursor_state.range(galley);
636636

637637
let mut new_vertex_indices = vec![];
638638

crates/egui/src/text_selection/text_cursor_state.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ impl TextCursorState {
3535
self.ccursor_range
3636
}
3737

38+
/// The currently selected range of characters, clamped within the character
39+
/// range of the given [`Galley`].
40+
pub fn range(&self, galley: &Galley) -> Option<CCursorRange> {
41+
self.ccursor_range.map(|mut range| {
42+
range.primary = galley.clamp_cursor(&range.primary);
43+
range.secondary = galley.clamp_cursor(&range.secondary);
44+
range
45+
})
46+
}
47+
3848
/// Sets the currently selected range of characters.
3949
pub fn set_char_range(&mut self, ccursor_range: Option<CCursorRange>) {
4050
self.ccursor_range = ccursor_range;
@@ -69,7 +79,7 @@ impl TextCursorState {
6979
if response.hovered() && ui.input(|i| i.pointer.any_pressed()) {
7080
// The start of a drag (or a click).
7181
if ui.input(|i| i.modifiers.shift) {
72-
if let Some(mut cursor_range) = self.char_range() {
82+
if let Some(mut cursor_range) = self.range(galley) {
7383
cursor_range.primary = cursor_at_pointer;
7484
self.set_char_range(Some(cursor_range));
7585
} else {
@@ -81,7 +91,7 @@ impl TextCursorState {
8191
true
8292
} else if is_being_dragged {
8393
// Drag to select text:
84-
if let Some(mut cursor_range) = self.char_range() {
94+
if let Some(mut cursor_range) = self.range(galley) {
8595
cursor_range.primary = cursor_at_pointer;
8696
self.set_char_range(Some(cursor_range));
8797
}

crates/egui/src/widgets/text_edit/builder.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ impl TextEdit<'_> {
617617
}
618618

619619
let mut cursor_range = None;
620-
let prev_cursor_range = state.cursor.char_range();
620+
let prev_cursor_range = state.cursor.range(&galley);
621621
if interactive && ui.memory(|mem| mem.has_focus(id)) {
622622
ui.memory_mut(|mem| mem.set_focus_lock_filter(id, event_filter));
623623

@@ -720,7 +720,7 @@ impl TextEdit<'_> {
720720
let has_focus = ui.memory(|mem| mem.has_focus(id));
721721

722722
if has_focus {
723-
if let Some(cursor_range) = state.cursor.char_range() {
723+
if let Some(cursor_range) = state.cursor.range(&galley) {
724724
// Add text selection rectangles to the galley:
725725
paint_text_selection(&mut galley, ui.visuals(), &cursor_range, None);
726726
}
@@ -742,7 +742,7 @@ impl TextEdit<'_> {
742742
painter.galley(galley_pos, galley.clone(), text_color);
743743

744744
if has_focus {
745-
if let Some(cursor_range) = state.cursor.char_range() {
745+
if let Some(cursor_range) = state.cursor.range(&galley) {
746746
let primary_cursor_rect =
747747
cursor_rect(&galley, &cursor_range.primary, row_height)
748748
.translate(galley_pos.to_vec2());
@@ -898,7 +898,7 @@ fn events(
898898
) -> (bool, CCursorRange) {
899899
let os = ui.ctx().os();
900900

901-
let mut cursor_range = state.cursor.char_range().unwrap_or(default_cursor_range);
901+
let mut cursor_range = state.cursor.range(galley).unwrap_or(default_cursor_range);
902902

903903
// We feed state to the undoer both before and after handling input
904904
// so that the undoer creates automatic saves even when there are no events for a while.

crates/epaint/src/text/text_layout_types.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,10 @@ impl Galley {
11041104
}
11051105
}
11061106

1107+
pub fn clamp_cursor(&self, cursor: &CCursor) -> CCursor {
1108+
self.cursor_from_layout(self.layout_from_cursor(*cursor))
1109+
}
1110+
11071111
pub fn cursor_up_one_row(
11081112
&self,
11091113
cursor: &CCursor,

0 commit comments

Comments
 (0)