Skip to content

Commit

Permalink
convert iop graphs to gtkgestures in prep for gtk4
Browse files Browse the repository at this point in the history
  • Loading branch information
dterrahe committed Aug 1, 2024
1 parent 423a0f4 commit 7a2ea00
Show file tree
Hide file tree
Showing 21 changed files with 852 additions and 898 deletions.
64 changes: 34 additions & 30 deletions src/develop/imageop.c
Original file line number Diff line number Diff line change
Expand Up @@ -2404,52 +2404,57 @@ void dt_iop_gui_update_expanded(dt_iop_module_t *module)
dtgtk_expander_set_expanded(DTGTK_EXPANDER(module->expander), expanded);
}

static gboolean _iop_plugin_body_button_press(GtkWidget *w,
GdkEventButton *e,
gpointer user_data)
static void _iop_plugin_body_button_press(GtkGestureSingle *gesture,
int n_press,
double x,
double y,
dt_iop_module_t *module)
{
dt_iop_module_t *module = (dt_iop_module_t *)user_data;
if(e->button == 1)
guint button = gtk_gesture_single_get_current_button(gesture);
if(button == 1)
{
dt_iop_request_focus(module);
return TRUE;
dt_gui_claim(gesture);
return;
}
else if(e->button == 3)
else if(button == 3)
{
_presets_popup_callback(NULL, NULL, module);

return TRUE;
dt_gui_claim(gesture);
return;
}
return FALSE;
}

static gboolean _iop_plugin_header_button_press(GtkWidget *w,
GdkEventButton *e,
gpointer user_data)
static void _iop_plugin_header_button_press(GtkGestureSingle *gesture,
int n_press,
double x,
double y,
dt_iop_module_t *module)
{
if(e->type == GDK_2BUTTON_PRESS || e->type == GDK_3BUTTON_PRESS) return TRUE;
if(n_press > 1) return;

dt_iop_module_t *module = (dt_iop_module_t *)user_data;

if(e->button == 1)
guint button = gtk_gesture_single_get_current_button(gesture);
if(button == 1)
{
if(dt_modifier_is(e->state, GDK_SHIFT_MASK | GDK_CONTROL_MASK))
if(dt_modifier_eq(gesture, GDK_SHIFT_MASK | GDK_CONTROL_MASK))
{
GtkBox *container =
dt_ui_get_container(darktable.gui->ui, DT_UI_CONTAINER_PANEL_RIGHT_CENTER);
g_object_set_data(G_OBJECT(container), "source_data", user_data);
return FALSE;
g_object_set_data(G_OBJECT(container), "source_data", module);
return;
}
else if(dt_modifier_is(e->state, GDK_CONTROL_MASK))
else if(dt_modifier_eq(gesture, GDK_CONTROL_MASK))
{
dt_iop_gui_rename_module(module);
return TRUE;
dt_gui_claim(gesture);
return;
}
else
{
const gboolean collapse_others =
!dt_conf_get_bool("darkroom/ui/single_module")
!= (!dt_modifier_is(e->state, GDK_SHIFT_MASK));
!= (!dt_modifier_eq(gesture, GDK_SHIFT_MASK));

dt_iop_gui_set_expanded(module, !module->expanded, collapse_others);

Expand All @@ -2459,16 +2464,17 @@ static gboolean _iop_plugin_header_button_press(GtkWidget *w,
//used to take focus away from module search text input box when module selected
gtk_widget_grab_focus(dt_ui_center(darktable.gui->ui));

return TRUE;
dt_gui_claim(gesture);
return;
}
}
else if(e->button == 3)
else if(button == 3)
{
_presets_popup_callback(NULL, NULL, module);

return TRUE;
dt_gui_claim(gesture);
return;
}
return FALSE;
}

static void _header_size_callback(GtkWidget *widget,
Expand Down Expand Up @@ -2909,17 +2915,15 @@ void dt_iop_gui_set_expander(dt_iop_module_t *module)
module->header = header;

/* setup the header box */
g_signal_connect(G_OBJECT(header_evb), "button-press-event",
G_CALLBACK(_iop_plugin_header_button_press), module);
dt_gui_connect_click_all(header_evb, _iop_plugin_header_button_press, NULL, module);
gtk_widget_add_events(header_evb, GDK_POINTER_MOTION_MASK);
g_signal_connect(G_OBJECT(header_evb), "enter-notify-event",
G_CALLBACK(_header_motion_notify_show_callback), module);
g_signal_connect(G_OBJECT(header_evb), "leave-notify-event",
G_CALLBACK(_header_motion_notify_hide_callback), module);

/* connect mouse button callbacks for focus and presets */
g_signal_connect(G_OBJECT(body_evb), "button-press-event",
G_CALLBACK(_iop_plugin_body_button_press), module);
dt_gui_connect_click_all(body_evb, _iop_plugin_body_button_press, NULL, module);
gtk_widget_add_events(body_evb, GDK_POINTER_MOTION_MASK);
g_signal_connect(G_OBJECT(body_evb), "enter-notify-event",
G_CALLBACK(_header_motion_notify_show_callback), module);
Expand Down
67 changes: 27 additions & 40 deletions src/dtgtk/thumbnail.c
Original file line number Diff line number Diff line change
Expand Up @@ -926,43 +926,42 @@ static void _thumbs_show_overlays(dt_thumbnail_t *thumb)
}
}

