1use crate::{
2 App, Bounds, ClipboardItem, Context, Entity, InputHandler, Pixels, UTF16Selection, Window,
3};
4use std::ops::Range;
5
6pub trait EntityInputHandler: 'static + Sized {
13 fn text_for_range(
15 &mut self,
16 range: Range<usize>,
17 adjusted_range: &mut Option<Range<usize>>,
18 window: &mut Window,
19 cx: &mut Context<Self>,
20 ) -> Option<String>;
21
22 fn selected_text_range(
24 &mut self,
25 ignore_disabled_input: bool,
26 window: &mut Window,
27 cx: &mut Context<Self>,
28 ) -> Option<UTF16Selection>;
29
30 fn marked_text_range(
32 &self,
33 window: &mut Window,
34 cx: &mut Context<Self>,
35 ) -> Option<Range<usize>>;
36
37 fn unmark_text(&mut self, window: &mut Window, cx: &mut Context<Self>);
39
40 fn paste(&mut self, item: ClipboardItem, window: &mut Window, cx: &mut Context<Self>) {
42 if let Some(text) = item.text() {
43 self.replace_text_in_range(None, &text, window, cx);
44 }
45 }
46
47 fn replace_text_in_range(
49 &mut self,
50 range: Option<Range<usize>>,
51 text: &str,
52 window: &mut Window,
53 cx: &mut Context<Self>,
54 );
55
56 fn replace_and_mark_text_in_range(
58 &mut self,
59 range: Option<Range<usize>>,
60 new_text: &str,
61 new_selected_range: Option<Range<usize>>,
62 window: &mut Window,
63 cx: &mut Context<Self>,
64 );
65
66 fn bounds_for_range(
68 &mut self,
69 range_utf16: Range<usize>,
70 element_bounds: Bounds<Pixels>,
71 window: &mut Window,
72 cx: &mut Context<Self>,
73 ) -> Option<Bounds<Pixels>>;
74
75 fn character_index_for_point(
77 &mut self,
78 point: crate::Point<Pixels>,
79 window: &mut Window,
80 cx: &mut Context<Self>,
81 ) -> Option<usize>;
82
83 fn set_selected_text_range(
85 &mut self,
86 _range_utf16: Range<usize>,
87 _window: &mut Window,
88 _cx: &mut Context<Self>,
89 ) {
90 }
91
92 fn text_length_utf16(
94 &mut self,
95 _window: &mut Window,
96 _cx: &mut Context<Self>,
97 ) -> Option<usize> {
98 None
99 }
100
101 fn accepts_text_input(&self, _window: &mut Window, _cx: &mut Context<Self>) -> bool {
103 true
104 }
105}
106
107pub struct ElementInputHandler<V> {
110 view: Entity<V>,
111 element_bounds: Bounds<Pixels>,
112}
113
114impl<V: 'static> ElementInputHandler<V> {
115 pub fn new(element_bounds: Bounds<Pixels>, view: Entity<V>) -> Self {
119 ElementInputHandler {
120 view,
121 element_bounds,
122 }
123 }
124}
125
126impl<V: EntityInputHandler> InputHandler for ElementInputHandler<V> {
127 fn selected_text_range(
128 &mut self,
129 ignore_disabled_input: bool,
130 window: &mut Window,
131 cx: &mut App,
132 ) -> Option<UTF16Selection> {
133 self.view.update(cx, |view, cx| {
134 view.selected_text_range(ignore_disabled_input, window, cx)
135 })
136 }
137
138 fn marked_text_range(&mut self, window: &mut Window, cx: &mut App) -> Option<Range<usize>> {
139 self.view
140 .update(cx, |view, cx| view.marked_text_range(window, cx))
141 }
142
143 fn text_for_range(
144 &mut self,
145 range_utf16: Range<usize>,
146 adjusted_range: &mut Option<Range<usize>>,
147 window: &mut Window,
148 cx: &mut App,
149 ) -> Option<String> {
150 self.view.update(cx, |view, cx| {
151 view.text_for_range(range_utf16, adjusted_range, window, cx)
152 })
153 }
154
155 fn replace_text_in_range(
156 &mut self,
157 replacement_range: Option<Range<usize>>,
158 text: &str,
159 window: &mut Window,
160 cx: &mut App,
161 ) {
162 self.view.update(cx, |view, cx| {
163 view.replace_text_in_range(replacement_range, text, window, cx)
164 });
165 }
166
167 fn replace_and_mark_text_in_range(
168 &mut self,
169 range_utf16: Option<Range<usize>>,
170 new_text: &str,
171 new_selected_range: Option<Range<usize>>,
172 window: &mut Window,
173 cx: &mut App,
174 ) {
175 self.view.update(cx, |view, cx| {
176 view.replace_and_mark_text_in_range(
177 range_utf16,
178 new_text,
179 new_selected_range,
180 window,
181 cx,
182 )
183 });
184 }
185
186 fn unmark_text(&mut self, window: &mut Window, cx: &mut App) {
187 self.view
188 .update(cx, |view, cx| view.unmark_text(window, cx));
189 }
190
191 fn paste(&mut self, item: ClipboardItem, window: &mut Window, cx: &mut App) {
192 self.view
193 .update(cx, |view, cx| view.paste(item, window, cx));
194 }
195
196 fn bounds_for_range(
197 &mut self,
198 range_utf16: Range<usize>,
199 window: &mut Window,
200 cx: &mut App,
201 ) -> Option<Bounds<Pixels>> {
202 self.view.update(cx, |view, cx| {
203 view.bounds_for_range(range_utf16, self.element_bounds, window, cx)
204 })
205 }
206
207 fn character_index_for_point(
208 &mut self,
209 point: crate::Point<Pixels>,
210 window: &mut Window,
211 cx: &mut App,
212 ) -> Option<usize> {
213 self.view.update(cx, |view, cx| {
214 view.character_index_for_point(point, window, cx)
215 })
216 }
217
218 fn set_selected_text_range(
219 &mut self,
220 range_utf16: Range<usize>,
221 window: &mut Window,
222 cx: &mut App,
223 ) {
224 self.view.update(cx, |view, cx| {
225 view.set_selected_text_range(range_utf16, window, cx)
226 })
227 }
228
229 fn element_bounds(&mut self, _window: &mut Window, _cx: &mut App) -> Option<Bounds<Pixels>> {
230 Some(self.element_bounds)
231 }
232
233 fn text_length_utf16(&mut self, window: &mut Window, cx: &mut App) -> Option<usize> {
234 self.view
235 .update(cx, |view, cx| view.text_length_utf16(window, cx))
236 }
237
238 fn accepts_text_input(&mut self, window: &mut Window, cx: &mut App) -> bool {
239 self.view
240 .update(cx, |view, cx| view.accepts_text_input(window, cx))
241 }
242
243 fn prefers_ime_for_printable_keys(&mut self, window: &mut Window, cx: &mut App) -> bool {
244 self.view
245 .update(cx, |view, cx| view.accepts_text_input(window, cx))
246 }
247}