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(
37            &mut self,
38            id: Option<&Id>,
39            _bounds: Rectangle,
40            state: &mut dyn TextInput,
41        ) {
42            match id {
43                Some(id) if id == &self.target => {
44                    state.move_cursor_to_front();
45                }
46                _ => {}
47            }
48        }
49
50        fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
51            operate(self);
52        }
53    }
54
55    MoveCursor { target }
56}
57
58/// Produces an [`Operation`] that moves the cursor of the widget with the given [`Id`] to the
59/// end.
60pub fn move_cursor_to_end<T>(target: Id) -> impl Operation<T> {
61    struct MoveCursor {
62        target: Id,
63    }
64
65    impl<T> Operation<T> for MoveCursor {
66        fn text_input(
67            &mut self,
68            id: Option<&Id>,
69            _bounds: Rectangle,
70            state: &mut dyn TextInput,
71        ) {
72            match id {
73                Some(id) if id == &self.target => {
74                    state.move_cursor_to_end();
75                }
76                _ => {}
77            }
78        }
79
80        fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
81            operate(self);
82        }
83    }
84
85    MoveCursor { target }
86}
87
88/// Produces an [`Operation`] that moves the cursor of the widget with the given [`Id`] to the
89/// provided position.
90pub fn move_cursor_to<T>(target: Id, position: usize) -> impl Operation<T> {
91    struct MoveCursor {
92        target: Id,
93        position: usize,
94    }
95
96    impl<T> Operation<T> for MoveCursor {
97        fn text_input(
98            &mut self,
99            id: Option<&Id>,
100            _bounds: Rectangle,
101            state: &mut dyn TextInput,
102        ) {
103            match id {
104                Some(id) if id == &self.target => {
105                    state.move_cursor_to(self.position);
106                }
107                _ => {}
108            }
109        }
110
111        fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
112            operate(self);
113        }
114    }
115
116    MoveCursor { target, position }
117}
118
119/// Produces an [`Operation`] that selects all the content of the widget with the given [`Id`].
120pub fn select_all<T>(target: Id) -> impl Operation<T> {
121    struct MoveCursor {
122        target: Id,
123    }
124
125    impl<T> Operation<T> for MoveCursor {
126        fn text_input(
127            &mut self,
128            id: Option<&Id>,
129            _bounds: Rectangle,
130            state: &mut dyn TextInput,
131        ) {
132            match id {
133                Some(id) if id == &self.target => {
134                    state.select_all();
135                }
136                _ => {}
137            }
138        }
139
140        fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
141            operate(self);
142        }
143    }
144
145    MoveCursor { target }
146}
147
148/// Produces an [`Operation`] that selects the given content range of the widget with the given [`Id`].
149pub fn select_range<T>(
150    target: Id,
151    start: usize,
152    end: usize,
153) -> impl Operation<T> {
154    struct SelectRange {
155        target: Id,
156        start: usize,
157        end: usize,
158    }
159
160    impl<T> Operation<T> for SelectRange {
161        fn text_input(
162            &mut self,
163            id: Option<&Id>,
164            _bounds: Rectangle,
165            state: &mut dyn TextInput,
166        ) {
167            match id {
168                Some(id) if id == &self.target => {
169                    state.select_range(self.start, self.end);
170                }
171                _ => {}
172            }
173        }
174
175        fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
176            operate(self);
177        }
178    }
179
180    SelectRange { target, start, end }
181}