diff options
author | 2019-12-06 04:46:53 +0100 | |
---|---|---|
committer | 2019-12-06 04:46:53 +0100 | |
commit | a56eef0fecff3ef39576327c042927724e21b760 (patch) | |
tree | 730ec2f44e66ed92db9b202d8c84c69110a3cb8c /native | |
parent | 114a759d2cb6740c2dce405cbc96ed7874a8842c (diff) | |
download | iced-a56eef0fecff3ef39576327c042927724e21b760.tar.gz iced-a56eef0fecff3ef39576327c042927724e21b760.tar.bz2 iced-a56eef0fecff3ef39576327c042927724e21b760.zip |
Use `unicode-segmentation` for `text_input::Value`
Diffstat (limited to '')
-rw-r--r-- | native/Cargo.toml | 1 | ||||
-rw-r--r-- | native/src/widget/text_input.rs | 51 |
2 files changed, 34 insertions, 18 deletions
diff --git a/native/Cargo.toml b/native/Cargo.toml index 7993676e..6ece36e4 100644 --- a/native/Cargo.toml +++ b/native/Cargo.toml @@ -11,3 +11,4 @@ repository = "https://github.com/hecrj/iced" iced_core = { version = "0.1.0", path = "../core", features = ["command"] } twox-hash = "1.5" raw-window-handle = "0.3" +unicode-segmentation = "1.6" diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index 0620e928..6ab90bf4 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -9,6 +9,7 @@ use crate::{ layout, Element, Event, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; +use unicode_segmentation::UnicodeSegmentation; /// A field that can be filled with text. /// @@ -441,23 +442,29 @@ impl State { /// The value of a [`TextInput`]. /// /// [`TextInput`]: struct.TextInput.html -// TODO: Use `unicode-segmentation` +// TODO: Reduce allocations, cache results (?) #[derive(Debug)] -pub struct Value(Vec<char>); +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 { - Self(string.chars().collect()) + let graphemes = UnicodeSegmentation::graphemes(string, true) + .map(String::from) + .collect(); + + Self { graphemes } } - /// Returns the total amount of `char` in the [`Value`]. + /// Returns the total amount of graphemes in the [`Value`]. /// /// [`Value`]: struct.Value.html pub fn len(&self) -> usize { - self.0.len() + self.graphemes.len() } /// Returns the position of the previous start of a word from the given @@ -469,9 +476,9 @@ impl Value { while index > 0 { if skip_space { - skip_space = self.0[index - 1] == ' '; + skip_space = self.graphemes[index - 1] == " "; } else { - if self.0[index - 1] == ' ' { + if self.graphemes[index - 1] == " " { break; } } @@ -488,11 +495,11 @@ impl Value { pub fn next_end_of_word(&self, mut index: usize) -> usize { let mut skip_space = true; - while index < self.0.len() { + while index < self.graphemes.len() { if skip_space { - skip_space = self.0[index] == ' '; + skip_space = self.graphemes[index] == " "; } else { - if self.0[index] == ' ' { + if self.graphemes[index] == " " { break; } } @@ -503,33 +510,41 @@ impl Value { index } - /// Returns a new [`Value`] containing the `char` until the given `index`. + /// Returns a new [`Value`] containing the graphemes until the given `index`. /// /// [`Value`]: struct.Value.html pub fn until(&self, index: usize) -> Self { - Self(self.0[..index.min(self.len())].to_vec()) + 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 { - use std::iter::FromIterator; - String::from_iter(self.0.iter()) + self.graphemes.concat() } - /// Inserts a new `char` at the given `index`. + /// Inserts a new `char` at the given grapheme `index`. /// /// [`Value`]: struct.Value.html pub fn insert(&mut self, index: usize, c: char) { - self.0.insert(index, c); + self.graphemes.insert(index, c.to_string()); + + self.graphemes = UnicodeSegmentation::graphemes( + self.graphemes.concat().as_ref() as &str, + true, + ) + .map(String::from) + .collect(); } - /// Removes the `char` at the given `index`. + /// Removes the grapheme at the given `index`. /// /// [`Value`]: struct.Value.html pub fn remove(&mut self, index: usize) { - let _ = self.0.remove(index); + let _ = self.graphemes.remove(index); } } |