Skip to main content

iced_core/widget/operation/
text_input.rs

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