iced_core/widget/operation/
text_input.rs

1//! Operate on widgets that have text input.
2use crate::Rectangle;
3use crate::widget::Id;
4use crate::widget::operation::Operation;
5
6/// The internal state of a widget that has text input.
7pub trait TextInput {
8    /// Returns the current _visible_ text of the text input
9    ///
10    /// Normally, this is either its value or its placeholder.
11    fn text(&self) -> &str;
12
13    /// Moves the cursor of the text input to the front of the input text.
14    fn move_cursor_to_front(&mut self);
15
16    /// Moves the cursor of the text input to the end of the input text.
17    fn move_cursor_to_end(&mut self);
18
19    /// Moves the cursor of the text input to an arbitrary location.
20    fn move_cursor_to(&mut self, position: usize);
21
22    /// Selects all the content of the text input.
23    fn select_all(&mut self);
24    /// Selects the given content range of the text input.
25    fn select_range(&mut self, start: usize, end: usize);
26}
27
28/// Produces an [`Operation`] that moves the cursor of the widget with the given [`Id`] to the
29/// front.
30pub fn move_cursor_to_front<T>(target: Id) -> impl Operation<T> {
31    struct MoveCursor {
32        target: Id,
33    }
34
35    impl<T> Operation<T> for MoveCursor {
36        fn text_input(&mut self, id: Option<&Id>, _bounds: Rectangle, state: &mut dyn TextInput) {
37            match id {
38                Some(id) if id == &self.target => {
39                    state.move_cursor_to_front();
40                }
41                _ => {}
42            }
43        }
44
45        fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
46            operate(self);
47        }
48    }
49
50    MoveCursor { target }
51}
52
53/// Produces an [`Operation`] that moves the cursor of the widget with the given [`Id`] to the
54/// end.
55pub fn move_cursor_to_end<T>(target: Id) -> impl Operation<T> {
56    struct MoveCursor {
57        target: Id,
58    }
59
60    impl<T> Operation<T> for MoveCursor {
61        fn text_input(&mut self, id: Option<&Id>, _bounds: Rectangle, state: &mut dyn TextInput) {
62            match id {
63                Some(id) if id == &self.target => {
64                    state.move_cursor_to_end();
65                }
66                _ => {}
67            }
68        }
69
70        fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
71            operate(self);
72        }
73    }
74
75    MoveCursor { target }
76}
77
78/// Produces an [`Operation`] that moves the cursor of the widget with the given [`Id`] to the
79/// provided position.
80pub fn move_cursor_to<T>(target: Id, position: usize) -> impl Operation<T> {
81    struct MoveCursor {
82        target: Id,
83        position: usize,
84    }
85
86    impl<T> Operation<T> for MoveCursor {
87        fn text_input(&mut self, id: Option<&Id>, _bounds: Rectangle, state: &mut dyn TextInput) {
88            match id {
89                Some(id) if id == &self.target => {
90                    state.move_cursor_to(self.position);
91                }
92                _ => {}
93            }
94        }
95
96        fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
97            operate(self);
98        }
99    }
100
101    MoveCursor { target, position }
102}
103
104/// Produces an [`Operation`] that selects all the content of the widget with the given [`Id`].
105pub fn select_all<T>(target: Id) -> impl Operation<T> {
106    struct MoveCursor {
107        target: Id,
108    }
109
110    impl<T> Operation<T> for MoveCursor {
111        fn text_input(&mut self, id: Option<&Id>, _bounds: Rectangle, state: &mut dyn TextInput) {
112            match id {
113                Some(id) if id == &self.target => {
114                    state.select_all();
115                }
116                _ => {}
117            }
118        }
119
120        fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
121            operate(self);
122        }
123    }
124
125    MoveCursor { target }
126}
127
128/// Produces an [`Operation`] that selects the given content range of the widget with the given [`Id`].
129pub fn select_range<T>(target: Id, start: usize, end: usize) -> impl Operation<T> {
130    struct SelectRange {
131        target: Id,
132        start: usize,
133        end: usize,
134    }
135
136    impl<T> Operation<T> for SelectRange {
137        fn text_input(&mut self, id: Option<&Id>, _bounds: Rectangle, state: &mut dyn TextInput) {
138            match id {
139                Some(id) if id == &self.target => {
140                    state.select_range(self.start, self.end);
141                }
142                _ => {}
143            }
144        }
145
146        fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
147            operate(self);
148        }
149    }
150
151    SelectRange { target, start, end }
152}