static gboolean _event_main_motion(GtkWidget *widget,
GdkEventMotion *event,
gpointer user_data)
static void _event_main_motion(GtkEventControllerMotion *controller,
double x,
double y,
gpointer user_data)
{
if(!user_data) return TRUE;
if(!user_data) return;
dt_thumbnail_t *thumb = (dt_thumbnail_t *)user_data;
// first, we hide the block overlays after a delay if the mouse hasn't move
_thumbs_show_overlays(thumb);

if(!thumb->mouse_over && !thumb->disable_mouseover)
dt_control_set_mouse_over_id(thumb->imgid);
return FALSE;
}

static gboolean _event_main_press(GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
static void _event_main_press(GtkGestureSingle *gesture,
int n_press,
double x,
double y,
dt_thumbnail_t *thumb)
{
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)))
if((n_press == 2 && !thumb->single_click)
|| (n_press == 1
&& dt_modifier_eq(gesture, 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)
static void _event_main_release(GtkGesture *gesture,
int n_press,
double x,
double y,
dt_thumbnail_t *thumb)
{
dt_thumbnail_t *thumb = (dt_thumbnail_t *)user_data;

if(event->button == 1
&& !thumb->moved
GdkEventButton *event = (GdkEventButton *)gtk_gesture_get_last_event(gesture, NULL);
if(!thumb->moved
&& thumb->sel_mode != DT_THUMBNAIL_SEL_MODE_DISABLED)
{
if(dt_modifier_is(event->state, 0)
Expand All @@ -976,7 +975,6 @@ static gboolean _event_main_release(GtkWidget *widget,
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,
Expand Down Expand Up @@ -1339,13 +1337,12 @@ static gboolean _event_star_leave(GtkWidget *widget,
return TRUE;
}

static gboolean _event_main_leave(GtkWidget *widget,
GdkEventCrossing *event,
gpointer user_data)
static void _event_main_leave(GtkEventControllerMotion *controller,
gpointer user_data)
{
GdkEventCrossing *event = (GdkEventCrossing *)gtk_get_current_event();
// if we leave for ancestor, that means we leave for blank thumbtable area
if(event->detail == GDK_NOTIFY_ANCESTOR) dt_control_set_mouse_over_id(NO_IMGID);
return FALSE;
}

// we only want to specify that the mouse is hovereing the thumbnail
Expand All @@ -1356,7 +1353,7 @@ static gboolean _event_main_drag_motion(GtkWidget *widget,
const guint time,
gpointer user_data)
{
_event_main_motion(widget, NULL, user_data);
_event_main_motion(NULL, .0f, .0f, user_data);
return TRUE;
}

Expand Down Expand Up @@ -1401,10 +1398,7 @@ 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);
dt_gui_connect_click(thumb->w_main, _event_main_press, _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,
Expand All @@ -1423,16 +1417,9 @@ GtkWidget *dt_thumbnail_create_widget(dt_thumbnail_t *thumb,

// the background
thumb->w_back = gtk_event_box_new();
gtk_widget_set_events(thumb->w_back,
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
| GDK_STRUCTURE_MASK
| GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK
| GDK_POINTER_MOTION_MASK);
gtk_widget_set_events(thumb->w_back, GDK_STRUCTURE_MASK); // TODO: Needed?
gtk_widget_set_name(thumb->w_back, "thumb-back");
g_signal_connect(G_OBJECT(thumb->w_back), "motion-notify-event",
G_CALLBACK(_event_main_motion), thumb);
g_signal_connect(G_OBJECT(thumb->w_back), "leave-notify-event",
G_CALLBACK(_event_main_leave), thumb);
dt_gui_connect_motion(thumb->w_back, _event_main_motion, NULL, _event_main_leave, thumb);
gtk_widget_show(thumb->w_back);
gtk_container_add(GTK_CONTAINER(thumb->w_main), thumb->w_back);

Expand Down
29 changes: 29 additions & 0 deletions src/gui/gtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -4161,6 +4161,35 @@ gboolean dt_gui_long_click(const int second,
return second - first > delay;
}

GtkGestureSingle *(dt_gui_connect_click)(GtkWidget *widget,
GCallback pressed,
GCallback released,
gpointer data)
{
GtkGesture *gesture = gtk_gesture_multi_press_new(widget);

if(pressed) g_signal_connect(gesture, "pressed", pressed, data);
if(released) g_signal_connect(gesture, "released", released, data);

return (GtkGestureSingle *)gesture;
}

GtkEventController *(dt_gui_connect_motion)(GtkWidget *widget,
GCallback motion,
GCallback enter,
GCallback leave,
gpointer data)
{
GtkEventController *controller = gtk_event_controller_motion_new(widget);

if(motion) g_signal_connect(controller, "motion", motion, data);
if(enter) g_signal_connect(controller, "enter", enter, data);
if(leave) g_signal_connect(controller, "leave", leave, data);

return controller;
}


// clang-format off
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
// vim: shiftwidth=2 expandtab tabstop=2 cindent
Expand Down
24 changes: 24 additions & 0 deletions src/gui/gtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,30 @@ void dt_gui_hide_collapsible_section(dt_gui_collapsible_section_t *cs);
gboolean dt_gui_long_click(const int second,
const int first);

GtkGestureSingle *(dt_gui_connect_click)(GtkWidget *widget,
GCallback pressed,
GCallback released,
gpointer data);
#define dt_gui_connect_click(widget, pressed, released, data) \
dt_gui_connect_click(GTK_WIDGET(widget), G_CALLBACK(pressed), G_CALLBACK(released), (data))
#define dt_gui_connect_click_all(widget, pressed, released, data) \
gtk_gesture_single_set_button(dt_gui_connect_click(widget, pressed, released, data), 0)

#define dt_gui_claim(gesture) \
gtk_gesture_set_state(GTK_GESTURE(gesture), GTK_EVENT_SEQUENCE_CLAIMED)

GtkEventController *(dt_gui_connect_motion)(GtkWidget *widget,
GCallback motion,
GCallback enter,
GCallback leave,
gpointer data);
#define dt_gui_connect_motion(widget, motion, enter, leave, data) \
dt_gui_connect_motion(GTK_WIDGET(widget), G_CALLBACK(motion), G_CALLBACK(enter), G_CALLBACK(leave), (data))

// in gtk4 use gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(controller));
#define dt_modifier_eq(controller, mask)\
dt_modifier_is(dt_key_modifier_state(), mask)

#ifdef __cplusplus
} // extern "C"
#endif /* __cplusplus */
Expand Down
Loading

0 comments on commit 7a2ea00

Please sign in to comment.