diff options
author | 2020-03-24 20:36:33 +0100 | |
---|---|---|
committer | 2020-03-24 20:36:33 +0100 | |
commit | 28382a47d3abd4f79064b610f1a2eca478a08595 (patch) | |
tree | 1ddcfc6f7d15293c8287e569ba0ad99cf0c514ee /native | |
parent | 6b89dd7db9715dd46738677e13ca9d9bd12f9636 (diff) | |
download | iced-28382a47d3abd4f79064b610f1a2eca478a08595.tar.gz iced-28382a47d3abd4f79064b610f1a2eca478a08595.tar.bz2 iced-28382a47d3abd4f79064b610f1a2eca478a08595.zip |
Move `Value` to its own module
Diffstat (limited to 'native')
-rw-r--r-- | native/src/widget/text_input.rs | 147 | ||||
-rw-r--r-- | native/src/widget/text_input/value.rs | 134 |
2 files changed, 142 insertions, 139 deletions
diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index f5ca16e1..7e77b76a 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -4,9 +4,12 @@ //! //! [`TextInput`]: struct.TextInput.html //! [`State`]: struct.State.html +mod value; + pub mod cursor; pub use cursor::Cursor; +pub use value::Value; use crate::{ input::{ @@ -19,7 +22,6 @@ use crate::{ }; use std::u32; -use unicode_segmentation::UnicodeSegmentation; /// A field that can be filled with text. /// @@ -362,12 +364,12 @@ where self.state.cursor.move_left(&self.value); } None => { - if self.state.cursor.start(&self.value) > 0 { + let start = self.state.cursor.start(&self.value); + + if start > 0 { self.state.cursor.move_left(&self.value); - let _ = self.value.remove( - self.state.cursor.start(&self.value), - ); + let _ = self.value.remove(start - 1); } } } @@ -383,7 +385,7 @@ where None => { let end = self.state.cursor.end(&self.value); - if end > 0 { + if end < self.value.len() { let _ = self.value.remove(end); } } @@ -691,139 +693,6 @@ impl State { } } -/// The value of a [`TextInput`]. -/// -/// [`TextInput`]: struct.TextInput.html -// TODO: Reduce allocations, cache results (?) -#[derive(Debug, Clone)] -pub struct Value { - graphemes: Vec<String>, -} - -impl Value { - /// Creates a new [`Value`] from a string slice. - /// - /// [`Value`]: struct.Value.html - pub fn new(string: &str) -> Self { - let graphemes = UnicodeSegmentation::graphemes(string, true) - .map(String::from) - .collect(); - - Self { graphemes } - } - - /// Returns the total amount of graphemes in the [`Value`]. - /// - /// [`Value`]: struct.Value.html - pub fn len(&self) -> usize { - self.graphemes.len() - } - - /// Returns the position of the previous start of a word from the given - /// grapheme `index`. - /// - /// [`Value`]: struct.Value.html - pub fn previous_start_of_word(&self, index: usize) -> usize { - let previous_string = - &self.graphemes[..index.min(self.graphemes.len())].concat(); - - UnicodeSegmentation::split_word_bound_indices(&previous_string as &str) - .filter(|(_, word)| !word.trim_start().is_empty()) - .next_back() - .map(|(i, previous_word)| { - index - - UnicodeSegmentation::graphemes(previous_word, true) - .count() - - UnicodeSegmentation::graphemes( - &previous_string[i + previous_word.len()..] as &str, - true, - ) - .count() - }) - .unwrap_or(0) - } - - /// Returns the position of the next end of a word from the given grapheme - /// `index`. - /// - /// [`Value`]: struct.Value.html - pub fn next_end_of_word(&self, index: usize) -> usize { - let next_string = &self.graphemes[index..].concat(); - - UnicodeSegmentation::split_word_bound_indices(&next_string as &str) - .filter(|(_, word)| !word.trim_start().is_empty()) - .next() - .map(|(i, next_word)| { - index - + UnicodeSegmentation::graphemes(next_word, true).count() - + UnicodeSegmentation::graphemes( - &next_string[..i] as &str, - true, - ) - .count() - }) - .unwrap_or(self.len()) - } - - /// Returns a new [`Value`] containing the graphemes until the given - /// `index`. - /// - /// [`Value`]: struct.Value.html - pub fn until(&self, index: usize) -> Self { - let graphemes = self.graphemes[..index.min(self.len())].to_vec(); - - Self { graphemes } - } - - /// Converts the [`Value`] into a `String`. - /// - /// [`Value`]: struct.Value.html - pub fn to_string(&self) -> String { - self.graphemes.concat() - } - - /// Inserts a new `char` at the given grapheme `index`. - pub fn insert(&mut self, index: usize, c: char) { - self.graphemes.insert(index, c.to_string()); - - self.graphemes = - UnicodeSegmentation::graphemes(&self.to_string() as &str, true) - .map(String::from) - .collect(); - } - - /// Inserts a bunch of graphemes at the given grapheme `index`. - pub fn insert_many(&mut self, index: usize, mut value: Value) { - let _ = self - .graphemes - .splice(index..index, value.graphemes.drain(..)); - } - - /// Removes the grapheme at the given `index`. - /// - /// [`Value`]: struct.Value.html - pub fn remove(&mut self, index: usize) { - let _ = self.graphemes.remove(index); - } - - /// Removes the graphemes from `start` to `end`. - pub fn remove_many(&mut self, start: usize, end: usize) { - let _ = self.graphemes.splice(start..end, std::iter::empty()); - } - - /// Returns a new [`Value`] with all its graphemes replaced with the - /// dot ('•') character. - /// - /// [`Value`]: struct.Value.html - pub fn secure(&self) -> Self { - Self { - graphemes: std::iter::repeat(String::from("•")) - .take(self.graphemes.len()) - .collect(), - } - } -} - // TODO: Reduce allocations fn find_cursor_position<Renderer: self::Renderer>( renderer: &Renderer, diff --git a/native/src/widget/text_input/value.rs b/native/src/widget/text_input/value.rs new file mode 100644 index 00000000..1e9ba45b --- /dev/null +++ b/native/src/widget/text_input/value.rs @@ -0,0 +1,134 @@ +use unicode_segmentation::UnicodeSegmentation; + +/// The value of a [`TextInput`]. +/// +/// [`TextInput`]: struct.TextInput.html +// TODO: Reduce allocations, cache results (?) +#[derive(Debug, Clone)] +pub struct Value { + graphemes: Vec<String>, +} + +impl Value { + /// Creates a new [`Value`] from a string slice. + /// + /// [`Value`]: struct.Value.html + pub fn new(string: &str) -> Self { + let graphemes = UnicodeSegmentation::graphemes(string, true) + .map(String::from) + .collect(); + + Self { graphemes } + } + + /// Returns the total amount of graphemes in the [`Value`]. + /// + /// [`Value`]: struct.Value.html + pub fn len(&self) -> usize { + self.graphemes.len() + } + + /// Returns the position of the previous start of a word from the given + /// grapheme `index`. + /// + /// [`Value`]: struct.Value.html + pub fn previous_start_of_word(&self, index: usize) -> usize { + let previous_string = + &self.graphemes[..index.min(self.graphemes.len())].concat(); + + UnicodeSegmentation::split_word_bound_indices(&previous_string as &str) + .filter(|(_, word)| !word.trim_start().is_empty()) + .next_back() + .map(|(i, previous_word)| { + index + - UnicodeSegmentation::graphemes(previous_word, true) + .count() + - UnicodeSegmentation::graphemes( + &previous_string[i + previous_word.len()..] as &str, + true, + ) + .count() + }) + .unwrap_or(0) + } + + /// Returns the position of the next end of a word from the given grapheme + /// `index`. + /// + /// [`Value`]: struct.Value.html + pub fn next_end_of_word(&self, index: usize) -> usize { + let next_string = &self.graphemes[index..].concat(); + + UnicodeSegmentation::split_word_bound_indices(&next_string as &str) + .filter(|(_, word)| !word.trim_start().is_empty()) + .next() + .map(|(i, next_word)| { + index + + UnicodeSegmentation::graphemes(next_word, true).count() + + UnicodeSegmentation::graphemes( + &next_string[..i] as &str, + true, + ) + .count() + }) + .unwrap_or(self.len()) + } + + /// Returns a new [`Value`] containing the graphemes until the given + /// `index`. + /// + /// [`Value`]: struct.Value.html + pub fn until(&self, index: usize) -> Self { + let graphemes = self.graphemes[..index.min(self.len())].to_vec(); + + Self { graphemes } + } + + /// Converts the [`Value`] into a `String`. + /// + /// [`Value`]: struct.Value.html + pub fn to_string(&self) -> String { + self.graphemes.concat() + } + + /// Inserts a new `char` at the given grapheme `index`. + pub fn insert(&mut self, index: usize, c: char) { + self.graphemes.insert(index, c.to_string()); + + self.graphemes = + UnicodeSegmentation::graphemes(&self.to_string() as &str, true) + .map(String::from) + .collect(); + } + + /// Inserts a bunch of graphemes at the given grapheme `index`. + pub fn insert_many(&mut self, index: usize, mut value: Value) { + let _ = self + .graphemes + .splice(index..index, value.graphemes.drain(..)); + } + + /// Removes the grapheme at the given `index`. + /// + /// [`Value`]: struct.Value.html + pub fn remove(&mut self, index: usize) { + let _ = self.graphemes.remove(index); + } + + /// Removes the graphemes from `start` to `end`. + pub fn remove_many(&mut self, start: usize, end: usize) { + let _ = self.graphemes.splice(start..end, std::iter::empty()); + } + + /// Returns a new [`Value`] with all its graphemes replaced with the + /// dot ('•') character. + /// + /// [`Value`]: struct.Value.html + pub fn secure(&self) -> Self { + Self { + graphemes: std::iter::repeat(String::from("•")) + .take(self.graphemes.len()) + .collect(), + } + } +} |