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
This commit is contained in:
parent
df2c16ef0a
commit
54fded362d
|
|
@ -530,7 +530,7 @@ impl LabelSelectionState {
|
|||
|
||||
let mut cursor_state = self.cursor_for(ui, response, global_from_galley, galley);
|
||||
|
||||
let old_range = cursor_state.char_range();
|
||||
let old_range = cursor_state.range(galley);
|
||||
|
||||
if let Some(pointer_pos) = ui.ctx().pointer_interact_pos() {
|
||||
if response.contains_pointer() {
|
||||
|
|
@ -544,7 +544,7 @@ impl LabelSelectionState {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(mut cursor_range) = cursor_state.char_range() {
|
||||
if let Some(mut cursor_range) = cursor_state.range(galley) {
|
||||
let galley_rect = global_from_galley * Rect::from_min_size(Pos2::ZERO, galley.size());
|
||||
self.selection_bbox_this_frame = self.selection_bbox_this_frame.union(galley_rect);
|
||||
|
||||
|
|
@ -562,7 +562,7 @@ impl LabelSelectionState {
|
|||
}
|
||||
|
||||
// Look for changes due to keyboard and/or mouse interaction:
|
||||
let new_range = cursor_state.char_range();
|
||||
let new_range = cursor_state.range(galley);
|
||||
let selection_changed = old_range != new_range;
|
||||
|
||||
if let (true, Some(range)) = (selection_changed, new_range) {
|
||||
|
|
@ -632,7 +632,7 @@ impl LabelSelectionState {
|
|||
}
|
||||
}
|
||||
|
||||
let cursor_range = cursor_state.char_range();
|
||||
let cursor_range = cursor_state.range(galley);
|
||||
|
||||
let mut new_vertex_indices = vec![];
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,16 @@ impl TextCursorState {
|
|||
self.ccursor_range
|
||||
}
|
||||
|
||||
/// The currently selected range of characters, clamped within the character
|
||||
/// range of the given [`Galley`].
|
||||
pub fn range(&self, galley: &Galley) -> Option<CCursorRange> {
|
||||
self.ccursor_range.map(|mut range| {
|
||||
range.primary = galley.clamp_cursor(&range.primary);
|
||||
range.secondary = galley.clamp_cursor(&range.secondary);
|
||||
range
|
||||
})
|
||||
}
|
||||
|
||||
/// Sets the currently selected range of characters.
|
||||
pub fn set_char_range(&mut self, ccursor_range: Option<CCursorRange>) {
|
||||
self.ccursor_range = ccursor_range;
|
||||
|
|
@ -69,7 +79,7 @@ impl TextCursorState {
|
|||
if response.hovered() && ui.input(|i| i.pointer.any_pressed()) {
|
||||
// The start of a drag (or a click).
|
||||
if ui.input(|i| i.modifiers.shift) {
|
||||
if let Some(mut cursor_range) = self.char_range() {
|
||||
if let Some(mut cursor_range) = self.range(galley) {
|
||||
cursor_range.primary = cursor_at_pointer;
|
||||
self.set_char_range(Some(cursor_range));
|
||||
} else {
|
||||
|
|
@ -81,7 +91,7 @@ impl TextCursorState {
|
|||
true
|
||||
} else if is_being_dragged {
|
||||
// Drag to select text:
|
||||
if let Some(mut cursor_range) = self.char_range() {
|
||||
if let Some(mut cursor_range) = self.range(galley) {
|
||||
cursor_range.primary = cursor_at_pointer;
|
||||
self.set_char_range(Some(cursor_range));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -617,7 +617,7 @@ impl TextEdit<'_> {
|
|||
}
|
||||
|
||||
let mut cursor_range = None;
|
||||
let prev_cursor_range = state.cursor.char_range();
|
||||
let prev_cursor_range = state.cursor.range(&galley);
|
||||
if interactive && ui.memory(|mem| mem.has_focus(id)) {
|
||||
ui.memory_mut(|mem| mem.set_focus_lock_filter(id, event_filter));
|
||||
|
||||
|
|
@ -720,7 +720,7 @@ impl TextEdit<'_> {
|
|||
let has_focus = ui.memory(|mem| mem.has_focus(id));
|
||||
|
||||
if has_focus {
|
||||
if let Some(cursor_range) = state.cursor.char_range() {
|
||||
if let Some(cursor_range) = state.cursor.range(&galley) {
|
||||
// Add text selection rectangles to the galley:
|
||||
paint_text_selection(&mut galley, ui.visuals(), &cursor_range, None);
|
||||
}
|
||||
|
|
@ -742,7 +742,7 @@ impl TextEdit<'_> {
|
|||
painter.galley(galley_pos, galley.clone(), text_color);
|
||||
|
||||
if has_focus {
|
||||
if let Some(cursor_range) = state.cursor.char_range() {
|
||||
if let Some(cursor_range) = state.cursor.range(&galley) {
|
||||
let primary_cursor_rect =
|
||||
cursor_rect(&galley, &cursor_range.primary, row_height)
|
||||
.translate(galley_pos.to_vec2());
|
||||
|
|
@ -898,7 +898,7 @@ fn events(
|
|||
) -> (bool, CCursorRange) {
|
||||
let os = ui.ctx().os();
|
||||
|
||||
let mut cursor_range = state.cursor.char_range().unwrap_or(default_cursor_range);
|
||||
let mut cursor_range = state.cursor.range(galley).unwrap_or(default_cursor_range);
|
||||
|
||||
// We feed state to the undoer both before and after handling input
|
||||
// so that the undoer creates automatic saves even when there are no events for a while.
|
||||
|
|
|
|||
|
|
@ -1104,6 +1104,10 @@ impl Galley {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn clamp_cursor(&self, cursor: &CCursor) -> CCursor {
|
||||
self.cursor_from_layout(self.layout_from_cursor(*cursor))
|
||||
}
|
||||
|
||||
pub fn cursor_up_one_row(
|
||||
&self,
|
||||
cursor: &CCursor,
|
||||
|
|
|
|||
Loading…
Reference in New Issue