editor: Implement drag and drop where it makes sense

This commit is contained in:
Elias Projahn 2025-03-01 15:52:59 +01:00
parent a13e406e99
commit e47b7c2006
31 changed files with 888 additions and 87 deletions

View file

@ -1,12 +1,15 @@
use std::cell::{OnceCell, RefCell};
use adw::{prelude::*, subclass::prelude::*};
use gtk::glib::{self, clone, subclass::Signal, Properties};
use gtk::{
gdk,
glib::{self, clone, subclass::Signal, Properties},
};
use once_cell::sync::Lazy;
use crate::{
db::models::EnsemblePerformer, editor::role::RoleEditor, library::Library,
selector::role::RoleSelectorPopover,
selector::role::RoleSelectorPopover, util::drag_widget::DragWidget,
};
mod imp {
@ -50,8 +53,14 @@ mod imp {
#[glib::derived_properties]
impl ObjectImpl for RecordingEditorEnsembleRow {
fn signals() -> &'static [Signal] {
static SIGNALS: Lazy<Vec<Signal>> =
Lazy::new(|| vec![Signal::builder("remove").build()]);
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
vec![
Signal::builder("remove").build(),
Signal::builder("move")
.param_types([super::RecordingEditorEnsembleRow::static_type()])
.build(),
]
});
SIGNALS.as_ref()
}
@ -59,6 +68,44 @@ mod imp {
fn constructed(&self) {
self.parent_constructed();
let drag_source = gtk::DragSource::builder()
.actions(gdk::DragAction::MOVE)
.content(&gdk::ContentProvider::for_value(&self.obj().to_value()))
.build();
drag_source.connect_drag_begin(clone!(
#[weak(rename_to = obj)]
self.obj(),
move |_, drag| {
let icon = gtk::DragIcon::for_drag(drag);
icon.set_child(Some(&DragWidget::new(&obj)));
}
));
self.obj().add_controller(drag_source);
let drop_target = gtk::DropTarget::builder()
.actions(gdk::DragAction::MOVE)
.build();
drop_target.set_types(&[Self::Type::static_type()]);
drop_target.connect_drop(clone!(
#[weak(rename_to = obj)]
self.obj(),
#[upgrade_or]
false,
move |_, value, _, _| {
if let Ok(row) = value.get::<Self::Type>() {
obj.emit_by_name::<()>("move", &[&row]);
true
} else {
false
}
}
));
self.obj().add_controller(drop_target);
let role_popover = RoleSelectorPopover::new(self.library.get().unwrap());
let obj = self.obj().to_owned();
@ -118,6 +165,15 @@ impl RecordingEditorEnsembleRow {
obj
}
pub fn connect_move<F: Fn(&Self, Self) + 'static>(&self, f: F) -> glib::SignalHandlerId {
self.connect_local("move", true, move |values| {
let obj = values[0].get::<Self>().unwrap();
let source = values[1].get::<Self>().unwrap();
f(&obj, source);
None
})
}
pub fn connect_remove<F: Fn(&Self) + 'static>(&self, f: F) -> glib::SignalHandlerId {
self.connect_local("remove", true, move |values| {
let obj = values[0].get::<Self>().unwrap();