iced/core/src/widget/text_input.rs
2019-11-13 07:38:06 +01:00

154 lines
3.5 KiB
Rust

use crate::Length;
pub struct TextInput<'a, Message> {
pub state: &'a mut State,
pub placeholder: String,
pub value: Value,
pub width: Length,
pub max_width: Length,
pub padding: u16,
pub size: Option<u16>,
pub on_change: Box<dyn Fn(String) -> Message>,
pub on_submit: Option<Message>,
}
impl<'a, Message> TextInput<'a, Message> {
pub fn new<F>(
state: &'a mut State,
placeholder: &str,
value: &str,
on_change: F,
) -> Self
where
F: 'static + Fn(String) -> Message,
{
Self {
state,
placeholder: String::from(placeholder),
value: Value::new(value),
width: Length::Fill,
max_width: Length::Shrink,
padding: 0,
size: None,
on_change: Box::new(on_change),
on_submit: None,
}
}
/// Sets the width of the [`TextInput`].
///
/// [`TextInput`]: struct.TextInput.html
pub fn width(mut self, width: Length) -> Self {
self.width = width;
self
}
/// Sets the maximum width of the [`TextInput`].
///
/// [`TextInput`]: struct.TextInput.html
pub fn max_width(mut self, max_width: Length) -> Self {
self.max_width = max_width;
self
}
/// Sets the padding of the [`TextInput`].
///
/// [`TextInput`]: struct.TextInput.html
pub fn padding(mut self, units: u16) -> Self {
self.padding = units;
self
}
pub fn size(mut self, size: u16) -> Self {
self.size = Some(size);
self
}
pub fn on_submit(mut self, message: Message) -> Self {
self.on_submit = Some(message);
self
}
}
impl<'a, Message> std::fmt::Debug for TextInput<'a, Message>
where
Message: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// TODO: Complete once stabilized
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(value: &str) -> Self {
Self {
is_focused: true,
cursor_position: Value::new(value).len(),
}
}
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 move_cursor_to_end(&mut self, value: &Value) {
self.cursor_position = value.len();
}
pub fn cursor_position(&self, value: &Value) -> usize {
self.cursor_position.min(value.len())
}
}
// TODO: Use `unicode-segmentation`
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.min(self.len())].to_vec())
}
pub fn to_string(&self) -> String {
use std::iter::FromIterator;
String::from_iter(self.0.iter())
}
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);
}
}