From 7eb5caaae8118eec65174c8eca2d706b54d90705 Mon Sep 17 00:00:00 2001 From: Sean Cohan Date: Fri, 27 May 2022 22:28:52 -0400 Subject: [PATCH 1/4] Added OptionFormatter TextBox Formatter --- druid/src/text/format.rs | 53 ++++++++++++++++++++++++++++++++++++++++ druid/src/text/mod.rs | 4 ++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/druid/src/text/format.rs b/druid/src/text/format.rs index 5c1affc29d..d8fdb98236 100644 --- a/druid/src/text/format.rs +++ b/druid/src/text/format.rs @@ -225,3 +225,56 @@ impl Default for ParseFormatter { ParseFormatter::new() } } + +/// A naive [`Formatter`] for optional types that implement [`FromStr`]. +/// +/// Some types that impl [`FromStr`], such as scalar values, do not allow empty strings as valid values. +/// In these cases, a user can not remove all text from the text box. +/// To allow users to remove all text, an option can be used to account for empty strings. +/// +/// [`Formatter`]: Formatter +/// [`FromStr`]: std::str::FromStr +/// ``` +/// use druid::text::OptionFormatter; +/// use druid::{Data, Lens, Widget, WidgetExt}; +/// use druid::widget::TextBox; +/// #[derive(Data, Clone, Lens)] +/// struct State { +/// float: Option +/// } +/// +/// fn optional_float_text_box() -> impl Widget { +/// TextBox::new().with_formatter(OptionFormatter).lens(State::float) +/// } +/// ``` +pub struct OptionFormatter; + +impl Formatter> for OptionFormatter +where + T: std::fmt::Display + FromStr, + ::Err: std::error::Error + 'static, +{ + fn format(&self, value: &Option) -> String { + match value { + None => String::new(), + Some(value) => value.to_string(), + } + } + + fn validate_partial_input(&self, input: &str, _sel: &Selection) -> Validation { + if input.is_empty() { + return Validation::success(); + } + match input.parse::() { + Ok(_) => Validation::success(), + Err(e) => Validation::failure(e), + } + } + + fn value(&self, input: &str) -> Result, ValidationError> { + if input.is_empty() { + return Ok(None); + } + Some(input.parse::().map_err(ValidationError::new)).transpose() + } +} diff --git a/druid/src/text/mod.rs b/druid/src/text/mod.rs index 6e82322fb8..8dfe9952ed 100644 --- a/druid/src/text/mod.rs +++ b/druid/src/text/mod.rs @@ -43,7 +43,9 @@ pub use self::attribute::{Attribute, AttributeSpans, Link}; pub use self::backspace::offset_for_delete_backwards; pub use self::editable_text::{EditableText, EditableTextCursor, StringCursor}; pub use self::font_descriptor::FontDescriptor; -pub use self::format_priv::{Formatter, ParseFormatter, Validation, ValidationError}; +pub use self::format_priv::{ + Formatter, OptionFormatter, ParseFormatter, Validation, ValidationError, +}; pub use self::layout::{LayoutMetrics, TextLayout}; pub use self::movement::movement; pub use input_component::{EditSession, TextComponent}; From 81be4bfe49d40238da297465c27302a1cd654ce2 Mon Sep 17 00:00:00 2001 From: Sean Cohan Date: Fri, 27 May 2022 22:35:25 -0400 Subject: [PATCH 2/4] Modified changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49df2b4eff..449f3fb21a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ You can find its changes [documented below](#070---2021-01-01). ### Added +- OptionFormatter TextBox Formatter ([#2193] by [@meettitan]) - Strikethrough rich text attribute ([#1953] by [@jenra-uwu]) - System fonts loaded so that SVG images render text ([#1850] by [@DrGabble]) - Add `scroll()` method in WidgetExt ([#1600] by [@totsteps]) From 05731076724b652420adce82810439674e0fc42b Mon Sep 17 00:00:00 2001 From: Sean Cohan Date: Fri, 27 May 2022 23:26:40 -0400 Subject: [PATCH 3/4] Modified docs --- druid/src/text/format.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/druid/src/text/format.rs b/druid/src/text/format.rs index d8fdb98236..47c7a5def8 100644 --- a/druid/src/text/format.rs +++ b/druid/src/text/format.rs @@ -228,8 +228,9 @@ impl Default for ParseFormatter { /// A naive [`Formatter`] for optional types that implement [`FromStr`]. /// -/// Some types that impl [`FromStr`], such as scalar values, do not allow empty strings as valid values. -/// In these cases, a user can not remove all text from the text box. +/// Maps empty strings to None +/// Some types that impl [`FromStr`], such as integer values, do not allow empty strings as valid values. +/// In these cases, a user cannot remove all text from the text box. /// To allow users to remove all text, an option can be used to account for empty strings. /// /// [`Formatter`]: Formatter From 86423a64debfecda4a700078c4555bae17d9d3ab Mon Sep 17 00:00:00 2001 From: Sean Cohan Date: Sat, 28 May 2022 00:06:41 -0400 Subject: [PATCH 4/4] Added Sean Cohan to AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index dfa6b9f233..9217880595 100644 --- a/AUTHORS +++ b/AUTHORS @@ -21,3 +21,4 @@ Laura Gallo Tim Murison Manmeet Singh Simon Fell +Sean Cohan