gtk4/auto/
svg.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, SymbolicPaintable};
6use glib::{
7    object::ObjectType as _,
8    prelude::*,
9    signal::{connect_raw, SignalHandlerId},
10    translate::*,
11};
12use std::boxed::Box as Box_;
13
14glib::wrapper! {
15    /// A paintable implementation that renders (a subset of) SVG,
16    /// with animations.
17    ///
18    /// [`Svg`][crate::Svg] objects are created by parsing a subset of SVG,
19    /// including SVG animations.
20    ///
21    /// The [`Svg`][crate::Svg] fills or strokes paths with symbolic or fixed
22    /// colors. It can have multiple states, and paths can be included
23    /// in a subset of the states. The special 'empty' state is always
24    /// available. States can have animation, and the transition between
25    /// different states can also be animated.
26    ///
27    /// To find out what states a [`Svg`][crate::Svg] has, use [`n_states()`][Self::n_states()].
28    /// To set the current state, use [`set_state()`][Self::set_state()].
29    ///
30    /// To play the animations in an SVG file, use
31    /// [`set_frame_clock()`][Self::set_frame_clock()] to connect the paintable to a frame clock,
32    /// and then use [`play()`][Self::play()] to start the animation.
33    ///
34    ///
35    /// ## Error handling
36    ///
37    /// Loading an SVG into [`Svg`][crate::Svg] will always produce a (possibly empty)
38    /// paintable. GTK will drop things that it can't handle and try to make
39    /// sense of the rest.
40    ///
41    /// To track errors during parsing or rednering, connect to the
42    /// [`error`][struct@crate::Svg#error] signal.
43    ///
44    /// For parsing errors in the `GTK_SVG_ERROR` domain, the functions
45    /// `Gtk::SvgError::get_start()`, `Gtk::SvgError::get_end()`,
46    /// `Gtk::SvgError::get_element()` and `Gtk::SvgError::get_attribute()`
47    /// can be used to obtain information about where the error occurred.
48    ///
49    ///
50    /// ## The supported subset of SVG
51    ///
52    /// The paintable does not support text or images, only shapes and paths.
53    ///
54    /// In `<defs>`, only `<clipPath>`, `<mask>`, gradients and shapes are
55    /// supported, not `<filter>`, `<pattern>` or other things.
56    ///
57    /// Gradient templating is not implemented.
58    ///
59    /// The support for filters is limited to filter functions minus
60    /// `drop-shadow()` plus a custom `alpha-level()` function, which
61    /// implements one particular case of feComponentTransfer.
62    ///
63    /// The `transform-origin` and `transform-box` attributes are not supported.
64    ///
65    /// The support for the `mask` attribute is limited to just a url
66    /// referring to the `<mask>` element by ID.
67    ///
68    /// In animation elements, the parsing of `begin` and `end` attributes
69    /// is limited, and the `by`, `min` and `max` attributes are not supported.
70    ///
71    /// Lastly, there is no CSS support, and no interactivity.
72    ///
73    ///
74    /// ## SVG Extensions
75    ///
76    /// The paintable supports a number of [custom attributes](icon-format.html)
77    /// that offer a convenient way to define states, transitions and animations.
78    /// For example,
79    ///
80    ///     <circle cx='5' cy='5' r='5'
81    ///             gpa:states='0 1'
82    ///             gpa:animation-type='automatic'
83    ///             gpa:animation-direction='segment'
84    ///             gpa:animation-duration='600ms'/>
85    ///
86    /// defines the circle to be shown in states 0 and 1, and animates a segment
87    /// of the circle.
88    ///
89    /// <image src="svg-renderer1.svg">
90    ///
91    /// Note that the generated animations assume a `pathLengh` value of 1.
92    /// Setting `pathLength` in your SVG is therefore going to interfere with
93    /// generated animations.
94    ///
95    /// To connect general SVG animations to the states of the paintable,
96    /// use the custom `gpa:states(...)` condition in the `begin` and `end`
97    /// attributes of SVG animation elements. For example,
98    ///
99    ///     <animate href='path1'
100    ///              attributeName='fill'
101    ///              begin='gpa:states(0).begin'
102    ///              dur='300ms'
103    ///              fill='freeze'
104    ///              from='black'
105    ///              to='magenta'/>
106    ///
107    /// will make the fill color of path1 transition from black to
108    /// magenta when the renderer enters state 0.
109    ///
110    /// <image src="svg-renderer2.svg">
111    ///
112    /// The `gpa:states(...)` condition triggers for upcoming state changes
113    /// as well, to support fade-out transitions. For example,
114    ///
115    ///     <animate href='path1'
116    ///              attributeName='opacity'
117    ///              begin='gpa:states(0).end -300ms'
118    ///              dur='300ms'
119    ///              fill='freeze'
120    ///              from='1'
121    ///              to='0'/>
122    ///
123    /// will start a fade-out of path1 300ms before state 0 ends.
124    ///
125    /// In addition to `gpa:fill` and `gpa:stroke`, symbolic colors can
126    /// also be specified as a custom paint server reference, like this:
127    /// `url(gpa:#warning)`. This works in `fill` and `stroke` attributes,
128    /// but also when specifying colors in SVG animation attributes like
129    /// `to` or `values`.
130    ///
131    /// Note that the SVG syntax allows for a fallback RGB color to be
132    /// specified after the url, for compatibility with other SVG consumers:
133    ///
134    ///     fill='url(gpa:#warning) orange'
135    ///
136    /// In contrast to SVG 1.1 and 2.0, we allow the `transform` attribute
137    /// to be animated with `<animate>`.
138    ///
139    /// ## Properties
140    ///
141    ///
142    /// #### `playing`
143    ///  Whether the paintable is currently animating its content.
144    ///
145    /// To set this property, use the [`Svg::play()`][crate::Svg::play()] and
146    /// [`Svg::pause()`][crate::Svg::pause()] functions.
147    ///
148    /// Readable | Writeable
149    ///
150    ///
151    /// #### `resource`
152    ///  Construct-only property to create a paintable from
153    /// a resource in ui files.
154    ///
155    /// Writeable | Construct Only
156    ///
157    ///
158    /// #### `state`
159    ///  The current state of the renderer.
160    ///
161    /// This can be a number between 0 and 63, or the special value
162    /// `(unsigned int) -1` to indicate the 'empty' state in which
163    /// nothing is drawn.
164    ///
165    /// Readable | Writeable
166    ///
167    ///
168    /// #### `weight`
169    ///  If not set to -1, this value overrides the weight used
170    /// when rendering the paintable.
171    ///
172    /// Readable | Writeable
173    ///
174    /// ## Signals
175    ///
176    ///
177    /// #### `error`
178    ///  Signals that an error occurred.
179    ///
180    /// Errors can occur both during parsing and during rendering.
181    ///
182    /// The expected error values are in the `Gtk::SvgError` enumeration,
183    /// context information about the location of parsing errors can
184    /// be obtained with the various `gtk_svg_error` functions.
185    ///
186    /// Parsing errors are never fatal, so the parsing will resume after
187    /// the error. Errors may however cause parts of the given data or
188    /// even all of it to not be parsed at all. So it is a useful idea
189    /// to check that the parsing succeeds by connecting to this signal.
190    ///
191    /// ::: note
192    ///     This signal is emitted in the middle of parsing or rendering,
193    ///     and if you handle it, you must be careful. Logging the errors
194    ///     you receive is fine, but modifying the widget hierarchy or
195    ///     changing the paintable state definitively isn't.
196    ///
197    ///     If in doubt, defer to an idle.
198    ///
199    ///
200    /// <details><summary><h4>Paintable</h4></summary>
201    ///
202    ///
203    /// #### `invalidate-contents`
204    ///  Emitted when the contents of the @paintable change.
205    ///
206    /// Examples for such an event would be videos changing to the next frame or
207    /// the icon theme for an icon changing.
208    ///
209    ///
210    ///
211    ///
212    /// #### `invalidate-size`
213    ///  Emitted when the intrinsic size of the @paintable changes.
214    ///
215    /// This means the values reported by at least one of
216    /// [`PaintableExtManual::intrinsic_width()`][crate::gdk::prelude::PaintableExtManual::intrinsic_width()],
217    /// [`PaintableExtManual::intrinsic_height()`][crate::gdk::prelude::PaintableExtManual::intrinsic_height()] or
218    /// [`PaintableExtManual::intrinsic_aspect_ratio()`][crate::gdk::prelude::PaintableExtManual::intrinsic_aspect_ratio()]
219    /// has changed.
220    ///
221    /// Examples for such an event would be a paintable displaying
222    /// the contents of a toplevel surface being resized.
223    ///
224    ///
225    /// </details>
226    ///
227    /// # Implements
228    ///
229    /// [`trait@glib::ObjectExt`], [`trait@gdk::prelude::PaintableExt`], [`SymbolicPaintableExt`][trait@crate::prelude::SymbolicPaintableExt]
230    #[doc(alias = "GtkSvg")]
231    pub struct Svg(Object<ffi::GtkSvg, ffi::GtkSvgClass>) @implements gdk::Paintable, SymbolicPaintable;
232
233    match fn {
234        type_ => || ffi::gtk_svg_get_type(),
235    }
236}
237
238impl Svg {
239    /// Creates a new, empty SVG paintable.
240    ///
241    /// # Returns
242    ///
243    /// the paintable
244    #[doc(alias = "gtk_svg_new")]
245    pub fn new() -> Svg {
246        assert_initialized_main_thread!();
247        unsafe { from_glib_full(ffi::gtk_svg_new()) }
248    }
249
250    /// Parses the SVG data in @bytes and creates a paintable.
251    /// ## `bytes`
252    /// the data
253    ///
254    /// # Returns
255    ///
256    /// the paintable
257    #[doc(alias = "gtk_svg_new_from_bytes")]
258    #[doc(alias = "new_from_bytes")]
259    pub fn from_bytes(bytes: &glib::Bytes) -> Svg {
260        assert_initialized_main_thread!();
261        unsafe { from_glib_full(ffi::gtk_svg_new_from_bytes(bytes.to_glib_none().0)) }
262    }
263
264    /// Parses the SVG data in the resource and creates a paintable.
265    /// ## `path`
266    /// the resource path
267    ///
268    /// # Returns
269    ///
270    /// the paintable
271    #[doc(alias = "gtk_svg_new_from_resource")]
272    #[doc(alias = "new_from_resource")]
273    pub fn from_resource(path: &str) -> Svg {
274        assert_initialized_main_thread!();
275        unsafe { from_glib_full(ffi::gtk_svg_new_from_resource(path.to_glib_none().0)) }
276    }
277
278    /// Gets the number of states defined in the SVG.
279    ///
280    /// Note that there is always an empty state, which does
281    /// not count towards this number. If this function returns
282    /// the value N, the meaningful states of the SVG are
283    /// 0, 1, ..., N - 1 and `GTK_SVG_STATE_EMPTY`.
284    ///
285    /// # Returns
286    ///
287    /// the number of states
288    #[doc(alias = "gtk_svg_get_n_states")]
289    #[doc(alias = "get_n_states")]
290    pub fn n_states(&self) -> u32 {
291        unsafe { ffi::gtk_svg_get_n_states(self.to_glib_none().0) }
292    }
293
294    /// Gets the current state of the paintable.
295    ///
296    /// # Returns
297    ///
298    /// the state
299    #[doc(alias = "gtk_svg_get_state")]
300    #[doc(alias = "get_state")]
301    pub fn state(&self) -> u32 {
302        unsafe { ffi::gtk_svg_get_state(self.to_glib_none().0) }
303    }
304
305    /// Gets the value of the weight property.
306    ///
307    /// # Returns
308    ///
309    /// the weight
310    #[doc(alias = "gtk_svg_get_weight")]
311    #[doc(alias = "get_weight")]
312    pub fn weight(&self) -> f64 {
313        unsafe { ffi::gtk_svg_get_weight(self.to_glib_none().0) }
314    }
315
316    /// Loads SVG content into an existing SVG paintable.
317    ///
318    /// To track errors while loading SVG content,
319    /// connect to the [`error`][struct@crate::Svg#error] signal.
320    ///
321    /// This clears any previously loaded content.
322    /// ## `bytes`
323    /// the data to load
324    #[doc(alias = "gtk_svg_load_from_bytes")]
325    pub fn load_from_bytes(&self, bytes: &glib::Bytes) {
326        unsafe {
327            ffi::gtk_svg_load_from_bytes(self.to_glib_none().0, bytes.to_glib_none().0);
328        }
329    }
330
331    /// Stop any playing animations.
332    ///
333    /// Animations can be paused and started repeatedly.
334    #[doc(alias = "gtk_svg_pause")]
335    pub fn pause(&self) {
336        unsafe {
337            ffi::gtk_svg_pause(self.to_glib_none().0);
338        }
339    }
340
341    /// Start playing animations.
342    ///
343    /// Note that this is necessary for state changes as
344    /// well.
345    #[doc(alias = "gtk_svg_play")]
346    pub fn play(&self) {
347        unsafe {
348            ffi::gtk_svg_play(self.to_glib_none().0);
349        }
350    }
351
352    /// Serializes the content of the renderer as SVG.
353    ///
354    /// The SVG will be similar to the orignally loaded one,
355    /// but is not guaranteed to be 100% identical.
356    ///
357    /// This function serializes the DOM, i.e. the results
358    /// of parsing the SVG. It does not reflect the effect
359    /// of applying animations.
360    ///
361    /// # Returns
362    ///
363    /// the serialized contents
364    #[doc(alias = "gtk_svg_serialize")]
365    pub fn serialize(&self) -> glib::Bytes {
366        unsafe { from_glib_full(ffi::gtk_svg_serialize(self.to_glib_none().0)) }
367    }
368
369    /// Sets a frame clock.
370    ///
371    /// Without a frame clock, GTK has to rely
372    /// on simple timeouts to run animations.
373    /// ## `clock`
374    /// the frame clock
375    #[doc(alias = "gtk_svg_set_frame_clock")]
376    pub fn set_frame_clock(&self, clock: &gdk::FrameClock) {
377        unsafe {
378            ffi::gtk_svg_set_frame_clock(self.to_glib_none().0, clock.to_glib_none().0);
379        }
380    }
381
382    /// Sets the state of the paintable.
383    ///
384    /// Use [`n_states()`][Self::n_states()] to find out
385    /// what states @self has.
386    ///
387    /// Note that [`play()`][Self::play()] must have been
388    /// called for the SVG paintable to react to state changes.
389    /// ## `state`
390    /// the state to set, as a value between 0 and 63,
391    ///   or `(unsigned int) -1`
392    #[doc(alias = "gtk_svg_set_state")]
393    #[doc(alias = "state")]
394    pub fn set_state(&self, state: u32) {
395        unsafe {
396            ffi::gtk_svg_set_state(self.to_glib_none().0, state);
397        }
398    }
399
400    /// Sets the weight that is used when rendering.
401    ///
402    /// The default value of -1 means to use the font weight
403    /// from CSS.
404    /// ## `weight`
405    /// the font weight, as a value between -1 and 1000
406    #[doc(alias = "gtk_svg_set_weight")]
407    #[doc(alias = "weight")]
408    pub fn set_weight(&self, weight: f64) {
409        unsafe {
410            ffi::gtk_svg_set_weight(self.to_glib_none().0, weight);
411        }
412    }
413
414    /// Serializes the paintable, and saves the result to a file.
415    /// ## `filename`
416    /// the file to save to
417    ///
418    /// # Returns
419    ///
420    /// true, unless an error occurred
421    #[doc(alias = "gtk_svg_write_to_file")]
422    pub fn write_to_file(&self, filename: &str) -> Result<(), glib::Error> {
423        unsafe {
424            let mut error = std::ptr::null_mut();
425            let is_ok = ffi::gtk_svg_write_to_file(
426                self.to_glib_none().0,
427                filename.to_glib_none().0,
428                &mut error,
429            );
430            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
431            if error.is_null() {
432                Ok(())
433            } else {
434                Err(from_glib_full(error))
435            }
436        }
437    }
438
439    /// Whether the paintable is currently animating its content.
440    ///
441    /// To set this property, use the [`play()`][Self::play()] and
442    /// [`pause()`][Self::pause()] functions.
443    #[cfg(feature = "v4_22")]
444    #[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
445    pub fn is_playing(&self) -> bool {
446        ObjectExt::property(self, "playing")
447    }
448
449    /// Whether the paintable is currently animating its content.
450    ///
451    /// To set this property, use the [`play()`][Self::play()] and
452    /// [`pause()`][Self::pause()] functions.
453    #[cfg(feature = "v4_22")]
454    #[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
455    pub fn set_playing(&self, playing: bool) {
456        ObjectExt::set_property(self, "playing", playing)
457    }
458
459    /// Signals that an error occurred.
460    ///
461    /// Errors can occur both during parsing and during rendering.
462    ///
463    /// The expected error values are in the `Gtk::SvgError` enumeration,
464    /// context information about the location of parsing errors can
465    /// be obtained with the various `gtk_svg_error` functions.
466    ///
467    /// Parsing errors are never fatal, so the parsing will resume after
468    /// the error. Errors may however cause parts of the given data or
469    /// even all of it to not be parsed at all. So it is a useful idea
470    /// to check that the parsing succeeds by connecting to this signal.
471    ///
472    /// ::: note
473    ///     This signal is emitted in the middle of parsing or rendering,
474    ///     and if you handle it, you must be careful. Logging the errors
475    ///     you receive is fine, but modifying the widget hierarchy or
476    ///     changing the paintable state definitively isn't.
477    ///
478    ///     If in doubt, defer to an idle.
479    /// ## `error`
480    /// the error
481    #[cfg(feature = "v4_22")]
482    #[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
483    #[doc(alias = "error")]
484    pub fn connect_error<F: Fn(&Self, &glib::Error) + 'static>(&self, f: F) -> SignalHandlerId {
485        unsafe extern "C" fn error_trampoline<F: Fn(&Svg, &glib::Error) + 'static>(
486            this: *mut ffi::GtkSvg,
487            error: *mut glib::ffi::GError,
488            f: glib::ffi::gpointer,
489        ) {
490            let f: &F = &*(f as *const F);
491            f(&from_glib_borrow(this), &from_glib_borrow(error))
492        }
493        unsafe {
494            let f: Box_<F> = Box_::new(f);
495            connect_raw(
496                self.as_ptr() as *mut _,
497                c"error".as_ptr() as *const _,
498                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
499                    error_trampoline::<F> as *const (),
500                )),
501                Box_::into_raw(f),
502            )
503        }
504    }
505
506    #[cfg(feature = "v4_22")]
507    #[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
508    #[doc(alias = "playing")]
509    pub fn connect_playing_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
510        unsafe extern "C" fn notify_playing_trampoline<F: Fn(&Svg) + 'static>(
511            this: *mut ffi::GtkSvg,
512            _param_spec: glib::ffi::gpointer,
513            f: glib::ffi::gpointer,
514        ) {
515            let f: &F = &*(f as *const F);
516            f(&from_glib_borrow(this))
517        }
518        unsafe {
519            let f: Box_<F> = Box_::new(f);
520            connect_raw(
521                self.as_ptr() as *mut _,
522                c"notify::playing".as_ptr() as *const _,
523                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
524                    notify_playing_trampoline::<F> as *const (),
525                )),
526                Box_::into_raw(f),
527            )
528        }
529    }
530
531    #[cfg(feature = "v4_22")]
532    #[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
533    #[doc(alias = "state")]
534    pub fn connect_state_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
535        unsafe extern "C" fn notify_state_trampoline<F: Fn(&Svg) + 'static>(
536            this: *mut ffi::GtkSvg,
537            _param_spec: glib::ffi::gpointer,
538            f: glib::ffi::gpointer,
539        ) {
540            let f: &F = &*(f as *const F);
541            f(&from_glib_borrow(this))
542        }
543        unsafe {
544            let f: Box_<F> = Box_::new(f);
545            connect_raw(
546                self.as_ptr() as *mut _,
547                c"notify::state".as_ptr() as *const _,
548                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
549                    notify_state_trampoline::<F> as *const (),
550                )),
551                Box_::into_raw(f),
552            )
553        }
554    }
555
556    #[cfg(feature = "v4_22")]
557    #[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
558    #[doc(alias = "weight")]
559    pub fn connect_weight_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
560        unsafe extern "C" fn notify_weight_trampoline<F: Fn(&Svg) + 'static>(
561            this: *mut ffi::GtkSvg,
562            _param_spec: glib::ffi::gpointer,
563            f: glib::ffi::gpointer,
564        ) {
565            let f: &F = &*(f as *const F);
566            f(&from_glib_borrow(this))
567        }
568        unsafe {
569            let f: Box_<F> = Box_::new(f);
570            connect_raw(
571                self.as_ptr() as *mut _,
572                c"notify::weight".as_ptr() as *const _,
573                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
574                    notify_weight_trampoline::<F> as *const (),
575                )),
576                Box_::into_raw(f),
577            )
578        }
579    }
580}
581
582#[cfg(feature = "v4_22")]
583#[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
584impl Default for Svg {
585    fn default() -> Self {
586        Self::new()
587    }
588}