diff options
author | Emil Ernerfeldt <emil.ernerfeldt@gmail.com> | 2024-06-30 14:34:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-30 14:34:36 +0200 |
commit | 6222e031b580be49b61ee499a50cb9da8f179734 (patch) | |
tree | e1fdd68ea360d97f13076bd1c71b24cc3090e441 | |
parent | b6fd1cfc99879f5a224c7c6c83626e1f1ff4ced3 (diff) |
The default parser for `DragValue` and `Slider` now ignores whitespace (#4739)
It's easy to include whitespace when copy-pasting values. Also, some
formatters use half-spaces as thousands separators.
-rw-r--r-- | crates/egui/src/widgets/drag_value.rs | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/crates/egui/src/widgets/drag_value.rs b/crates/egui/src/widgets/drag_value.rs index e46a454f..509dc5f9 100644 --- a/crates/egui/src/widgets/drag_value.rs +++ b/crates/egui/src/widgets/drag_value.rs @@ -491,10 +491,7 @@ impl<'a> Widget for DragValue<'a> { if let Some(value_text) = value_text { // We were editing the value as text last frame, but lost focus. // Make sure we applied the last text value: - let parsed_value = match &custom_parser { - Some(parser) => parser(&value_text), - None => value_text.parse().ok(), - }; + let parsed_value = parse(&custom_parser, &value_text); if let Some(mut parsed_value) = parsed_value { if clamp_to_range { parsed_value = clamp_value_to_range(parsed_value, range.clone()); @@ -530,10 +527,7 @@ impl<'a> Widget for DragValue<'a> { response.lost_focus() && !ui.input(|i| i.key_pressed(Key::Escape)) }; if update { - let parsed_value = match &custom_parser { - Some(parser) => parser(&value_text), - None => value_text.parse().ok(), - }; + let parsed_value = parse(&custom_parser, &value_text); if let Some(mut parsed_value) = parsed_value { if clamp_to_range { parsed_value = clamp_value_to_range(parsed_value, range.clone()); @@ -675,6 +669,19 @@ impl<'a> Widget for DragValue<'a> { } } +fn parse(custom_parser: &Option<NumParser<'_>>, value_text: &str) -> Option<f64> { + match &custom_parser { + Some(parser) => parser(value_text), + None => default_parser(value_text), + } +} + +fn default_parser(value_text: &str) -> Option<f64> { + // Ignore whitespace (trailing, leading, and thousands separators): + let value_text: String = value_text.chars().filter(|c| !c.is_whitespace()).collect(); + value_text.parse().ok() +} + fn clamp_value_to_range(x: f64, range: RangeInclusive<f64>) -> f64 { let (mut min, mut max) = (*range.start(), *range.end()); @@ -719,4 +726,23 @@ mod tests { total_assert_eq!(5.0_f64, clamp_value_to_range(15.0, 5.0..=1.0)); total_assert_eq!(1.0_f64, clamp_value_to_range(-5.0, 5.0..=1.0)); } + + #[test] + fn test_default_parser() { + assert_eq!(super::default_parser("123"), Some(123.0)); + + assert_eq!(super::default_parser("1.23"), Some(1.230)); + + assert_eq!( + super::default_parser(" 1.23 "), + Some(1.230), + "We should handle leading and trailing spaces" + ); + + assert_eq!( + super::default_parser("1 234 567"), + Some(1_234_567.0), + "We should handle thousands separators using half-space" + ); + } } |