gtk4/subclass/
text_view.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// rustdoc-stripper-ignore-next
4//! Traits intended for subclassing [`TextView`].
5
6use glib::translate::*;
7
8use crate::{
9    ffi, prelude::*, subclass::prelude::*, DeleteType, MovementStep, Scrollable, Snapshot,
10    TextExtendSelection, TextIter, TextView, TextViewLayer,
11};
12
13pub trait TextViewImpl: WidgetImpl + ObjectSubclass<Type: IsA<TextView> + IsA<Scrollable>> {
14    fn backspace(&self) {
15        self.parent_backspace()
16    }
17
18    fn copy_clipboard(&self) {
19        self.parent_copy_clipboard()
20    }
21
22    fn cut_clipboard(&self) {
23        self.parent_cut_clipboard()
24    }
25
26    fn delete_from_cursor(&self, type_: DeleteType, count: i32) {
27        self.parent_delete_from_cursor(type_, count)
28    }
29
30    fn extend_selection(
31        &self,
32        granularity: TextExtendSelection,
33        location: &TextIter,
34        start: &mut TextIter,
35        end: &mut TextIter,
36    ) -> glib::ControlFlow {
37        self.parent_extend_selection(granularity, location, start, end)
38    }
39
40    fn insert_at_cursor(&self, text: &str) {
41        self.parent_insert_at_cursor(text)
42    }
43
44    fn insert_emoji(&self) {
45        self.parent_insert_emoji()
46    }
47
48    fn move_cursor(&self, step: MovementStep, count: i32, extend_selection: bool) {
49        self.parent_move_cursor(step, count, extend_selection)
50    }
51
52    fn paste_clipboard(&self) {
53        self.parent_paste_clipboard()
54    }
55
56    fn set_anchor(&self) {
57        self.parent_set_anchor()
58    }
59
60    fn snapshot_layer(&self, layer: TextViewLayer, snapshot: Snapshot) {
61        self.parent_snapshot_layer(layer, snapshot)
62    }
63
64    fn toggle_overwrite(&self) {
65        self.parent_toggle_overwrite()
66    }
67}
68
69pub trait TextViewImplExt: TextViewImpl {
70    fn parent_backspace(&self) {
71        unsafe {
72            let data = Self::type_data();
73            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTextViewClass;
74            if let Some(f) = (*parent_class).backspace {
75                f(self.obj().unsafe_cast_ref::<TextView>().to_glib_none().0)
76            }
77        }
78    }
79
80    fn parent_copy_clipboard(&self) {
81        unsafe {
82            let data = Self::type_data();
83            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTextViewClass;
84            if let Some(f) = (*parent_class).copy_clipboard {
85                f(self.obj().unsafe_cast_ref::<TextView>().to_glib_none().0)
86            }
87        }
88    }
89
90    fn parent_cut_clipboard(&self) {
91        unsafe {
92            let data = Self::type_data();
93            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTextViewClass;
94            if let Some(f) = (*parent_class).cut_clipboard {
95                f(self.obj().unsafe_cast_ref::<TextView>().to_glib_none().0)
96            }
97        }
98    }
99
100    fn parent_delete_from_cursor(&self, type_: DeleteType, count: i32) {
101        unsafe {
102            let data = Self::type_data();
103            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTextViewClass;
104            if let Some(f) = (*parent_class).delete_from_cursor {
105                f(
106                    self.obj().unsafe_cast_ref::<TextView>().to_glib_none().0,
107                    type_.into_glib(),
108                    count,
109                )
110            }
111        }
112    }
113
114    fn parent_extend_selection(
115        &self,
116        granularity: TextExtendSelection,
117        location: &TextIter,
118        start: &mut TextIter,
119        end: &mut TextIter,
120    ) -> glib::ControlFlow {
121        unsafe {
122            let data = Self::type_data();
123            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTextViewClass;
124            if let Some(f) = (*parent_class).extend_selection {
125                glib::ControlFlow::from_glib(f(
126                    self.obj().unsafe_cast_ref::<TextView>().to_glib_none().0,
127                    granularity.into_glib(),
128                    location.to_glib_none().0,
129                    start.to_glib_none_mut().0,
130                    end.to_glib_none_mut().0,
131                ))
132            } else {
133                glib::ControlFlow::Break
134            }
135        }
136    }
137
138    fn parent_insert_at_cursor(&self, text: &str) {
139        unsafe {
140            let data = Self::type_data();
141            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTextViewClass;
142            if let Some(f) = (*parent_class).insert_at_cursor {
143                f(
144                    self.obj().unsafe_cast_ref::<TextView>().to_glib_none().0,
145                    text.to_glib_none().0,
146                )
147            }
148        }
149    }
150
151    fn parent_insert_emoji(&self) {
152        unsafe {
153            let data = Self::type_data();
154            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTextViewClass;
155            if let Some(f) = (*parent_class).insert_emoji {
156                f(self.obj().unsafe_cast_ref::<TextView>().to_glib_none().0)
157            }
158        }
159    }
160
161    fn parent_move_cursor(&self, step: MovementStep, count: i32, extend_selection: bool) {
162        unsafe {
163            let data = Self::type_data();
164            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTextViewClass;
165            if let Some(f) = (*parent_class).move_cursor {
166                f(
167                    self.obj().unsafe_cast_ref::<TextView>().to_glib_none().0,
168                    step.into_glib(),
169                    count,
170                    extend_selection.into_glib(),
171                )
172            }
173        }
174    }
175
176    fn parent_paste_clipboard(&self) {
177        unsafe {
178            let data = Self::type_data();
179            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTextViewClass;
180            if let Some(f) = (*parent_class).paste_clipboard {
181                f(self.obj().unsafe_cast_ref::<TextView>().to_glib_none().0)
182            }
183        }
184    }
185
186    fn parent_set_anchor(&self) {
187        unsafe {
188            let data = Self::type_data();
189            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTextViewClass;
190            if let Some(f) = (*parent_class).set_anchor {
191                f(self.obj().unsafe_cast_ref::<TextView>().to_glib_none().0)
192            }
193        }
194    }
195
196    fn parent_snapshot_layer(&self, layer: TextViewLayer, snapshot: Snapshot) {
197        unsafe {
198            let data = Self::type_data();
199            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTextViewClass;
200            if let Some(f) = (*parent_class).snapshot_layer {
201                f(
202                    self.obj().unsafe_cast_ref::<TextView>().to_glib_none().0,
203                    layer.into_glib(),
204                    snapshot.to_glib_none().0,
205                )
206            }
207        }
208    }
209
210    fn parent_toggle_overwrite(&self) {
211        unsafe {
212            let data = Self::type_data();
213            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkTextViewClass;
214            if let Some(f) = (*parent_class).toggle_overwrite {
215                f(self.obj().unsafe_cast_ref::<TextView>().to_glib_none().0)
216            }
217        }
218    }
219}
220
221impl<T: TextViewImpl> TextViewImplExt for T {}
222
223unsafe impl<T: TextViewImpl> IsSubclassable<T> for TextView {
224    fn class_init(class: &mut glib::Class<Self>) {
225        Self::parent_class_init::<T>(class);
226
227        let klass = class.as_mut();
228        klass.backspace = Some(text_view_backspace::<T>);
229        klass.copy_clipboard = Some(text_view_copy_clipboard::<T>);
230        klass.cut_clipboard = Some(text_view_cut_clipboard::<T>);
231        klass.delete_from_cursor = Some(text_view_delete_from_cursor::<T>);
232        klass.extend_selection = Some(text_view_extend_selection::<T>);
233        klass.insert_at_cursor = Some(text_view_insert_at_cursor::<T>);
234        klass.insert_emoji = Some(text_view_insert_emoji::<T>);
235        klass.move_cursor = Some(text_view_move_cursor::<T>);
236        klass.paste_clipboard = Some(text_view_paste_clipboard::<T>);
237        klass.set_anchor = Some(text_view_set_anchor::<T>);
238        klass.snapshot_layer = Some(text_view_snapshot_layer::<T>);
239        klass.toggle_overwrite = Some(text_view_toggle_overwrite::<T>);
240    }
241}
242
243unsafe extern "C" fn text_view_backspace<T: TextViewImpl>(ptr: *mut ffi::GtkTextView) {
244    let instance = &*(ptr as *mut T::Instance);
245    let imp = instance.imp();
246
247    imp.backspace()
248}
249
250unsafe extern "C" fn text_view_copy_clipboard<T: TextViewImpl>(ptr: *mut ffi::GtkTextView) {
251    let instance = &*(ptr as *mut T::Instance);
252    let imp = instance.imp();
253
254    imp.copy_clipboard()
255}
256
257unsafe extern "C" fn text_view_cut_clipboard<T: TextViewImpl>(ptr: *mut ffi::GtkTextView) {
258    let instance = &*(ptr as *mut T::Instance);
259    let imp = instance.imp();
260
261    imp.cut_clipboard()
262}
263
264unsafe extern "C" fn text_view_delete_from_cursor<T: TextViewImpl>(
265    ptr: *mut ffi::GtkTextView,
266    type_: ffi::GtkDeleteType,
267    count: i32,
268) {
269    let instance = &*(ptr as *mut T::Instance);
270    let imp = instance.imp();
271
272    imp.delete_from_cursor(from_glib(type_), count)
273}
274
275unsafe extern "C" fn text_view_extend_selection<T: TextViewImpl>(
276    ptr: *mut ffi::GtkTextView,
277    granularity: ffi::GtkTextExtendSelection,
278    location: *const ffi::GtkTextIter,
279    start: *mut ffi::GtkTextIter,
280    end: *mut ffi::GtkTextIter,
281) -> glib::ffi::gboolean {
282    let instance = &*(ptr as *mut T::Instance);
283    let imp = instance.imp();
284
285    let mut start_copy = from_glib_none(start);
286    let mut end_copy = from_glib_none(end);
287
288    let result = imp.extend_selection(
289        from_glib(granularity),
290        &from_glib_borrow(location),
291        &mut start_copy,
292        &mut end_copy,
293    );
294    *start = *start_copy.to_glib_none().0;
295    *end = *end_copy.to_glib_none().0;
296
297    result.into_glib()
298}
299
300unsafe extern "C" fn text_view_insert_at_cursor<T: TextViewImpl>(
301    ptr: *mut ffi::GtkTextView,
302    text_ptr: *const libc::c_char,
303) {
304    let instance = &*(ptr as *mut T::Instance);
305    let imp = instance.imp();
306    let text: Borrowed<glib::GString> = from_glib_borrow(text_ptr);
307
308    imp.insert_at_cursor(text.as_str())
309}
310
311unsafe extern "C" fn text_view_insert_emoji<T: TextViewImpl>(ptr: *mut ffi::GtkTextView) {
312    let instance = &*(ptr as *mut T::Instance);
313    let imp = instance.imp();
314
315    imp.insert_emoji()
316}
317
318unsafe extern "C" fn text_view_move_cursor<T: TextViewImpl>(
319    ptr: *mut ffi::GtkTextView,
320    step: ffi::GtkMovementStep,
321    count: i32,
322    extend_selection: glib::ffi::gboolean,
323) {
324    let instance = &*(ptr as *mut T::Instance);
325    let imp = instance.imp();
326
327    imp.move_cursor(from_glib(step), count, from_glib(extend_selection))
328}
329
330unsafe extern "C" fn text_view_paste_clipboard<T: TextViewImpl>(ptr: *mut ffi::GtkTextView) {
331    let instance = &*(ptr as *mut T::Instance);
332    let imp = instance.imp();
333
334    imp.paste_clipboard()
335}
336
337unsafe extern "C" fn text_view_set_anchor<T: TextViewImpl>(ptr: *mut ffi::GtkTextView) {
338    let instance = &*(ptr as *mut T::Instance);
339    let imp = instance.imp();
340
341    imp.set_anchor()
342}
343
344unsafe extern "C" fn text_view_snapshot_layer<T: TextViewImpl>(
345    ptr: *mut ffi::GtkTextView,
346    layer: ffi::GtkTextViewLayer,
347    snapshot: *mut ffi::GtkSnapshot,
348) {
349    let instance = &*(ptr as *mut T::Instance);
350    let imp = instance.imp();
351
352    imp.snapshot_layer(from_glib(layer), from_glib_none(snapshot))
353}
354
355unsafe extern "C" fn text_view_toggle_overwrite<T: TextViewImpl>(ptr: *mut ffi::GtkTextView) {
356    let instance = &*(ptr as *mut T::Instance);
357    let imp = instance.imp();
358
359    imp.toggle_overwrite()
360}