diff --git a/src/dtgtk/thumbnail.c b/src/dtgtk/thumbnail.c index f941b34b7f14..6b447a6746b3 100644 --- a/src/dtgtk/thumbnail.c +++ b/src/dtgtk/thumbnail.c @@ -941,57 +941,13 @@ static gboolean _event_main_motion(GtkWidget *widget, return FALSE; } -static gboolean _event_main_press(GtkWidget *widget, - GdkEventButton *event, - gpointer user_data) -{ - dt_thumbnail_t *thumb = (dt_thumbnail_t *)user_data; - if(event->button == 1 - && ((event->type == GDK_2BUTTON_PRESS && !thumb->single_click) - || (event->type == GDK_BUTTON_PRESS - && dt_modifier_is(event->state, 0) && thumb->single_click))) - { - dt_control_set_mouse_over_id(thumb->imgid); - // to ensure we haven't lost imgid during double-click - } - return FALSE; -} -static gboolean _event_main_release(GtkWidget *widget, - GdkEventButton *event, - gpointer user_data) -{ - dt_thumbnail_t *thumb = (dt_thumbnail_t *)user_data; - - if(event->button == 1 - && !thumb->moved - && thumb->sel_mode != DT_THUMBNAIL_SEL_MODE_DISABLED) - { - if(dt_modifier_is(event->state, 0) - && thumb->sel_mode != DT_THUMBNAIL_SEL_MODE_MOD_ONLY) - dt_selection_select_single(darktable.selection, thumb->imgid); - else if(dt_modifier_is(event->state, GDK_MOD1_MASK)) - { - dt_selection_select_single(darktable.selection, thumb->imgid); - } - else if(dt_modifier_is(event->state, GDK_CONTROL_MASK) - || dt_modifier_is(event->state, GDK_MOD2_MASK)) // CMD key on macOS - { - dt_selection_toggle(darktable.selection, thumb->imgid); - } - else if(dt_modifier_is(event->state, GDK_SHIFT_MASK)) - { - dt_selection_select_range(darktable.selection, thumb->imgid); - } - } - return FALSE; -} - static gboolean _event_rating_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { return TRUE; } + static gboolean _event_rating_release(GtkWidget *widget, GdkEventButton *event, gpointer user_data) @@ -1408,11 +1364,6 @@ GtkWidget *dt_thumbnail_create_widget(dt_thumbnail_t *thumb, g_signal_connect(G_OBJECT(thumb->w_main), "drag-motion", G_CALLBACK(_event_main_drag_motion), thumb); - g_signal_connect(G_OBJECT(thumb->w_main), "button-press-event", - G_CALLBACK(_event_main_press), thumb); - g_signal_connect(G_OBJECT(thumb->w_main), "button-release-event", - G_CALLBACK(_event_main_release), thumb); - g_object_set_data(G_OBJECT(thumb->w_main), "thumb", thumb); DT_DEBUG_CONTROL_SIGNAL_CONNECT(darktable.signals, DT_SIGNAL_ACTIVE_IMAGES_CHANGE, G_CALLBACK(_dt_active_images_callback), thumb); diff --git a/src/dtgtk/thumbtable.c b/src/dtgtk/thumbtable.c index 63ec73052a6b..18984800940e 100644 --- a/src/dtgtk/thumbtable.c +++ b/src/dtgtk/thumbtable.c @@ -1386,6 +1386,23 @@ static gboolean _event_enter_notify(GtkWidget *widget, return TRUE; } +static gboolean _do_select_single(gpointer user_data) +{ + dt_thumbtable_t *table = (dt_thumbtable_t *)user_data; + const dt_imgid_t id = table->to_selid; + + // always keep the edited picture selected + GList *sel = g_list_append(NULL, GINT_TO_POINTER(id)); + sel = g_list_append(sel, GINT_TO_POINTER(darktable.develop->image_storage.id)); + + dt_selection_clear(darktable.selection); + dt_selection_select_list(darktable.selection, sel); + table->sel_single_cb = 0; + g_list_free(sel); + + return FALSE; +} + static gboolean _event_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data) @@ -1396,12 +1413,45 @@ static gboolean _event_button_press(GtkWidget *widget, const dt_imgid_t id = dt_control_get_mouse_over_id(); if(dt_is_valid_imgid(id) - && event->button == 1 - && (table->mode == DT_THUMBTABLE_MODE_FILEMANAGER - || table->mode == DT_THUMBTABLE_MODE_ZOOM) - && event->type == GDK_2BUTTON_PRESS) + && event->button == 1) { - dt_view_manager_switch(darktable.view_manager, "darkroom"); + // double-click + if(event->type == GDK_2BUTTON_PRESS) + { + switch(table->mode) + { + case DT_THUMBTABLE_MODE_FILEMANAGER: + case DT_THUMBTABLE_MODE_ZOOM: + dt_view_manager_switch(darktable.view_manager, "darkroom"); + break; + + case DT_THUMBTABLE_MODE_FILMSTRIP: + if(dt_view_get_current() == DT_VIEW_DARKROOM) + { + if(table->sel_single_cb != 0) + { + g_source_remove(table->sel_single_cb); + table->sel_single_cb = 0; + } + // disable next BUTTON_RELEASE event (see _event_motion_release) + table->to_selid = -1; + // unselect currently edited picture, select new one + dt_selection_deselect(darktable.selection, + darktable.develop->image_storage.id); + dt_selection_select(darktable.selection, id); + DT_DEBUG_CONTROL_SIGNAL_RAISE(darktable.signals, + DT_SIGNAL_VIEWMANAGER_THUMBTABLE_ACTIVATE, id); + return FALSE; + } + default: + break; + } + } + + if(event->button == 1 + && event->type == GDK_BUTTON_PRESS + && table->mode == DT_THUMBTABLE_MODE_FILMSTRIP) + return FALSE; } if(event->button == 1 && event->type == GDK_BUTTON_PRESS) @@ -1424,19 +1474,6 @@ static gboolean _event_button_press(GtkWidget *widget, return TRUE; } - if(table->mode != DT_THUMBTABLE_MODE_ZOOM) - return FALSE; - - if(event->button == 1 - && event->type == GDK_BUTTON_PRESS) - { - table->dragging = TRUE; - table->drag_dx = table->drag_dy = 0; - table->drag_initial_imgid = id; - table->drag_thumb = _thumbtable_get_thumb(table, id); - if(table->drag_thumb) - table->drag_thumb->moved = FALSE; - } return TRUE; } @@ -1476,39 +1513,63 @@ static gboolean _event_button_release(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { + // we select only in LIGHTTABLE, DARKROOM & MAP mode + dt_view_type_flags_t cv = dt_view_get_current(); + if(cv != DT_VIEW_DARKROOM + && cv != DT_VIEW_LIGHTTABLE + && cv != DT_VIEW_MAP) + return FALSE; + dt_set_backthumb_time(0.0); + const dt_imgid_t id = dt_control_get_mouse_over_id(); dt_thumbtable_t *table = (dt_thumbtable_t *)user_data; - if(table->dragging == FALSE) - { - // on map view consider click release instead of press - dt_view_manager_t *vm = darktable.view_manager; - dt_view_t *view = vm->current_view; - const dt_imgid_t id = dt_control_get_mouse_over_id(); - if(dt_is_valid_imgid(id) - && event->button == 1 - && table->mode == DT_THUMBTABLE_MODE_FILMSTRIP - && event->type == GDK_BUTTON_RELEASE - && !strcmp(view->module_name, "map") - && dt_modifier_is(event->state, 0)) - { - DT_DEBUG_CONTROL_SIGNAL_RAISE(darktable.signals, - DT_SIGNAL_VIEWMANAGER_THUMBTABLE_ACTIVATE, id); - return TRUE; + if(dt_is_valid_imgid(id) + && event->button == 1 + && event->type == GDK_BUTTON_RELEASE) + { + if(dt_modifier_is(event->state, GDK_CONTROL_MASK) + || dt_modifier_is(event->state, GDK_MOD2_MASK)) // CMD key on macOS + { + dt_selection_toggle(darktable.selection, id); } - else if(dt_is_valid_imgid(id) - && event->button == 1 - && table->mode == DT_THUMBTABLE_MODE_FILMSTRIP - && event->type == GDK_BUTTON_RELEASE - && strcmp(view->module_name, "map") - && dt_modifier_is(event->state, 0)) + else if(dt_modifier_is(event->state, GDK_SHIFT_MASK)) + { + dt_selection_select_range(darktable.selection, id); + } + else + { + if(table->mode == DT_THUMBTABLE_MODE_FILMSTRIP + && cv == DT_VIEW_DARKROOM) { - DT_DEBUG_CONTROL_SIGNAL_RAISE(darktable.signals, - DT_SIGNAL_VIEWMANAGER_THUMBTABLE_ACTIVATE, id); + // if there is more than one selected image then we have at least + // one picture selected not counting the currently edited one. + // delay the single selection to ensure that if we double-click we + // do not unselect all the pictures. + if(table->sel_single_cb == 0) + { + // button released event must be skip + if(table->to_selid == -1) + { + table->to_selid = NO_IMGID; + } + else + { + table->to_selid = id; + table->sel_single_cb = g_timeout_add(350, _do_select_single, table); + } + } + } + else + { + dt_selection_select_single(darktable.selection, id); } + } } + // Left now if not in zoom mode + if(table->mode != DT_THUMBTABLE_MODE_ZOOM) return FALSE; @@ -2407,6 +2468,8 @@ dt_thumbtable_t *dt_thumbtable_new() // we init key accels _thumbtable_init_accels(); + table->sel_single_cb = 0; + table->to_selid = NO_IMGID; return table; } diff --git a/src/dtgtk/thumbtable.h b/src/dtgtk/thumbtable.h index d020a72e58ac..f0b6e53538a5 100644 --- a/src/dtgtk/thumbtable.h +++ b/src/dtgtk/thumbtable.h @@ -105,6 +105,10 @@ typedef struct dt_thumbtable_t // scroll timeout values guint scroll_timeout_id; float scroll_value; + + // darkroom selection from filmstrip (support for single & double click) + guint sel_single_cb; + dt_imgid_t to_selid; } dt_thumbtable_t; dt_thumbtable_t *dt_thumbtable_new();