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 'native')
-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, - } - } */ } |