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}