window_input_handler.rs

 1use crate::{AnyWindowHandle, AppCell, Context, PlatformInputHandler, ViewContext, WeakView};
 2use std::{ops::Range, rc::Weak};
 3
 4pub struct WindowInputHandler<V>
 5where
 6    V: InputHandler,
 7{
 8    pub cx: Weak<AppCell>,
 9    pub window: AnyWindowHandle,
10    pub handler: WeakView<V>,
11}
12
13impl<V: InputHandler + 'static> PlatformInputHandler for WindowInputHandler<V> {
14    fn selected_text_range(&self) -> Option<std::ops::Range<usize>> {
15        self.update(|view, cx| view.selected_text_range(cx))
16            .flatten()
17    }
18
19    fn marked_text_range(&self) -> Option<std::ops::Range<usize>> {
20        self.update(|view, cx| view.marked_text_range(cx)).flatten()
21    }
22
23    fn text_for_range(&self, range_utf16: std::ops::Range<usize>) -> Option<String> {
24        self.update(|view, cx| view.text_for_range(range_utf16, cx))
25            .flatten()
26    }
27
28    fn replace_text_in_range(
29        &mut self,
30        replacement_range: Option<std::ops::Range<usize>>,
31        text: &str,
32    ) {
33        self.update(|view, cx| view.replace_text_in_range(replacement_range, text, cx));
34    }
35
36    fn replace_and_mark_text_in_range(
37        &mut self,
38        range_utf16: Option<std::ops::Range<usize>>,
39        new_text: &str,
40        new_selected_range: Option<std::ops::Range<usize>>,
41    ) {
42        self.update(|view, cx| {
43            view.replace_and_mark_text_in_range(range_utf16, new_text, new_selected_range, cx)
44        });
45    }
46
47    fn unmark_text(&mut self) {
48        self.update(|view, cx| view.unmark_text(cx));
49    }
50
51    fn bounds_for_range(&self, range_utf16: std::ops::Range<usize>) -> Option<crate::Bounds<f32>> {
52        self.update(|view, cx| view.bounds_for_range(range_utf16, cx))
53            .flatten()
54    }
55}
56
57impl<V: InputHandler + 'static> WindowInputHandler<V> {
58    fn update<T>(&self, f: impl FnOnce(&mut V, &mut ViewContext<V>) -> T) -> Option<T> {
59        let cx = self.cx.upgrade()?;
60        let mut cx = cx.borrow_mut();
61        cx.update_window(self.window, |_, cx| self.handler.update(cx, f).ok())
62            .ok()?
63    }
64}
65
66pub trait InputHandler: Sized {
67    fn text_for_range(&self, range: Range<usize>, cx: &mut ViewContext<Self>) -> Option<String>;
68    fn selected_text_range(&self, cx: &mut ViewContext<Self>) -> Option<Range<usize>>;
69    fn marked_text_range(&self, cx: &mut ViewContext<Self>) -> Option<Range<usize>>;
70    fn unmark_text(&mut self, cx: &mut ViewContext<Self>);
71    fn replace_text_in_range(
72        &mut self,
73        range: Option<Range<usize>>,
74        text: &str,
75        cx: &mut ViewContext<Self>,
76    );
77    fn replace_and_mark_text_in_range(
78        &mut self,
79        range: Option<Range<usize>>,
80        new_text: &str,
81        new_selected_range: Option<Range<usize>>,
82        cx: &mut ViewContext<Self>,
83    );
84    fn bounds_for_range(
85        &self,
86        range_utf16: std::ops::Range<usize>,
87        cx: &mut ViewContext<Self>,
88    ) -> Option<crate::Bounds<f32>>;
89}