Skip to main content

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::{RenderNode, ffi};
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            unsafe {
238                let replay = from_glib_borrow(replay);
239                let font = from_glib_borrow(font);
240                let callback = &*(user_data
241                    as *mut Option<
242                        Box_<dyn Fn(&RenderReplay, &pango::Font) -> pango::Font + 'static>,
243                    >);
244                if let Some(ref callback) = *callback {
245                    callback(&replay, &font)
246                } else {
247                    panic!("cannot get closure...")
248                }
249                .to_glib_full()
250            }
251        }
252        let filter = if filter_data.is_some() {
253            Some(filter_func as _)
254        } else {
255            None
256        };
257        unsafe extern "C" fn user_destroy_func(data: glib::ffi::gpointer) {
258            unsafe {
259                let _callback = Box_::from_raw(
260                    data as *mut Option<
261                        Box_<dyn Fn(&RenderReplay, &pango::Font) -> pango::Font + 'static>,
262                    >,
263                );
264            }
265        }
266        let destroy_call3 = Some(user_destroy_func as _);
267        let super_callback0: Box_<
268            Option<Box_<dyn Fn(&RenderReplay, &pango::Font) -> pango::Font + 'static>>,
269        > = filter_data;
270        unsafe {
271            ffi::gsk_render_replay_set_font_filter(
272                self.to_glib_none_mut().0,
273                filter,
274                Box_::into_raw(super_callback0) as *mut _,
275                destroy_call3,
276            );
277        }
278    }
279
280    /// Sets the function to use as a node filter.
281    ///
282    /// This is the most complex function to use for replaying nodes.
283    /// It can either:
284    ///
285    /// * keep the node and just return it unchanged
286    ///
287    /// * create a replacement node and return that
288    ///
289    /// * discard the node by returning `NULL`
290    ///
291    /// * call [`default()`][Self::default()] to have the default handler
292    ///   run for this node, which calls your function on its children
293    /// ## `filter`
294    ///
295    ///   the function to call to replay nodes
296    #[doc(alias = "gsk_render_replay_set_node_filter")]
297    pub fn set_node_filter(
298        &mut self,
299        filter: Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>>,
300    ) {
301        let filter_data: Box_<
302            Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>>,
303        > = Box_::new(filter);
304        unsafe extern "C" fn filter_func(
305            replay: *mut ffi::GskRenderReplay,
306            node: *mut ffi::GskRenderNode,
307            user_data: glib::ffi::gpointer,
308        ) -> *mut ffi::GskRenderNode {
309            unsafe {
310                let replay = from_glib_borrow(replay);
311                let node = from_glib_borrow(node);
312                let callback = &*(user_data
313                    as *mut Option<
314                        Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>,
315                    >);
316                if let Some(ref callback) = *callback {
317                    callback(&replay, &node)
318                } else {
319                    panic!("cannot get closure...")
320                }
321                .to_glib_full()
322            }
323        }
324        let filter = if filter_data.is_some() {
325            Some(filter_func as _)
326        } else {
327            None
328        };
329        unsafe extern "C" fn user_destroy_func(data: glib::ffi::gpointer) {
330            unsafe {
331                let _callback = Box_::from_raw(
332                    data as *mut Option<
333                        Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>,
334                    >,
335                );
336            }
337        }
338        let destroy_call3 = Some(user_destroy_func as _);
339        let super_callback0: Box_<
340            Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> Option<RenderNode> + 'static>>,
341        > = filter_data;
342        unsafe {
343            ffi::gsk_render_replay_set_node_filter(
344                self.to_glib_none_mut().0,
345                filter,
346                Box_::into_raw(super_callback0) as *mut _,
347                destroy_call3,
348            );
349        }
350    }
351
352    /// Sets the function to call for every node.
353    ///
354    /// This function is called before the node filter, so if it returns
355    /// false, the node filter will never be called.
356    /// ## `foreach`
357    ///
358    ///   the function to call for all nodes
359    #[doc(alias = "gsk_render_replay_set_node_foreach")]
360    pub fn set_node_foreach(
361        &mut self,
362        foreach: Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> bool + 'static>>,
363    ) {
364        let foreach_data: Box_<Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> bool + 'static>>> =
365            Box_::new(foreach);
366        unsafe extern "C" fn foreach_func(
367            replay: *mut ffi::GskRenderReplay,
368            node: *mut ffi::GskRenderNode,
369            user_data: glib::ffi::gpointer,
370        ) -> glib::ffi::gboolean {
371            unsafe {
372                let replay = from_glib_borrow(replay);
373                let node = from_glib_borrow(node);
374                let callback = &*(user_data
375                    as *mut Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> bool + 'static>>);
376                if let Some(ref callback) = *callback {
377                    callback(&replay, &node)
378                } else {
379                    panic!("cannot get closure...")
380                }
381                .into_glib()
382            }
383        }
384        let foreach = if foreach_data.is_some() {
385            Some(foreach_func as _)
386        } else {
387            None
388        };
389        unsafe extern "C" fn user_destroy_func(data: glib::ffi::gpointer) {
390            unsafe {
391                let _callback = Box_::from_raw(
392                    data as *mut Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> bool + 'static>>,
393                );
394            }
395        }
396        let destroy_call3 = Some(user_destroy_func as _);
397        let super_callback0: Box_<
398            Option<Box_<dyn Fn(&RenderReplay, &RenderNode) -> bool + 'static>>,
399        > = foreach_data;
400        unsafe {
401            ffi::gsk_render_replay_set_node_foreach(
402                self.to_glib_none_mut().0,
403                foreach,
404                Box_::into_raw(super_callback0) as *mut _,
405                destroy_call3,
406            );
407        }
408    }
409
410    /// Sets a filter function to be called by [`default()`][Self::default()]
411    /// for nodes that contain textures.
412    ///
413    /// You can call `GskRenderReplay::filter_texture()` to filter
414    /// a texture yourself.
415    /// ## `filter`
416    ///
417    ///   the texture filter function
418    #[doc(alias = "gsk_render_replay_set_texture_filter")]
419    pub fn set_texture_filter(
420        &mut self,
421        filter: Option<Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>>,
422    ) {
423        let filter_data: Box_<
424            Option<Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>>,
425        > = Box_::new(filter);
426        unsafe extern "C" fn filter_func(
427            replay: *mut ffi::GskRenderReplay,
428            texture: *mut gdk::ffi::GdkTexture,
429            user_data: glib::ffi::gpointer,
430        ) -> *mut gdk::ffi::GdkTexture {
431            unsafe {
432                let replay = from_glib_borrow(replay);
433                let texture = from_glib_borrow(texture);
434                let callback = &*(user_data
435                    as *mut Option<
436                        Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>,
437                    >);
438                if let Some(ref callback) = *callback {
439                    callback(&replay, &texture)
440                } else {
441                    panic!("cannot get closure...")
442                }
443                .to_glib_full()
444            }
445        }
446        let filter = if filter_data.is_some() {
447            Some(filter_func as _)
448        } else {
449            None
450        };
451        unsafe extern "C" fn user_destroy_func(data: glib::ffi::gpointer) {
452            unsafe {
453                let _callback = Box_::from_raw(
454                    data as *mut Option<
455                        Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>,
456                    >,
457                );
458            }
459        }
460        let destroy_call3 = Some(user_destroy_func as _);
461        let super_callback0: Box_<
462            Option<Box_<dyn Fn(&RenderReplay, &gdk::Texture) -> gdk::Texture + 'static>>,
463        > = filter_data;
464        unsafe {
465            ffi::gsk_render_replay_set_texture_filter(
466                self.to_glib_none_mut().0,
467                filter,
468                Box_::into_raw(super_callback0) as *mut _,
469                destroy_call3,
470            );
471        }
472    }
473}
474
475#[cfg(feature = "v4_22")]
476#[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
477impl Default for RenderReplay {
478    fn default() -> Self {
479        Self::new()
480    }
481}