diff --git a/native/src/lib.rs b/native/src/lib.rs index 5c6ab3ee..d17dd918 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/cursor.rs b/native/src/widget/text_input/cursor.rs index d8938777..16e7a01b 100644 --- a/native/src/widget/text_input/cursor.rs +++ b/native/src/widget/text_input/cursor.rs @@ -1,17 +1,29 @@ //! Track the cursor of a text input. use crate::widget::text_input::Value; -#[derive(Debug, Copy, Clone)] -pub enum State { - Index(usize), - Selection { start: usize, end: usize }, -} - +/// The cursor of a text input. #[derive(Debug, Copy, Clone)] pub struct Cursor { state: State, } +/// The state of a [`Cursor`]. +/// +/// [`Cursor`]: struct.Cursor.html +#[derive(Debug, Copy, Clone)] +pub enum State { + /// Cursor without a selection + Index(usize), + + /// Cursor selecting a range of text + Selection { + /// The start of the selection + start: usize, + /// The end of the selection + end: usize, + }, +} + impl Default for Cursor { fn default() -> Self { Cursor { @@ -21,97 +33,10 @@ impl Default for Cursor { } impl Cursor { - pub fn move_to(&mut self, position: usize) { - self.state = State::Index(position); - } - - pub fn move_right(&mut self, value: &Value) { - self.move_right_by_amount(value, 1) - } - - pub fn move_right_by_words(&mut self, value: &Value) { - 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(value) { - State::Index(index) => { - self.move_to(index.saturating_add(amount).min(value.len())) - } - State::Selection { start, end } => self.move_to(end.max(start)), - } - } - - 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 { 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.left(value))); - } - - pub fn select_range(&mut self, start: usize, end: usize) { - if start == end { - self.state = State::Index(start); - } else { - self.state = State::Selection { start, end }; - } - } - - pub fn select_left(&mut self, value: &Value) { - match self.state(value) { - State::Index(index) if index > 0 => { - self.select_range(index, index - 1) - } - State::Selection { start, end } if end > 0 => { - self.select_range(start, end - 1) - } - _ => (), - } - } - - pub fn select_right(&mut self, value: &Value) { - match self.state(value) { - State::Index(index) if index < value.len() => { - self.select_range(index, index + 1) - } - State::Selection { start, end } if end < value.len() => { - self.select_range(start, end + 1) - } - _ => (), - } - } - - pub fn select_left_by_words(&mut self, value: &Value) { - match self.state(value) { - State::Index(index) => { - self.select_range(index, value.previous_start_of_word(index)) - } - State::Selection { start, end } => { - self.select_range(start, value.previous_start_of_word(end)) - } - } - } - - pub fn select_right_by_words(&mut self, value: &Value) { - match self.state(value) { - State::Index(index) => { - self.select_range(index, value.next_end_of_word(index)) - } - State::Selection { start, end } => { - self.select_range(start, value.next_end_of_word(end)) - } - } - } - - pub fn select_all(&mut self, value: &Value) { - self.select_range(0, value.len()); - } - + /// Returns the [`State`] of the [`Cursor`]. + /// + /// [`State`]: struct.State.html + /// [`Cursor`]: struct.Cursor.html pub fn state(&self, value: &Value) -> State { match self.state { State::Index(index) => State::Index(index.min(value.len())), @@ -128,7 +53,102 @@ impl Cursor { } } - pub fn start(&self, value: &Value) -> usize { + pub(crate) fn move_to(&mut self, position: usize) { + self.state = State::Index(position); + } + + pub(crate) fn move_right(&mut self, value: &Value) { + self.move_right_by_amount(value, 1) + } + + pub(crate) fn move_right_by_words(&mut self, value: &Value) { + self.move_to(value.next_end_of_word(self.right(value))) + } + + pub(crate) fn move_right_by_amount( + &mut self, + value: &Value, + amount: usize, + ) { + match self.state(value) { + State::Index(index) => { + self.move_to(index.saturating_add(amount).min(value.len())) + } + State::Selection { start, end } => self.move_to(end.max(start)), + } + } + + pub(crate) fn move_left(&mut self, value: &Value) { + match self.state(value) { + State::Index(index) if index > 0 => self.move_to(index - 1), + State::Selection { start, end } => self.move_to(start.min(end)), + _ => self.move_to(0), + } + } + + pub(crate) fn move_left_by_words(&mut self, value: &Value) { + self.move_to(value.previous_start_of_word(self.left(value))); + } + + pub(crate) fn select_range(&mut self, start: usize, end: usize) { + if start == end { + self.state = State::Index(start); + } else { + self.state = State::Selection { start, end }; + } + } + + pub(crate) fn select_left(&mut self, value: &Value) { + match self.state(value) { + State::Index(index) if index > 0 => { + self.select_range(index, index - 1) + } + State::Selection { start, end } if end > 0 => { + self.select_range(start, end - 1) + } + _ => (), + } + } + + pub(crate) fn select_right(&mut self, value: &Value) { + match self.state(value) { + State::Index(index) if index < value.len() => { + self.select_range(index, index + 1) + } + State::Selection { start, end } if end < value.len() => { + self.select_range(start, end + 1) + } + _ => (), + } + } + + pub(crate) fn select_left_by_words(&mut self, value: &Value) { + match self.state(value) { + State::Index(index) => { + self.select_range(index, value.previous_start_of_word(index)) + } + State::Selection { start, end } => { + self.select_range(start, value.previous_start_of_word(end)) + } + } + } + + pub(crate) fn select_right_by_words(&mut self, value: &Value) { + match self.state(value) { + State::Index(index) => { + self.select_range(index, value.next_end_of_word(index)) + } + State::Selection { start, end } => { + self.select_range(start, value.next_end_of_word(end)) + } + } + } + + pub(crate) fn select_all(&mut self, value: &Value) { + self.select_range(0, value.len()); + } + + pub(crate) fn start(&self, value: &Value) -> usize { let start = match self.state { State::Index(index) => index, State::Selection { start, .. } => start, @@ -137,7 +157,7 @@ impl Cursor { start.min(value.len()) } - pub fn end(&self, value: &Value) -> usize { + pub(crate) fn end(&self, value: &Value) -> usize { let end = match self.state { State::Index(index) => index, State::Selection { end, .. } => end, @@ -146,6 +166,15 @@ impl Cursor { end.min(value.len()) } + pub(crate) fn selection(&self) -> Option<(usize, usize)> { + match self.state { + State::Selection { start, end } => { + Some((start.min(end), start.max(end))) + } + _ => None, + } + } + fn left(&self, value: &Value) -> usize { match self.state(value) { State::Index(index) => index, @@ -159,13 +188,4 @@ impl Cursor { State::Selection { start, end } => start.max(end), } } - - pub fn selection(&self) -> Option<(usize, usize)> { - match self.state { - State::Selection { start, end } => { - Some((start.min(end), start.max(end))) - } - _ => None, - } - } }