summaryrefslogtreecommitdiffstats
path: root/native/src/widget/text_input
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-03-24 20:23:31 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-03-24 20:23:31 +0100
commit6b89dd7db9715dd46738677e13ca9d9bd12f9636 (patch)
treea37fbdece73f8b4ab348cc8ac9e1eb1fc0040d6e /native/src/widget/text_input
parent763f64b653e69b46715dcd8f7918ed769639098c (diff)
downloadiced-6b89dd7db9715dd46738677e13ca9d9bd12f9636.tar.gz
iced-6b89dd7db9715dd46738677e13ca9d9bd12f9636.tar.bz2
iced-6b89dd7db9715dd46738677e13ca9d9bd12f9636.zip
Improve `text_input::cursor` API
Diffstat (limited to 'native/src/widget/text_input')
-rw-r--r--native/src/widget/text_input/cursor.rs98
1 files changed, 47 insertions, 51 deletions
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,
- }
- } */
}