gsk4/auto/
render_replay.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{ffi, RenderNode};
6use glib::{prelude::*, translate::*};
7use std::boxed::Box as Box_;
8
9glib::wrapper! {
10    /// A facility to replay a [`RenderNode`][crate::RenderNode] and its children, potentially
11    /// modifying them.
12    ///
13    /// This is a utility tool to walk a rendernode tree. The most powerful way
14    /// is to provide a function via [`set_node_filter()`][Self::set_node_filter()]
15    /// to filter each individual node and then run
16    /// [`filter_node()`][Self::filter_node()] on the nodes you want to filter.
17    ///
18    /// An easier method exists to just walk the node tree and extract information
19    /// without any modifications. If you want to do that, the functions
20    /// [`set_node_foreach()`][Self::set_node_foreach()] exists. You can also call
21    /// [`foreach_node()`][Self::foreach_node()] to run that function. Note that
22    /// the previously mentioned complex functionality will still be invoked if you
23    /// have set up a function for it, but its result will not be returned.
24    ///
25    /// Here is an example that combines both approaches to print the whole tree:
26    ///
27    /// **⚠️ The following code is in c ⚠️**
28    ///
29    /// ```c
30    /// #include <gtk/gtk.h>
31    ///
32    /// static GskRenderNode *
33    /// print_nodes (GskRenderReplay *replay,
34    ///              GskRenderNode   *node,
35    ///              gpointer         user_data)
36    /// {
37    ///   int *depth = user_data;
38    ///   GskRenderNode *result;
39    ///
40    ///   g_print ("%*s%s\n", 2 * *depth, "", g_type_name_from_instance ((GTypeInstance *) node));
41    ///
42    ///   *depth += 1;
43    ///   result = gsk_render_replay_default (replay, node);
44    ///   *depth -= 1;
45    ///
46    ///   return result;
47    /// }
48    ///
49    /// int
50    /// main (int argc, char *argv[])
51    /// {
52    ///   GFile *file;
53    ///   GBytes *bytes;
54    ///   GskRenderNode *node;
55    ///   GskRenderReplay *replay;
56    ///   int depth = 0;
57    ///
58    ///   gtk_init ();
59    ///
60    ///   if (argc < 2)
61    ///     {
62    ///       g_print ("usage: %s NODEFILE\n", argv[0]);
63    ///       return 0;
64    ///     }
65    ///
66    ///   file = g_file_new_for_commandline_arg (argv[1]);
67    ///   bytes = g_file_load_bytes (file, NULL, NULL, NULL);
68    ///   g_object_unref (file);
69    ///   if (bytes == NULL)
70    ///     return 1;
71    ///
72    ///   node = gsk_render_node_deserialize (bytes, NULL, NULL);
73    ///   g_bytes_unref (bytes);
74    ///   if (node == NULL)
75    ///     return 1;
76    ///
77    ///   replay = gsk_render_replay_new ();
78    ///   gsk_render_replay_set_node_filter (replay, print_nodes, &depth, NULL);
79    ///   gsk_render_node_foreach_node (replay, node);
80    ///   gsk_render_node_unref (node);
81    ///
82    ///   return 0;
83    /// }
84    /// ```
85    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
86    pub struct RenderReplay(Boxed<ffi::GskRenderReplay>);
87
88    match fn {
89        copy => |ptr| glib::gobject_ffi::g_boxed_copy(ffi::gsk_render_replay_get_type(), ptr as *mut _) as *mut ffi::GskRenderReplay,
90        free => |ptr| glib::gobject_ffi::g_boxed_free(ffi::gsk_render_replay_get_type(), ptr as *mut _),
91        type_ => || ffi::gsk_render_replay_get_type(),
92    }
93}
94
95impl RenderReplay {
96    /// Creates a new replay object to replay nodes.
97    ///
98    /// # Returns
99    ///
100    /// A new replay object to replay nodes
101    #[doc(alias = "gsk_render_replay_new")]
102    pub fn new() -> RenderReplay {
103        assert_initialized_main_thread!();
104        unsafe { from_glib_full(ffi::gsk_render_replay_new()) }
105    }
106
107    /// Replays the node using the default method.
108    ///
109    /// The default method calls [`filter_node()`][Self::filter_node()]
110    /// on all its child nodes and the filter functions for all its
111    /// properties. If none of them are changed, it returns the passed
112    /// in node. Otherwise it constructs a new node with the changed
113    /// children and properties.
114    ///
115    /// It may not be possible to construct a new node when any of the
116    /// callbacks return NULL. In that case, this function will return
117    /// NULL, too.
118    /// ## `node`
119    /// the node to replay
120    ///
121    /// # Returns
122    ///
123    /// The replayed node
124    #[doc(alias = "gsk_render_replay_default")]
125    #[allow(clippy::should_implement_trait)]
126    pub fn default(&mut self, node: impl AsRef<RenderNode>) -> Option<RenderNode> {
127        unsafe {
128            from_glib_full(ffi::gsk_render_replay_default(
129                self.to_glib_none_mut().0,
130                node.as_ref().to_glib_none().0,
131            ))
132        }
133    }
134
135    /// Filters a font using the current filter function.
136    /// ## `font`
137    /// The font to filter
138    ///
139    /// # Returns
140    ///
141    /// the filtered font
142    #[doc(alias = "gsk_render_replay_filter_font")]
143    pub fn filter_font(&mut self, font: &impl IsA<pango::Font>) -> pango::Font {
144        unsafe {
145            from_glib_full(ffi::gsk_render_replay_filter_font(
146                self.to_glib_none_mut().0,
147                font.as_ref().to_glib_none().0,
148            ))
149        }
150    }
151
152    /// Replays a node using the replay's filter function.
153    ///
154    /// After the replay the node may be unchanged, or it may be
155    /// removed, which will result in [`None`] being returned.
156    ///
157    /// This function calls the registered callback in the following order:
158    ///
159    /// 1. If a foreach function is set, it is called first. If it returns
160    ///    false, this function immediately exits and returns the passed
161    ///    in node.
162    ///
163    /// 2. If a node filter is set, it is called and its result is returned.
164    ///
165    /// 3. [`default()`][Self::default()] is called and its result is
166    ///    returned.
167    /// ## `node`
168    /// the node to replay
169    ///
170    /// # Returns
171    ///
172    /// The replayed node
173    #[doc(alias = "gsk_render_replay_filter_node")]
174    pub fn filter_node(&mut self, node: impl AsRef<RenderNode>) -> Option<RenderNode> {
175        unsafe {
176            from_glib_full(ffi::gsk_render_replay_filter_node(
177                self.to_glib_none_mut().0,
178                node.as_ref().to_glib_none().0,
179            ))
180        }
181    }
182
183    /// Filters a texture using the current filter function.
184    /// ## `texture`
185    /// The texture to filter
186    ///
187    /// # Returns
188    ///
189    /// the filtered texture
190    #[doc(alias = "gsk_render_replay_filter_texture")]
191    pub fn filter_texture(&mut self, texture: &impl IsA<gdk::Texture>) -> gdk::Texture {
192        unsafe {
193            from_glib_full(ffi::gsk_render_replay_filter_texture(
194                self.to_glib_none_mut().0,
195                texture.as_ref().to_glib_none().0,
196            ))
197        }
198    }
199
200    /// Calls the filter and foreach functions for each node.
201    ///
202    /// This function calls [`filter_node()`][Self::filter_node()] internally,
203    /// but discards the result assuming no changes were made.
204    /// ## `node`
205    /// the node to replay
206    #[doc(alias = "gsk_render_replay_foreach_node")]
207    pub fn foreach_node(&mut self, node: impl AsRef<RenderNode>) {
208        unsafe {
209            ffi::gsk_render_replay_foreach_node(
210                self.to_glib_none_mut().0,
211                node.as_ref().to_glib_none().0,
212            );
213        }
214    }
215
216    /// Sets a filter function to be called by [`default()`][Self::default()]
217    /// for nodes that contain fonts.
218    ///
219    /// You can call `GskRenderReplay::filter_font()` to filter
220    /// a font yourself.
221    /// ## `filter`
222    ///
223    ///   the font filter function
224    #[doc(alias = "gsk_render_replay_set_font_filter")]
225    pub fn set_font_filter(
226        &mut self,
227        filter: Option<Box_<dyn Fn(&RenderReplay, &pango::Font) -> pango::Font + 'static>>,
228    ) {
229        let filter_data: Box_<
230            Option<Box_<dyn Fn(&RenderReplay, &pango::Font) -> pango::Font + 'static>>,
231        > = Box_::new(filter);
232        unsafe extern "C" fn filter_func(
233            replay: *mut ffi::GskRenderReplay,
234            font: *mut pango::ffi::PangoFont,
235            user_data: glib::ffi::gpointer,
236        ) -> *mut pango::ffi::PangoFont {
237            let replay = from_glib_borrow(replay);
238            let font = from_glib_borrow(font);
239            let callback = &*(user_data
240                as *mut Option<Box_<dyn Fn(&RenderReplay, &pango::Font) -> pango::Font + 'static>>);
241            if let Some(ref callback) = *callback {
242                callback(&replay, &font)
243            } else {
244                panic!("cannot get closure...")
245            }
246            .to_glib_full()
247        }
248        let filter = if filter_data.is_some() {
249            Some(filter_func as _)
250        } else {
251            None
252        };
253        unsafe extern "C" fn user_destroy_func(data: glib::ffi::gpointer) {
254            let _callback = Box_::from_raw(
255                data as *mut Option<
256                    Box_<dyn Fn(&RenderReplay, &pango::Font) -> pango::Font + 'static>,
257                >,
258            );
259        }
260        let destroy_call3 = Some(user_destroy_func as _);
261        let super_callback0: Box_<
262            Option<Box_<dyn Fn(&RenderReplay, &pango::Font) -> pango::Font + 'static>>,
263        > = filter_data;
264        unsafe {
265            ffi::gsk_render_replay_set_font_filter(
266                self.to_glib_none_mut().0,
267                filter,
268                Box_::into_raw(super_callback0) as *mut _,
269                destroy_call3,
270            );
271        }
272    }
273
274    /// Sets the function to use as a node filter.
275    ///
276    /// This is the most complex function to use for replaying nodes.
277    /// It can either:
278    ///
279    /// * keep the node and just return it unchanged
280    ///
281    /// * create a replacement node and return that
282    ///
283    /// * discard the node by returning `NULL`
284    ///
285    /// * call [`default()`][Self::default()] to have the default handler
286    ///   run for this node, which calls your function on its children
287    /// ## `filter`
288    ///
289    ///   the function to call to replay nodes
290    #[doc(alias = "gsk_render_replay_set_node_filter")]
291    pub fn set_node_filter(
292        &mut self,
293        filter: Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>>,
294    ) {
295        let filter_data: Box_<
296            Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>>,
297        > = Box_::new(filter);
298        unsafe extern "C" fn filter_func(
299            replay: *mut ffi::GskRenderReplay,
300            node: *mut ffi::GskRenderNode,
301            user_data: glib::ffi::gpointer,
302        ) -> *mut ffi::GskRenderNode {
303            let replay = from_glib_borrow(replay);
304            let node = from_glib_borrow(node);
305            let callback = &*(user_data
306                as *mut Option<
307                    Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>,
308                >);
309            if let Some(ref callback) = *callback {
310                callback(&replay, &node)
311            } else {
312                panic!("cannot get closure...")
313            }
314            .to_glib_full()
315        }
316        let filter = if filter_data.is_some() {
317            Some(filter_func as _)
318        } else {
319            None
320        };
321        unsafe extern "C" fn user_destroy_func(data: glib::ffi::gpointer) {
322            let _callback = Box_::from_raw(
323                data as *mut Option<
324                    Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>,
325                >,
326            );
327        }
328        let destroy_call3 = Some(user_destroy_func as _);
329        let super_callback0: Box_<
330            Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>>,
331        > = filter_data;
332        unsafe {
333            ffi::gsk_render_replay_set_node_filter(
334                self.to_glib_none_mut().0,
335                filter,
336                Box_::into_raw(super_callback0) as *mut _,
337                destroy_call3,
338            );
339        }
340    }
341
342    /// Sets the function to call for every node.
343    ///
344    /// This function is called before the node filter, so if it returns
345    /// false, the node filter will never be called.
346    /// ## `foreach`
347    ///
348    ///   the function to call for all nodes
349    #[doc(alias = "gsk_render_replay_set_node_foreach")]
350    pub fn set_node_foreach(
351        &mut self,
352        foreach: Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> bool + 'static>>,
353    ) {
354        let foreach_data: Box_<Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> bool + 'static>>> =
355            Box_::new(foreach);
356        unsafe extern "C" fn foreach_func(
357            replay: *mut ffi::GskRenderReplay,
358            node: *mut ffi::GskRenderNode,
359            user_data: glib::ffi::gpointer,
360        ) -> glib::ffi::gboolean {
361            let replay = from_glib_borrow(replay);
362            let node = from_glib_borrow(node);
363            let callback = &*(user_data
364                as *mut Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> bool + 'static>>);
365            if let Some(ref callback) = *callback {
366                callback(&replay, &node)
367            } else {
368                panic!("cannot get closure...")
369            }
370            .into_glib()
371        }
372        let foreach = if foreach_data.is_some() {
373            Some(foreach_func as _)
374        } else {
375            None
376        };
377        unsafe extern "C" fn user_destroy_func(data: glib::ffi::gpointer) {
378            let _callback = Box_::from_raw(
379                data as *mut Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> bool + 'static>>,
380            );
381        }
382        let destroy_call3 = Some(user_destroy_func as _);
383        let super_callback0: Box_<
384            Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> bool + 'static>>,
385        > = foreach_data;
386        unsafe {
387            ffi::gsk_render_replay_set_node_foreach(
388                self.to_glib_none_mut().0,
389                foreach,
390                Box_::into_raw(super_callback0) as *mut _,
391                destroy_call3,
392            );
393        }
394    }
395
396    /// Sets a filter function to be called by [`default()`][Self::default()]
397    /// for nodes that contain textures.
398    ///
399    /// You can call `GskRenderReplay::filter_texture()` to filter
400    /// a texture yourself.
401    /// ## `filter`
402    ///
403    ///   the texture filter function
404    #[doc(alias = "gsk_render_replay_set_texture_filter")]
405    pub fn set_texture_filter(
406        &mut self,
407        filter: Option<Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>>,
408    ) {
409        let filter_data: Box_<
410            Option<Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>>,
411        > = Box_::new(filter);
412        unsafe extern "C" fn filter_func(
413            replay: *mut ffi::GskRenderReplay,
414            texture: *mut gdk::ffi::GdkTexture,
415            user_data: glib::ffi::gpointer,
416        ) -> *mut gdk::ffi::GdkTexture {
417            let replay = from_glib_borrow(replay);
418            let texture = from_glib_borrow(texture);
419            let callback = &*(user_data
420                as *mut Option<
421                    Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>,
422                >);
423            if let Some(ref callback) = *callback {
424                callback(&replay, &texture)
425            } else {
426                panic!("cannot get closure...")
427            }
428            .to_glib_full()
429        }
430        let filter = if filter_data.is_some() {
431            Some(filter_func as _)
432        } else {
433            None
434        };
435        unsafe extern "C" fn user_destroy_func(data: glib::ffi::gpointer) {
436            let _callback = Box_::from_raw(
437                data as *mut Option<
438                    Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>,
439                >,
440            );
441        }
442        let destroy_call3 = Some(user_destroy_func as _);
443        let super_callback0: Box_<
444            Option<Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>>,
445        > = filter_data;
446        unsafe {
447            ffi::gsk_render_replay_set_texture_filter(
448                self.to_glib_none_mut().0,
449                filter,
450                Box_::into_raw(super_callback0) as *mut _,
451                destroy_call3,
452            );
453        }
454    }
455}
456
457#[cfg(feature = "v4_22")]
458#[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
459impl Default for RenderReplay {
460    fn default() -> Self {
461        Self::new()
462    }
463}