Implement drag source on images

Using a 128x128 thumbnail.
This commit is contained in:
Maximiliano Sandoval R 2022-01-08 16:21:27 +01:00 • committed by Christopher Davis
parent fc6d3668c0
commit 13d7a21501
5 changed files with 135 additions and 0 deletions

90
src/thumbnail.rs Normal file
View file

@ -0,0 +1,90 @@
use gtk::prelude::*;
use gtk::subclass::prelude::*;
use gtk::{gdk, glib};
mod imp {
use super::*;
use once_cell::sync::OnceCell;
const SIZE: i32 = 128;
#[derive(Debug, Default)]
pub struct Thumbnail {
pub image: OnceCell<gdk::Paintable>,
}
#[glib::object_subclass]
impl ObjectSubclass for Thumbnail {
const NAME: &'static str = "Thumbnail";
type Type = super::Thumbnail;
type ParentType = glib::Object;
type Interfaces = (gdk::Paintable,);
}
impl ObjectImpl for Thumbnail {}
impl PaintableImpl for Thumbnail {
fn intrinsic_height(&self, _paintable: &Self::Type) -> i32 {
let image = self.image.get().unwrap();
let width = image.intrinsic_width();
let height = image.intrinsic_height();
let aspect_ratio = width as f64 / (height as f64).max(std::f64::EPSILON);
if width >= height {
(SIZE as f64 / aspect_ratio) as i32
} else {
SIZE
}
}
fn intrinsic_width(&self, _paintable: &Self::Type) -> i32 {
let image = self.image.get().unwrap();
let width = image.intrinsic_width();
let height = image.intrinsic_height();
let aspect_ratio = width as f64 / (height as f64).max(std::f64::EPSILON);
if width >= height {
SIZE
} else {
(SIZE as f64 * aspect_ratio) as i32
}
}
fn intrinsic_aspect_ratio(&self, _paintable: &Self::Type) -> f64 {
self.image.get().unwrap().intrinsic_aspect_ratio()
}
fn snapshot(
&self,
paintable: &Self::Type,
snapshot: &gdk::Snapshot,
_width: f64,
_height: f64,
) {
let width = paintable.intrinsic_width() as f64;
let height = paintable.intrinsic_height() as f64;
self.image.get().unwrap().snapshot(snapshot, width, height);
}
}
}
glib::wrapper! {
/// Thumbnail Paintable
///
/// Creates a thumbnail from another paintable. The thumbnail will be drawn
/// at a maximum size of 128 × 128 taking into account the original
/// paintable aspect ratio.
pub struct Thumbnail(ObjectSubclass<imp::Thumbnail>) @implements gdk::Paintable;
}
impl Thumbnail {
pub fn new(paintable: &impl glib::IsA<gdk::Paintable>) -> Self {
let object = glib::Object::new::<Self>(&[]).unwrap();
let imp = object.imp();
imp.image.set(paintable.clone().upcast()).unwrap();
object
}
}