diff options
| author | 2020-03-24 20:23:31 +0100 | |
|---|---|---|
| committer | 2020-03-24 20:23:31 +0100 | |
| commit | 6b89dd7db9715dd46738677e13ca9d9bd12f9636 (patch) | |
| tree | a37fbdece73f8b4ab348cc8ac9e1eb1fc0040d6e /native | |
| parent | 763f64b653e69b46715dcd8f7918ed769639098c (diff) | |
| download | iced-6b89dd7db9715dd46738677e13ca9d9bd12f9636.tar.gz iced-6b89dd7db9715dd46738677e13ca9d9bd12f9636.tar.bz2 iced-6b89dd7db9715dd46738677e13ca9d9bd12f9636.zip  | |
Improve `text_input::cursor` API
Diffstat (limited to '')
| -rw-r--r-- | native/src/lib.rs | 2 | ||||
| -rw-r--r-- | native/src/widget/text_input.rs | 78 | ||||
| -rw-r--r-- | native/src/widget/text_input/cursor.rs | 98 | 
3 files changed, 89 insertions, 89 deletions
diff --git a/native/src/lib.rs b/native/src/lib.rs index d17dd918..5c6ab3ee 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -34,7 +34,7 @@  //! [`window::Renderer`]: window/trait.Renderer.html  //! [`UserInterface`]: struct.UserInterface.html  //! [renderer]: renderer/index.html -#![deny(missing_docs)] +//#![deny(missing_docs)]  #![deny(missing_debug_implementations)]  #![deny(unused_results)]  #![forbid(unsafe_code)] diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index c379f0d1..f5ca16e1 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -4,17 +4,18 @@  //!  //! [`TextInput`]: struct.TextInput.html  //! [`State`]: struct.State.html -mod cursor; +pub mod cursor; + +pub use cursor::Cursor; +  use crate::{      input::{          keyboard,          mouse::{self, click},          ButtonState,      }, -    layout, -    widget::text_input::cursor::Cursor, -    Clipboard, Element, Event, Font, Hasher, Layout, Length, Point, Rectangle, -    Size, Widget, +    layout, Clipboard, Element, Event, Font, Hasher, Layout, Length, Point, +    Rectangle, Size, Widget,  };  use std::u32; @@ -261,7 +262,8 @@ where                              if self.is_secure {                                  self.state.cursor.select_all(&self.value);                              } else { -                                let end = self.state.cursor.end(); +                                let end = self.state.cursor.end(&self.value); +                                  self.state.cursor.select_range(                                      self.value.previous_start_of_word(end),                                      self.value.next_end_of_word(end), @@ -307,7 +309,7 @@ where                              self.font,                          ); -                        let pos = find_cursor_position( +                        let position = find_cursor_position(                              renderer,                              target + offset,                              &value, @@ -317,9 +319,10 @@ where                              self.font,                          ); -                        self.state -                            .cursor -                            .select_range(self.state.cursor.start(), pos); +                        self.state.cursor.select_range( +                            self.state.cursor.start(&value), +                            position, +                        );                      }                  }              } @@ -328,15 +331,15 @@ where                      && self.state.is_pasting.is_none()                      && !c.is_control() =>              { -                match self.state.cursor.selection_position() { +                match self.state.cursor.selection() {                      Some((left, right)) => {                          self.value.remove_many(left, right); -                        self.state.cursor.move_left(); +                        self.state.cursor.move_left(&self.value);                      }                      _ => (),                  } -                self.value -                    .insert(self.state.cursor.end().min(self.value.len()), c); + +                self.value.insert(self.state.cursor.end(&self.value), c);                  self.state.cursor.move_right(&self.value);                  let message = (self.on_change)(self.value.to_string()); @@ -353,19 +356,18 @@ where                      }                  }                  keyboard::KeyCode::Backspace => { -                    match self.state.cursor.selection_position() { +                    match self.state.cursor.selection() {                          Some((start, end)) => {                              self.value.remove_many(start, end); -                            self.state.cursor.move_left(); +                            self.state.cursor.move_left(&self.value);                          }                          None => { -                            if self.state.cursor.start().min(self.value.len()) -                                > 0 -                            { -                                self.state.cursor.move_left(); -                                let _ = self -                                    .value -                                    .remove(self.state.cursor.start()); +                            if self.state.cursor.start(&self.value) > 0 { +                                self.state.cursor.move_left(&self.value); + +                                let _ = self.value.remove( +                                    self.state.cursor.start(&self.value), +                                );                              }                          }                      } @@ -373,15 +375,16 @@ where                      messages.push(message);                  }                  keyboard::KeyCode::Delete => { -                    match self.state.cursor.selection_position() { +                    match self.state.cursor.selection() {                          Some((start, end)) => {                              self.value.remove_many(start, end); -                            self.state.cursor.move_left(); +                            self.state.cursor.move_left(&self.value);                          }                          None => { -                            if self.state.cursor.end() < self.value.len() { -                                let _ = -                                    self.value.remove(self.state.cursor.end()); +                            let end = self.state.cursor.end(&self.value); + +                            if end > 0 { +                                let _ = self.value.remove(end);                              }                          }                      } @@ -398,9 +401,9 @@ where                              self.state.cursor.move_left_by_words(&self.value);                          }                      } else if modifiers.shift { -                        self.state.cursor.select_left() +                        self.state.cursor.select_left(&self.value)                      } else { -                        self.state.cursor.move_left(); +                        self.state.cursor.move_left(&self.value);                      }                  }                  keyboard::KeyCode::Right => { @@ -422,9 +425,10 @@ where                  }                  keyboard::KeyCode::Home => {                      if modifiers.shift { -                        self.state -                            .cursor -                            .select_range(self.state.cursor.start(), 0); +                        self.state.cursor.select_range( +                            self.state.cursor.start(&self.value), +                            0, +                        );                      } else {                          self.state.cursor.move_to(0);                      } @@ -432,7 +436,7 @@ where                  keyboard::KeyCode::End => {                      if modifiers.shift {                          self.state.cursor.select_range( -                            self.state.cursor.start(), +                            self.state.cursor.start(&self.value),                              self.value.len(),                          );                      } else { @@ -456,16 +460,16 @@ where                                  }                              }; -                            match self.state.cursor.selection_position() { +                            match self.state.cursor.selection() {                                  Some((left, right)) => {                                      self.value.remove_many(left, right); -                                    self.state.cursor.move_left(); +                                    self.state.cursor.move_left(&self.value);                                  }                                  _ => (),                              }                              self.value.insert_many( -                                self.state.cursor.end().min(self.value.len()), +                                self.state.cursor.end(&self.value),                                  content.clone(),                              ); diff --git a/native/src/widget/text_input/cursor.rs b/native/src/widget/text_input/cursor.rs index 92fd2029..d8938777 100644 --- a/native/src/widget/text_input/cursor.rs +++ b/native/src/widget/text_input/cursor.rs @@ -1,7 +1,8 @@ +//! Track the cursor of a text input.  use crate::widget::text_input::Value;  #[derive(Debug, Copy, Clone)] -enum State { +pub enum State {      Index(usize),      Selection { start: usize, end: usize },  } @@ -20,7 +21,6 @@ impl Default for Cursor {  }  impl Cursor { -    /* index move methods */      pub fn move_to(&mut self, position: usize) {          self.state = State::Index(position);      } @@ -30,42 +30,40 @@ impl Cursor {      }      pub fn move_right_by_words(&mut self, value: &Value) { -        self.move_to(value.next_end_of_word(self.right())) +        self.move_to(value.next_end_of_word(self.right(value)))      }      pub fn move_right_by_amount(&mut self, value: &Value, amount: usize) { -        match self.state { +        match self.state(value) {              State::Index(index) => {                  self.move_to(index.saturating_add(amount).min(value.len()))              } -            State::Selection { .. } => self.move_to(self.right()), +            State::Selection { start, end } => self.move_to(end.max(start)),          }      } -    pub fn move_left(&mut self) { -        match self.state { +    pub fn move_left(&mut self, value: &Value) { +        match self.state(value) {              State::Index(index) if index > 0 => self.move_to(index - 1), -            State::Selection { .. } => self.move_to(self.left()), +            State::Selection { start, end } => self.move_to(start.min(end)),              _ => self.move_to(0),          }      }      pub fn move_left_by_words(&mut self, value: &Value) { -        self.move_to(value.previous_start_of_word(self.right())); +        self.move_to(value.previous_start_of_word(self.left(value)));      } -    /* end of index move methods */ -    /* expand/shrink selection */      pub fn select_range(&mut self, start: usize, end: usize) { -        if start != end { -            self.state = State::Selection { start, end }; -        } else { +        if start == end {              self.state = State::Index(start); +        } else { +            self.state = State::Selection { start, end };          }      } -    pub fn select_left(&mut self) { -        match self.state { +    pub fn select_left(&mut self, value: &Value) { +        match self.state(value) {              State::Index(index) if index > 0 => {                  self.select_range(index, index - 1)              } @@ -77,7 +75,7 @@ impl Cursor {      }      pub fn select_right(&mut self, value: &Value) { -        match self.state { +        match self.state(value) {              State::Index(index) if index < value.len() => {                  self.select_range(index, index + 1)              } @@ -89,7 +87,7 @@ impl Cursor {      }      pub fn select_left_by_words(&mut self, value: &Value) { -        match self.state { +        match self.state(value) {              State::Index(index) => {                  self.select_range(index, value.previous_start_of_word(index))              } @@ -100,7 +98,7 @@ impl Cursor {      }      pub fn select_right_by_words(&mut self, value: &Value) { -        match self.state { +        match self.state(value) {              State::Index(index) => {                  self.select_range(index, value.next_end_of_word(index))              } @@ -113,51 +111,56 @@ impl Cursor {      pub fn select_all(&mut self, value: &Value) {          self.select_range(0, value.len());      } -    /* end of selection section */ -    /* helpers */ -    // get start position of selection (can be left OR right boundary of selection) or index -    pub(crate) fn start(&self) -> usize { +    pub fn state(&self, value: &Value) -> State {          match self.state { +            State::Index(index) => State::Index(index.min(value.len())), +            State::Selection { start, end } => { +                let start = start.min(value.len()); +                let end = end.min(value.len()); + +                if start == end { +                    State::Index(start) +                } else { +                    State::Selection { start, end } +                } +            } +        } +    } + +    pub fn start(&self, value: &Value) -> usize { +        let start = match self.state {              State::Index(index) => index,              State::Selection { start, .. } => start, -        } +        }; + +        start.min(value.len())      } -    // get end position of selection (can be left OR right boundary of selection) or index -    pub fn end(&self) -> usize { -        match self.state { +    pub fn end(&self, value: &Value) -> usize { +        let end = match self.state {              State::Index(index) => index,              State::Selection { end, .. } => end, -        } +        }; + +        end.min(value.len())      } -    // get left boundary of selection or index -    pub fn left(&self) -> usize { -        match self.state { +    fn left(&self, value: &Value) -> usize { +        match self.state(value) {              State::Index(index) => index,              State::Selection { start, end } => start.min(end),          }      } -    // get right boundary of selection or index -    pub fn right(&self) -> usize { -        match self.state { +    fn right(&self, value: &Value) -> usize { +        match self.state(value) {              State::Index(index) => index,              State::Selection { start, end } => start.max(end),          }      } -    pub fn cursor_position(&self, value: &Value) -> usize { -        match self.state { -            State::Index(index) => index.min(value.len()), -            State::Selection { end, .. } => end.min(value.len()), -        } -    } - -    // returns Option of left and right border of selection -    // a second method that returns start and end may be useful (see below) -    pub fn selection_position(&self) -> Option<(usize, usize)> { +    pub fn selection(&self) -> Option<(usize, usize)> {          match self.state {              State::Selection { start, end } => {                  Some((start.min(end), start.max(end))) @@ -165,11 +168,4 @@ impl Cursor {              _ => None,          }      } - -    /* pub fn selection_position(&self) -> Option<(usize, usize)> { -        match self.state { -            State::Selection { start, end } => Some((start, end)), -            _ => None, -        } -    } */  }  | 
