Implement cursor movement in TextInput
This commit is contained in:
parent
374b54c3ec
commit
51a0e99097
4 changed files with 176 additions and 50 deletions
|
|
@ -1,9 +1,11 @@
|
|||
use crate::Length;
|
||||
|
||||
use std::ops::{Index, RangeTo};
|
||||
|
||||
pub struct TextInput<'a, Message> {
|
||||
pub state: &'a mut State,
|
||||
pub placeholder: String,
|
||||
pub value: String,
|
||||
pub value: Value,
|
||||
pub width: Length,
|
||||
pub max_width: Length,
|
||||
pub padding: u16,
|
||||
|
|
@ -12,11 +14,6 @@ pub struct TextInput<'a, Message> {
|
|||
pub on_submit: Option<Message>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct State {
|
||||
pub is_focused: bool,
|
||||
}
|
||||
|
||||
impl<'a, Message> TextInput<'a, Message> {
|
||||
pub fn new<F>(
|
||||
state: &'a mut State,
|
||||
|
|
@ -30,7 +27,7 @@ impl<'a, Message> TextInput<'a, Message> {
|
|||
Self {
|
||||
state,
|
||||
placeholder: String::from(placeholder),
|
||||
value: String::from(value),
|
||||
value: Value::new(value),
|
||||
width: Length::Fill,
|
||||
max_width: Length::Shrink,
|
||||
padding: 0,
|
||||
|
|
@ -84,3 +81,84 @@ where
|
|||
f.debug_struct("TextInput").finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct State {
|
||||
pub is_focused: bool,
|
||||
cursor_position: usize,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn focused() -> Self {
|
||||
Self {
|
||||
is_focused: true,
|
||||
..Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_cursor_right(&mut self, value: &Value) {
|
||||
let current = self.cursor_position(value);
|
||||
|
||||
if current < value.len() {
|
||||
self.cursor_position = current + 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_cursor_left(&mut self, value: &Value) {
|
||||
let current = self.cursor_position(value);
|
||||
|
||||
if current > 0 {
|
||||
self.cursor_position = current - 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cursor_position(&self, value: &Value) -> usize {
|
||||
self.cursor_position.min(value.len())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Value(Vec<char>);
|
||||
|
||||
impl Value {
|
||||
pub fn new(string: &str) -> Self {
|
||||
Self(string.chars().collect())
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
pub fn until(&self, index: usize) -> Self {
|
||||
Self(self.0[..index].iter().cloned().collect())
|
||||
}
|
||||
|
||||
pub fn to_string(&self) -> String {
|
||||
let mut string = String::new();
|
||||
|
||||
for c in self.0.iter() {
|
||||
string.push(*c);
|
||||
}
|
||||
|
||||
string
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, index: usize, c: char) {
|
||||
self.0.insert(index, c);
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, index: usize) {
|
||||
self.0.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<RangeTo<usize>> for Value {
|
||||
type Output = [char];
|
||||
|
||||
fn index(&self, index: RangeTo<usize>) -> &[char] {
|
||||
&self.0[index]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue