From 4e326c8859d7e6f5a8956f282aad4b846f4f9892 Mon Sep 17 00:00:00 2001 From: Diederik ter Rahe Date: Fri, 13 Sep 2024 11:58:34 -0400 Subject: [PATCH] scroll module during d&d even if not valid move --- src/develop/imageop.c | 20 ++++++++++++-------- src/dtgtk/expander.c | 20 ++++++++++++-------- src/dtgtk/expander.h | 2 +- src/gui/gtk.c | 2 +- src/libs/lib.c | 13 +++++++------ 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/develop/imageop.c b/src/develop/imageop.c index 21f79e27ef66..2d6eac372e4c 100644 --- a/src/develop/imageop.c +++ b/src/develop/imageop.c @@ -2975,13 +2975,15 @@ GtkWidget *dt_iop_gui_header_button(dt_iop_module_t *module, static gboolean _on_drag_motion(GtkWidget *widget, GdkDragContext *dc, gint x, gint y, guint time, dt_iop_module_t *dest) { gdk_drag_status(dc, 0, time); + dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), FALSE, TRUE, time); - GtkWidget *src_widget = gtk_widget_get_ancestor(gtk_drag_get_source_widget(dc), - DTGTK_TYPE_EXPANDER); + GtkWidget *src_header = gtk_drag_get_source_widget(dc); + if(!src_header) return TRUE; + GtkWidget *src_expander = gtk_widget_get_ancestor(src_header, DTGTK_TYPE_EXPANDER); dt_iop_module_t *src = NULL; for(GList *iop = darktable.develop->iop; iop; iop = iop->next) - if(((dt_iop_module_t *)iop->data)->expander == src_widget) + if(((dt_iop_module_t *)iop->data)->expander == src_expander) src = iop->data; if(!src || dest == src) return TRUE; @@ -3001,11 +3003,13 @@ static gboolean _on_drag_motion(GtkWidget *widget, GdkDragContext *dc, gint x, g if(x != DND_DROP) { - gboolean allow = src->iop_order < dest->iop_order - ? dt_ioppr_check_can_move_after_iop(darktable.develop->iop, src, dest) - : dt_ioppr_check_can_move_before_iop(darktable.develop->iop, src, dest); - dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), allow, !above); - if(allow) gdk_drag_status(dc, GDK_ACTION_COPY, time); + if(src->iop_order < dest->iop_order + ? dt_ioppr_check_can_move_after_iop(darktable.develop->iop, src, dest) + : dt_ioppr_check_can_move_before_iop(darktable.develop->iop, src, dest)) + { + dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), TRUE, !above, time); + gdk_drag_status(dc, GDK_ACTION_COPY, time); + } } else { diff --git a/src/dtgtk/expander.c b/src/dtgtk/expander.c index 894aab5a1dcf..cd2f555c8d63 100644 --- a/src/dtgtk/expander.c +++ b/src/dtgtk/expander.c @@ -183,23 +183,25 @@ static void _expander_resize(GtkWidget *widget, GdkRectangle *allocation, gpoint + dt_conf_get_int("darkroom/ui/transition_duration") * 1000), NULL); } -void dtgtk_expander_set_drag_hover(GtkDarktableExpander *expander, gboolean hover, gboolean below) +void dtgtk_expander_set_drag_hover(GtkDarktableExpander *expander, gboolean allow, gboolean below, guint time) { GtkWidget *widget = expander ? GTK_WIDGET(expander) : _drop_widget; // don't remove drop zone when switching between last expander and empty space to avoid jitter - static guint hovertime; - guint time = gtk_get_current_event_time(); - if(!widget || (!hover && widget == _drop_widget && time == hovertime)) return; + static guint last_time; + if(!widget || (!allow && !below && widget == _drop_widget && time == last_time)) return; dt_gui_remove_class(widget, "module_drop_after"); dt_gui_remove_class(widget, "module_drop_before"); - if(hover) + if(allow || below) { _drop_widget = widget; - hovertime = time; + _last_expanded = NULL; + last_time = time; - if(below) + if(!allow) + gtk_widget_queue_resize(widget); + else if(below) dt_gui_add_class(widget, "module_drop_before"); else dt_gui_add_class(widget, "module_drop_after"); @@ -211,7 +213,7 @@ static void _expander_drag_leave(GtkDarktableExpander *widget, guint time, gpointer user_data) { - dtgtk_expander_set_drag_hover(widget, FALSE, FALSE); + dtgtk_expander_set_drag_hover(widget, FALSE, FALSE, time); } // FIXME: default highlight for the dnd is barely visible @@ -226,6 +228,7 @@ static void _expander_drag_begin(GtkWidget *widget, GdkDragContext *context, gpo // hack to render not transparent dt_gui_add_class(widget, "module_drag_icon"); + gtk_widget_size_allocate(widget, &allocation); gtk_widget_draw(widget, cr); dt_gui_remove_class(widget, "module_drag_icon"); @@ -244,6 +247,7 @@ static void _expander_drag_begin(GtkWidget *widget, GdkDragContext *context, gpo static void _expander_drag_end(GtkWidget *widget, GdkDragContext *context, gpointer user_data) { + dtgtk_expander_set_drag_hover(NULL, FALSE, FALSE, 0); _drop_widget = NULL; gtk_widget_set_opacity(widget, 1.0); } diff --git a/src/dtgtk/expander.h b/src/dtgtk/expander.h index d09cc4ed1ba6..f52eb4c609a5 100644 --- a/src/dtgtk/expander.h +++ b/src/dtgtk/expander.h @@ -45,7 +45,7 @@ GtkWidget *dtgtk_expander_get_body_event_box(GtkDarktableExpander *expander); void dtgtk_expander_set_expanded(GtkDarktableExpander *expander, gboolean expanded); gboolean dtgtk_expander_get_expanded(GtkDarktableExpander *expander); -void dtgtk_expander_set_drag_hover(GtkDarktableExpander *expander, gboolean hover, gboolean below); +void dtgtk_expander_set_drag_hover(GtkDarktableExpander *expander, gboolean allow, gboolean below, guint time); GtkWidget *dtgtk_expander_new(GtkWidget *header, GtkWidget *body); diff --git a/src/gui/gtk.c b/src/gui/gtk.c index a7c910e21316..1f8897149cab 100644 --- a/src/gui/gtk.c +++ b/src/gui/gtk.c @@ -2248,7 +2248,7 @@ static gboolean _on_drag_motion_drop(GtkWidget *empty, GdkDragContext *dc, gint static void _on_drag_leave(GtkWidget *widget, GdkDragContext *dc, guint time, gpointer user_data) { - dtgtk_expander_set_drag_hover(NULL, FALSE, FALSE); + dtgtk_expander_set_drag_hover(NULL, FALSE, FALSE, time); } static gboolean _remove_modules_visibility(gpointer key, diff --git a/src/libs/lib.c b/src/libs/lib.c index 558befa9c0ad..099a02251a6b 100644 --- a/src/libs/lib.c +++ b/src/libs/lib.c @@ -1098,17 +1098,18 @@ static gboolean _on_drag_motion(GtkWidget *widget, } else { - dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), FALSE, FALSE); + dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), FALSE, TRUE, time); gdk_drag_status(dc, 0, time); - GtkWidget *src_widget = gtk_widget_get_ancestor(gtk_drag_get_source_widget(dc), - DTGTK_TYPE_EXPANDER); + GtkWidget *src_header = gtk_drag_get_source_widget(dc); + if(!src_header) return TRUE; + GtkWidget *src_expander = gtk_widget_get_ancestor(src_header, DTGTK_TYPE_EXPANDER); for(GList *lib = darktable.lib->plugins; lib; lib = lib->next) - if(((dt_lib_module_t *)lib->data)->expander == src_widget) + if(((dt_lib_module_t *)lib->data)->expander == src_expander) src = lib->data; - if(!src_widget || !src || dest == src ) return TRUE; + if(!src_expander || !src || dest == src ) return TRUE; src_panel = GTK_CONTAINER(gtk_widget_get_parent(src->expander)); dest_panel = GTK_CONTAINER(gtk_widget_get_parent(dest->expander)); @@ -1132,7 +1133,7 @@ static gboolean _on_drag_motion(GtkWidget *widget, if(x != DND_DROP) { - dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), TRUE, below); + dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), TRUE, below, time); gdk_drag_status(dc, GDK_ACTION_COPY, time); return TRUE;