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}