2017-07-14 15:23:42 +00:00
|
|
|
//! Helper functions for the UI, mostly pixbuf functions.
|
|
|
|
|
|
|
|
|
2017-06-26 07:08:37 +00:00
|
|
|
use errors::*;
|
|
|
|
use gdk_pixbuf;
|
|
|
|
use gdk_pixbuf_sys;
|
|
|
|
use glib::translate::FromGlibPtrFull;
|
|
|
|
use glib::translate::ToGlibPtr;
|
|
|
|
use gtk::prelude::*;
|
|
|
|
use gtk;
|
|
|
|
use std::path::*;
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-07-14 15:23:42 +00:00
|
|
|
/// Copy a `Pixbuf` explicitly, since they don't implement the `Copy` trait.
|
|
|
|
/// Currently does not call `gdk_pixbuf_copy_options()`.
|
2017-06-26 07:08:37 +00:00
|
|
|
pub fn copy_pixbuf(pixbuf: &gdk_pixbuf::Pixbuf) -> gdk_pixbuf::Pixbuf {
|
|
|
|
|
|
|
|
let new_pixbuf = unsafe {
|
|
|
|
let gdk_pixbuf = pixbuf.to_glib_full();
|
|
|
|
let copy = gdk_pixbuf_sys::gdk_pixbuf_copy(gdk_pixbuf);
|
|
|
|
FromGlibPtrFull::from_glib_full(copy)
|
|
|
|
};
|
|
|
|
|
|
|
|
return new_pixbuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-14 15:23:42 +00:00
|
|
|
/// Get a pixbuf by name from the given theme with the requested size.
|
|
|
|
/// Note that the size is not enforced, but rather a hint.
|
2017-06-26 07:08:37 +00:00
|
|
|
pub fn pixbuf_new_from_theme(icon_name: &str,
|
|
|
|
size: i32,
|
|
|
|
theme: >k::IconTheme)
|
|
|
|
-> Result<gdk_pixbuf::Pixbuf> {
|
|
|
|
|
|
|
|
let icon_info =
|
|
|
|
theme.lookup_icon(icon_name, size, gtk::IconLookupFlags::empty())
|
|
|
|
.ok_or(format!("Couldn't find icon {}", icon_name))?;
|
|
|
|
|
|
|
|
debug!("Loading stock icon {} from {:?}",
|
|
|
|
icon_name,
|
|
|
|
icon_info.get_filename().unwrap_or(PathBuf::new()));
|
|
|
|
|
|
|
|
// TODO: propagate error
|
|
|
|
let pixbuf = icon_info.load_icon().unwrap();
|
|
|
|
|
|
|
|
return Ok(pixbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[macro_export]
|
2017-07-14 15:23:42 +00:00
|
|
|
/// Create a pixbuf from the given PNG file. Includes the file as bytes
|
|
|
|
/// in the binary and decodes it.
|
2017-07-14 23:19:27 +00:00
|
|
|
macro_rules! pixbuf_new_from_png {
|
2017-07-13 15:46:49 +00:00
|
|
|
($name:expr) => {
|
2017-06-26 07:08:37 +00:00
|
|
|
{
|
2017-07-13 15:46:49 +00:00
|
|
|
use gdk_pixbuf;
|
|
|
|
use png;
|
|
|
|
|
|
|
|
let bytes = include_bytes!($name);
|
|
|
|
let pixbuf_new_from_bytes = |bytes| -> Result<gdk_pixbuf::Pixbuf> {
|
|
|
|
let decoder = png::Decoder::new(bytes);
|
|
|
|
let (info, mut reader) = decoder.read_info()?;
|
|
|
|
let mut buf = vec![0; info.buffer_size()];
|
|
|
|
reader.next_frame(&mut buf).unwrap();
|
|
|
|
|
|
|
|
ensure!(info.color_type == png::ColorType::RGB ||
|
|
|
|
info.color_type == png::ColorType::RGBA,
|
|
|
|
"Only RGB is supported for GDKPixbuf");
|
|
|
|
|
|
|
|
debug!("Loading icon from {}", $name);
|
|
|
|
|
|
|
|
return Ok(gdk_pixbuf::Pixbuf::new_from_vec(buf,
|
|
|
|
gdk_pixbuf_sys::GDK_COLORSPACE_RGB,
|
|
|
|
true,
|
|
|
|
info.bit_depth as i32,
|
|
|
|
info.width as i32,
|
|
|
|
info.height as i32,
|
|
|
|
info.line_size as i32));
|
|
|
|
};
|
|
|
|
pixbuf_new_from_bytes(bytes as &[u8])
|
2017-06-26 07:08:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|