Write documentation for text_input::Cursor
This commit is contained in:
parent
735d9f049c
commit
857d65c1ce
2 changed files with 129 additions and 109 deletions
|
|
@ -34,7 +34,7 @@
|
||||||
//! [`window::Renderer`]: window/trait.Renderer.html
|
//! [`window::Renderer`]: window/trait.Renderer.html
|
||||||
//! [`UserInterface`]: struct.UserInterface.html
|
//! [`UserInterface`]: struct.UserInterface.html
|
||||||
//! [renderer]: renderer/index.html
|
//! [renderer]: renderer/index.html
|
||||||
//#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![deny(missing_debug_implementations)]
|
#![deny(missing_debug_implementations)]
|
||||||
#![deny(unused_results)]
|
#![deny(unused_results)]
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,29 @@
|
||||||
//! Track the cursor of a text input.
|
//! Track the cursor of a text input.
|
||||||
use crate::widget::text_input::Value;
|
use crate::widget::text_input::Value;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
/// The cursor of a text input.
|
||||||
pub enum State {
|
|
||||||
Index(usize),
|
|
||||||
Selection { start: usize, end: usize },
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct Cursor {
|
pub struct Cursor {
|
||||||
state: State,
|
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 {
|
impl Default for Cursor {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Cursor {
|
Cursor {
|
||||||
|
|
@ -21,97 +33,10 @@ impl Default for Cursor {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cursor {
|
impl Cursor {
|
||||||
pub fn move_to(&mut self, position: usize) {
|
/// Returns the [`State`] of the [`Cursor`].
|
||||||
self.state = State::Index(position);
|
///
|
||||||
}
|
/// [`State`]: struct.State.html
|
||||||
|
/// [`Cursor`]: struct.Cursor.html
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn state(&self, value: &Value) -> State {
|
pub fn state(&self, value: &Value) -> State {
|
||||||
match self.state {
|
match self.state {
|
||||||
State::Index(index) => State::Index(index.min(value.len())),
|
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 {
|
let start = match self.state {
|
||||||
State::Index(index) => index,
|
State::Index(index) => index,
|
||||||
State::Selection { start, .. } => start,
|
State::Selection { start, .. } => start,
|
||||||
|
|
@ -137,7 +157,7 @@ impl Cursor {
|
||||||
start.min(value.len())
|
start.min(value.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn end(&self, value: &Value) -> usize {
|
pub(crate) fn end(&self, value: &Value) -> usize {
|
||||||
let end = match self.state {
|
let end = match self.state {
|
||||||
State::Index(index) => index,
|
State::Index(index) => index,
|
||||||
State::Selection { end, .. } => end,
|
State::Selection { end, .. } => end,
|
||||||
|
|
@ -146,6 +166,15 @@ impl Cursor {
|
||||||
end.min(value.len())
|
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 {
|
fn left(&self, value: &Value) -> usize {
|
||||||
match self.state(value) {
|
match self.state(value) {
|
||||||
State::Index(index) => index,
|
State::Index(index) => index,
|
||||||
|
|
@ -159,13 +188,4 @@ impl Cursor {
|
||||||
State::Selection { start, end } => start.max(end),
|
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue