Select all text in DragValue when gaining focus via keyboard (#7107)

Previously, the `DragValue` widget selected all text when focus was
gained via a mouse click, but didn't when focus was gained via keyboard.


https://github.com/user-attachments/assets/5e82ca2c-0214-4201-ad2d-056dabc05e92

This PR makes both gained focus behaving the same way by selecting the
text on focus gained via keyboard.


https://github.com/user-attachments/assets/f246c779-3368-428c-a6b2-cec20dbc20a6

- [x] I have followed the instructions in the PR template

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
Azkellas 2025-06-16 02:11:26 +02:00 committed by GitHub
parent 54fded362d
commit 96c34139fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 17 additions and 7 deletions

View File

@ -3,7 +3,7 @@
use std::{cmp::Ordering, ops::RangeInclusive};
use crate::{
emath, text, Button, CursorIcon, Key, Modifiers, NumExt as _, Response, RichText, Sense,
emath, text, Button, CursorIcon, Id, Key, Modifiers, NumExt as _, Response, RichText, Sense,
TextEdit, TextWrapMode, Ui, Widget, WidgetInfo, MINUS_CHAR_STR,
};
@ -569,6 +569,11 @@ impl Widget for DragValue<'_> {
.font(text_style),
);
// Select all text when the edit gains focus.
if ui.memory_mut(|mem| mem.gained_focus(id)) {
select_all_text(ui, id, response.id, &value_text);
}
let update = if update_while_editing {
// Update when the edit content has changed.
response.changed()
@ -623,12 +628,7 @@ impl Widget for DragValue<'_> {
if response.clicked() {
ui.data_mut(|data| data.remove::<String>(id));
ui.memory_mut(|mem| mem.request_focus(id));
let mut state = TextEdit::load_state(ui.ctx(), id).unwrap_or_default();
state.cursor.set_char_range(Some(text::CCursorRange::two(
text::CCursor::default(),
text::CCursor::new(value_text.chars().count()),
)));
state.store(ui.ctx(), response.id);
select_all_text(ui, id, response.id, &value_text);
} else if response.dragged() {
ui.ctx().set_cursor_icon(cursor_icon);
@ -759,6 +759,16 @@ pub(crate) fn clamp_value_to_range(x: f64, range: RangeInclusive<f64>) -> f64 {
}
}
/// Select all text in the `DragValue` text edit widget.
fn select_all_text(ui: &Ui, widget_id: Id, response_id: Id, value_text: &str) {
let mut state = TextEdit::load_state(ui.ctx(), widget_id).unwrap_or_default();
state.cursor.set_char_range(Some(text::CCursorRange::two(
text::CCursor::default(),
text::CCursor::new(value_text.chars().count()),
)));
state.store(ui.ctx(), response_id);
}
#[cfg(test)]
mod tests {
use super::clamp_value_to_range;