gdk_pixbuf/pixbuf_animation_iter.rs
1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::time::{Duration, SystemTime};
4
5use glib::translate::*;
6
7use super::{ffi, Pixbuf};
8
9glib::wrapper! {
10 /// Use a different image loading library for animatable assets
11 /// An opaque object representing an iterator which points to a
12 /// certain position in an animation.
13 #[doc(alias = "GdkPixbufAnimationIter")]
14 pub struct PixbufAnimationIter(Object<ffi::GdkPixbufAnimationIter, ffi::GdkPixbufAnimationIterClass>);
15
16 match fn {
17 type_ => || ffi::gdk_pixbuf_animation_iter_get_type(),
18 }
19}
20
21impl PixbufAnimationIter {
22 /// Possibly advances an animation to a new frame.
23 ///
24 /// Chooses the frame based on the start time passed to
25 /// gdk_pixbuf_animation_get_iter().
26 ///
27 /// @current_time would normally come from g_get_current_time(), and
28 /// must be greater than or equal to the time passed to
29 /// gdk_pixbuf_animation_get_iter(), and must increase or remain
30 /// unchanged each time gdk_pixbuf_animation_iter_get_pixbuf() is
31 /// called. That is, you can't go backward in time; animations only
32 /// play forward.
33 ///
34 /// As a shortcut, pass `NULL` for the current time and g_get_current_time()
35 /// will be invoked on your behalf. So you only need to explicitly pass
36 /// @current_time if you're doing something odd like playing the animation
37 /// at double speed.
38 ///
39 /// If this function returns `FALSE`, there's no need to update the animation
40 /// display, assuming the display had been rendered prior to advancing;
41 /// if `TRUE`, you need to call gdk_pixbuf_animation_iter_get_pixbuf()
42 /// and update the display with the new pixbuf.
43 ///
44 /// # Deprecated since 2.44
45 ///
46 /// Use a different image loading library for animatable assets
47 /// ## `current_time`
48 /// current time
49 ///
50 /// # Returns
51 ///
52 /// `TRUE` if the image may need updating
53 #[doc(alias = "gdk_pixbuf_animation_iter_advance")]
54 pub fn advance(&self, current_time: SystemTime) -> bool {
55 let diff = current_time
56 .duration_since(SystemTime::UNIX_EPOCH)
57 .expect("failed to convert time");
58
59 unsafe {
60 from_glib(ffi::gdk_pixbuf_animation_iter_advance(
61 self.to_glib_none().0,
62 &glib::ffi::GTimeVal {
63 tv_sec: diff.as_secs() as _,
64 tv_usec: diff.subsec_micros() as _,
65 },
66 ))
67 }
68 }
69
70 /// Gets the current pixbuf which should be displayed.
71 ///
72 /// The pixbuf might not be the same size as the animation itself
73 /// (gdk_pixbuf_animation_get_width(), gdk_pixbuf_animation_get_height()).
74 ///
75 /// This pixbuf should be displayed for gdk_pixbuf_animation_iter_get_delay_time()
76 /// milliseconds.
77 ///
78 /// The caller of this function does not own a reference to the returned
79 /// pixbuf; the returned pixbuf will become invalid when the iterator
80 /// advances to the next frame, which may happen anytime you call
81 /// gdk_pixbuf_animation_iter_advance().
82 ///
83 /// Copy the pixbuf to keep it (don't just add a reference), as it may get
84 /// recycled as you advance the iterator.
85 ///
86 /// # Deprecated since 2.44
87 ///
88 /// Use a different image loading library for animatable assets
89 ///
90 /// # Returns
91 ///
92 /// the pixbuf to be displayed
93 #[doc(alias = "gdk_pixbuf_animation_iter_get_pixbuf")]
94 #[doc(alias = "get_pixbuf")]
95 pub fn pixbuf(&self) -> Pixbuf {
96 unsafe {
97 from_glib_none(ffi::gdk_pixbuf_animation_iter_get_pixbuf(
98 self.to_glib_none().0,
99 ))
100 }
101 }
102
103 /// Gets the number of milliseconds the current pixbuf should be displayed,
104 /// or -1 if the current pixbuf should be displayed forever.
105 ///
106 /// The `g_timeout_add()` function conveniently takes a timeout in milliseconds,
107 /// so you can use a timeout to schedule the next update.
108 ///
109 /// Note that some formats, like GIF, might clamp the timeout values in the
110 /// image file to avoid updates that are just too quick. The minimum timeout
111 /// for GIF images is currently 20 milliseconds.
112 ///
113 /// # Deprecated since 2.44
114 ///
115 /// Use a different image loading library for animatable assets
116 ///
117 /// # Returns
118 ///
119 /// delay time in milliseconds (thousandths of a second)
120 #[doc(alias = "gdk_pixbuf_animation_iter_get_delay_time")]
121 #[doc(alias = "get_delay_time")]
122 pub fn delay_time(&self) -> Option<Duration> {
123 unsafe {
124 let res = ffi::gdk_pixbuf_animation_iter_get_delay_time(self.to_glib_none().0);
125
126 if res < 0 {
127 None
128 } else {
129 Some(Duration::from_millis(res as u64))
130 }
131 }
132 }
133
134 /// Used to determine how to respond to the area_updated signal on
135 /// #GdkPixbufLoader when loading an animation.
136 ///
137 /// The `::area_updated` signal is emitted for an area of the frame currently
138 /// streaming in to the loader. So if you're on the currently loading frame,
139 /// you will need to redraw the screen for the updated area.
140 ///
141 /// # Deprecated since 2.44
142 ///
143 /// Use a different image loading library for animatable assets
144 ///
145 /// # Returns
146 ///
147 /// `TRUE` if the frame we're on is partially loaded, or the last frame
148 #[doc(alias = "gdk_pixbuf_animation_iter_on_currently_loading_frame")]
149 pub fn on_currently_loading_frame(&self) -> bool {
150 unsafe {
151 from_glib(ffi::gdk_pixbuf_animation_iter_on_currently_loading_frame(
152 self.to_glib_none().0,
153 ))
154 }
155 }
156}