-
-
Notifications
You must be signed in to change notification settings - Fork 118
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #837 from sdroege/0.16-backports
0.16 backports
- Loading branch information
Showing
10 changed files
with
520 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Take a look at the license at the top of the repository in the LICENSE file. | ||
|
||
// rustdoc-stripper-ignore-next | ||
//! Traits intended for creating custom types. | ||
pub mod pixbuf_animation; | ||
pub mod pixbuf_animation_iter; | ||
pub mod pixbuf_loader; | ||
|
||
pub mod prelude { | ||
pub use gio::subclass::prelude::*; | ||
pub use glib::subclass::prelude::*; | ||
|
||
pub use super::pixbuf_animation::{PixbufAnimationImpl, PixbufAnimationImplExt}; | ||
pub use super::pixbuf_animation_iter::{PixbufAnimationIterImpl, PixbufAnimationIterImplExt}; | ||
pub use super::pixbuf_loader::{PixbufLoaderImpl, PixbufLoaderImplExt}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
// Take a look at the license at the top of the repository in the LICENSE file. | ||
|
||
// rustdoc-stripper-ignore-next | ||
//! Traits intended for subclassing [`PixbufAnimation`](crate::PixbufAnimation). | ||
use std::mem::MaybeUninit; | ||
use std::time::Duration; | ||
|
||
use crate::{Pixbuf, PixbufAnimation, PixbufAnimationIter}; | ||
use glib::subclass::prelude::*; | ||
use glib::translate::*; | ||
use glib::Cast; | ||
|
||
pub trait PixbufAnimationImpl: ObjectImpl { | ||
fn is_static_image(&self) -> bool { | ||
self.parent_is_static_image() | ||
} | ||
|
||
fn static_image(&self) -> Option<Pixbuf> { | ||
self.parent_static_image() | ||
} | ||
|
||
fn size(&self) -> (i32, i32) { | ||
self.parent_size() | ||
} | ||
|
||
fn iter(&self, start_time: Duration) -> PixbufAnimationIter { | ||
self.parent_iter(start_time) | ||
} | ||
} | ||
|
||
pub trait PixbufAnimationImplExt: ObjectSubclass { | ||
fn parent_is_static_image(&self) -> bool; | ||
fn parent_static_image(&self) -> Option<Pixbuf>; | ||
fn parent_size(&self) -> (i32, i32); | ||
fn parent_iter(&self, start_time: Duration) -> PixbufAnimationIter; | ||
} | ||
|
||
impl<T: PixbufAnimationImpl> PixbufAnimationImplExt for T { | ||
fn parent_is_static_image(&self) -> bool { | ||
unsafe { | ||
let data = T::type_data(); | ||
let parent_class = data.as_ref().parent_class() as *mut ffi::GdkPixbufAnimationClass; | ||
let f = (*parent_class) | ||
.is_static_image | ||
.expect("No parent class implementation for \"is_static_image\""); | ||
|
||
from_glib(f(self | ||
.obj() | ||
.unsafe_cast_ref::<PixbufAnimation>() | ||
.to_glib_none() | ||
.0)) | ||
} | ||
} | ||
|
||
fn parent_static_image(&self) -> Option<Pixbuf> { | ||
unsafe { | ||
let data = T::type_data(); | ||
let parent_class = data.as_ref().parent_class() as *mut ffi::GdkPixbufAnimationClass; | ||
let f = (*parent_class) | ||
.get_static_image | ||
.expect("No parent class implementation for \"get_static_image\""); | ||
|
||
from_glib_none(f(self | ||
.obj() | ||
.unsafe_cast_ref::<PixbufAnimation>() | ||
.to_glib_none() | ||
.0)) | ||
} | ||
} | ||
|
||
fn parent_size(&self) -> (i32, i32) { | ||
unsafe { | ||
let data = T::type_data(); | ||
let parent_class = data.as_ref().parent_class() as *mut ffi::GdkPixbufAnimationClass; | ||
let f = (*parent_class) | ||
.get_size | ||
.expect("No parent class implementation for \"get_size\""); | ||
let mut width = MaybeUninit::uninit(); | ||
let mut height = MaybeUninit::uninit(); | ||
f( | ||
self.obj() | ||
.unsafe_cast_ref::<PixbufAnimation>() | ||
.to_glib_none() | ||
.0, | ||
width.as_mut_ptr(), | ||
height.as_mut_ptr(), | ||
); | ||
(width.assume_init(), height.assume_init()) | ||
} | ||
} | ||
|
||
fn parent_iter(&self, start_time: Duration) -> PixbufAnimationIter { | ||
unsafe { | ||
let data = T::type_data(); | ||
let parent_class = data.as_ref().parent_class() as *mut ffi::GdkPixbufAnimationClass; | ||
let f = (*parent_class) | ||
.get_iter | ||
.expect("No parent class implementation for \"get_iter\""); | ||
|
||
let time = glib::ffi::GTimeVal { | ||
tv_sec: start_time.as_secs() as _, | ||
tv_usec: start_time.subsec_micros() as _, | ||
}; | ||
from_glib_full(f( | ||
self.obj() | ||
.unsafe_cast_ref::<PixbufAnimation>() | ||
.to_glib_none() | ||
.0, | ||
&time as *const _, | ||
)) | ||
} | ||
} | ||
} | ||
|
||
unsafe impl<T: PixbufAnimationImpl> IsSubclassable<T> for PixbufAnimation { | ||
fn class_init(class: &mut ::glib::Class<Self>) { | ||
Self::parent_class_init::<T>(class); | ||
|
||
let klass = class.as_mut(); | ||
klass.get_static_image = Some(animation_get_static_image::<T>); | ||
klass.get_size = Some(animation_get_size::<T>); | ||
klass.get_iter = Some(animation_get_iter::<T>); | ||
klass.is_static_image = Some(animation_is_static_image::<T>); | ||
} | ||
} | ||
|
||
unsafe extern "C" fn animation_is_static_image<T: PixbufAnimationImpl>( | ||
ptr: *mut ffi::GdkPixbufAnimation, | ||
) -> glib::ffi::gboolean { | ||
let instance = &*(ptr as *mut T::Instance); | ||
let imp = instance.imp(); | ||
|
||
imp.is_static_image().into_glib() | ||
} | ||
|
||
unsafe extern "C" fn animation_get_size<T: PixbufAnimationImpl>( | ||
ptr: *mut ffi::GdkPixbufAnimation, | ||
width_ptr: *mut libc::c_int, | ||
height_ptr: *mut libc::c_int, | ||
) { | ||
let instance = &*(ptr as *mut T::Instance); | ||
let imp = instance.imp(); | ||
|
||
let (width, height) = imp.size(); | ||
*width_ptr = width; | ||
*height_ptr = height; | ||
} | ||
|
||
unsafe extern "C" fn animation_get_static_image<T: PixbufAnimationImpl>( | ||
ptr: *mut ffi::GdkPixbufAnimation, | ||
) -> *mut ffi::GdkPixbuf { | ||
let instance = &*(ptr as *mut T::Instance); | ||
let imp = instance.imp(); | ||
|
||
imp.static_image().to_glib_none().0 | ||
} | ||
|
||
unsafe extern "C" fn animation_get_iter<T: PixbufAnimationImpl>( | ||
ptr: *mut ffi::GdkPixbufAnimation, | ||
start_time_ptr: *const glib::ffi::GTimeVal, | ||
) -> *mut ffi::GdkPixbufAnimationIter { | ||
let instance = &*(ptr as *mut T::Instance); | ||
let imp = instance.imp(); | ||
|
||
let total = Duration::from_secs((*start_time_ptr).tv_sec.try_into().unwrap()) | ||
+ Duration::from_micros((*start_time_ptr).tv_usec.try_into().unwrap()); | ||
|
||
imp.iter(total).to_glib_full() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
// Take a look at the license at the top of the repository in the LICENSE file. | ||
|
||
// rustdoc-stripper-ignore-next | ||
//! Traits intended for subclassing [`PixbufAnimationIter`](crate::PixbufAnimationIter). | ||
use std::time::Duration; | ||
|
||
use glib::subclass::prelude::*; | ||
use glib::translate::*; | ||
use glib::Cast; | ||
|
||
use crate::{Pixbuf, PixbufAnimationIter}; | ||
|
||
pub trait PixbufAnimationIterImpl: ObjectImpl { | ||
// rustdoc-stripper-ignore-next | ||
/// Time in milliseconds, returning `None` implies showing the same pixbuf forever. | ||
fn delay_time(&self) -> Option<Duration> { | ||
self.parent_delay_time() | ||
} | ||
|
||
fn pixbuf(&self) -> Pixbuf { | ||
self.parent_pixbuf() | ||
} | ||
|
||
fn on_currently_loading_frame(&self) -> bool { | ||
self.parent_on_currently_loading_frame() | ||
} | ||
|
||
fn advance(&self, time: Duration) -> bool { | ||
self.parent_advance(time) | ||
} | ||
} | ||
|
||
pub trait PixbufAnimationIterImplExt: ObjectSubclass { | ||
fn parent_delay_time(&self) -> Option<Duration>; | ||
fn parent_pixbuf(&self) -> Pixbuf; | ||
fn parent_on_currently_loading_frame(&self) -> bool; | ||
fn parent_advance(&self, time: Duration) -> bool; | ||
} | ||
|
||
impl<T: PixbufAnimationIterImpl> PixbufAnimationIterImplExt for T { | ||
fn parent_delay_time(&self) -> Option<Duration> { | ||
unsafe { | ||
let data = T::type_data(); | ||
let parent_class = | ||
data.as_ref().parent_class() as *mut ffi::GdkPixbufAnimationIterClass; | ||
let f = (*parent_class) | ||
.get_delay_time | ||
.expect("No parent class implementation for \"get_delay_time\""); | ||
|
||
let time = f(self | ||
.obj() | ||
.unsafe_cast_ref::<PixbufAnimationIter>() | ||
.to_glib_none() | ||
.0); | ||
if time == -1 { | ||
None | ||
} else { | ||
Some(Duration::from_millis(time.try_into().unwrap())) | ||
} | ||
} | ||
} | ||
|
||
fn parent_pixbuf(&self) -> Pixbuf { | ||
unsafe { | ||
let data = T::type_data(); | ||
let parent_class = | ||
data.as_ref().parent_class() as *mut ffi::GdkPixbufAnimationIterClass; | ||
let f = (*parent_class) | ||
.get_pixbuf | ||
.expect("No parent class implementation for \"get_pixbuf\""); | ||
|
||
from_glib_none(f(self | ||
.obj() | ||
.unsafe_cast_ref::<PixbufAnimationIter>() | ||
.to_glib_none() | ||
.0)) | ||
} | ||
} | ||
|
||
fn parent_on_currently_loading_frame(&self) -> bool { | ||
unsafe { | ||
let data = T::type_data(); | ||
let parent_class = | ||
data.as_ref().parent_class() as *mut ffi::GdkPixbufAnimationIterClass; | ||
let f = (*parent_class) | ||
.on_currently_loading_frame | ||
.expect("No parent class implementation for \"on_currently_loading_frame\""); | ||
|
||
from_glib(f(self | ||
.obj() | ||
.unsafe_cast_ref::<PixbufAnimationIter>() | ||
.to_glib_none() | ||
.0)) | ||
} | ||
} | ||
|
||
fn parent_advance(&self, time: Duration) -> bool { | ||
unsafe { | ||
let data = T::type_data(); | ||
let parent_class = | ||
data.as_ref().parent_class() as *mut ffi::GdkPixbufAnimationIterClass; | ||
let f = (*parent_class) | ||
.advance | ||
.expect("No parent class implementation for \"advance\""); | ||
|
||
let time = glib::ffi::GTimeVal { | ||
tv_sec: time.as_secs() as _, | ||
tv_usec: time.subsec_micros() as _, | ||
}; | ||
from_glib(f( | ||
self.obj() | ||
.unsafe_cast_ref::<PixbufAnimationIter>() | ||
.to_glib_none() | ||
.0, | ||
&time as *const _, | ||
)) | ||
} | ||
} | ||
} | ||
|
||
unsafe impl<T: PixbufAnimationIterImpl> IsSubclassable<T> for PixbufAnimationIter { | ||
fn class_init(class: &mut ::glib::Class<Self>) { | ||
Self::parent_class_init::<T>(class); | ||
|
||
let klass = class.as_mut(); | ||
klass.get_delay_time = Some(animation_iter_get_delay_time::<T>); | ||
klass.get_pixbuf = Some(animation_iter_get_pixbuf::<T>); | ||
klass.on_currently_loading_frame = Some(animation_iter_on_currently_loading_frame::<T>); | ||
klass.advance = Some(animation_iter_advance::<T>); | ||
} | ||
} | ||
|
||
unsafe extern "C" fn animation_iter_get_delay_time<T: PixbufAnimationIterImpl>( | ||
ptr: *mut ffi::GdkPixbufAnimationIter, | ||
) -> i32 { | ||
let instance = &*(ptr as *mut T::Instance); | ||
let imp = instance.imp(); | ||
|
||
imp.delay_time().map(|t| t.as_millis() as i32).unwrap_or(-1) | ||
} | ||
|
||
unsafe extern "C" fn animation_iter_get_pixbuf<T: PixbufAnimationIterImpl>( | ||
ptr: *mut ffi::GdkPixbufAnimationIter, | ||
) -> *mut ffi::GdkPixbuf { | ||
let instance = &*(ptr as *mut T::Instance); | ||
let imp = instance.imp(); | ||
|
||
imp.pixbuf().to_glib_none().0 | ||
} | ||
|
||
unsafe extern "C" fn animation_iter_on_currently_loading_frame<T: PixbufAnimationIterImpl>( | ||
ptr: *mut ffi::GdkPixbufAnimationIter, | ||
) -> glib::ffi::gboolean { | ||
let instance = &*(ptr as *mut T::Instance); | ||
let imp = instance.imp(); | ||
|
||
imp.on_currently_loading_frame().into_glib() | ||
} | ||
|
||
unsafe extern "C" fn animation_iter_advance<T: PixbufAnimationIterImpl>( | ||
ptr: *mut ffi::GdkPixbufAnimationIter, | ||
time_ptr: *const glib::ffi::GTimeVal, | ||
) -> glib::ffi::gboolean { | ||
let instance = &*(ptr as *mut T::Instance); | ||
let imp = instance.imp(); | ||
|
||
let total = Duration::from_secs((*time_ptr).tv_sec.try_into().unwrap()) | ||
+ Duration::from_micros((*time_ptr).tv_usec.try_into().unwrap()); | ||
|
||
imp.advance(total).into_glib() | ||
} |
Oops, something went wrong.