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}