Skip to content

Commit b39d03b

Browse files
authored
Merge pull request #19523 from dterrahe/bh_gestures
Convert bauhaus to use GtkGestures
2 parents 0abbac2 + ce40540 commit b39d03b

File tree

15 files changed

+713
-690
lines changed

15 files changed

+713
-690
lines changed

src/bauhaus/bauhaus.c

Lines changed: 480 additions & 425 deletions
Large diffs are not rendered by default.

src/bauhaus/bauhaus.h

Lines changed: 87 additions & 165 deletions
Large diffs are not rendered by default.

src/develop/blend_gui.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2766,7 +2766,6 @@ void dt_iop_gui_init_masks(GtkWidget *blendw, dt_iop_module_t *module)
27662766

27672767
bd->masks_combo = dt_bauhaus_combobox_new(module);
27682768
dt_bauhaus_widget_set_label(bd->masks_combo, N_("blend"), N_("drawn mask"));
2769-
dt_bauhaus_widget_set_section(bd->masks_combo, TRUE);
27702769

27712770
dt_bauhaus_combobox_add(bd->masks_combo, _("no mask used"));
27722771
g_signal_connect(G_OBJECT(bd->masks_combo), "value-changed",

src/develop/develop.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2957,10 +2957,10 @@ float dt_dev_exposure_get_black(dt_develop_t *dev)
29572957
return instance && instance->get_black && instance->module->enabled ? instance->get_black(instance->module) : 0.0f;
29582958
}
29592959

2960-
void dt_dev_exposure_handle_event(GdkEvent *event, const gboolean blackwhite)
2960+
void dt_dev_exposure_handle_event(gpointer controller, int n_press, gdouble x, const gboolean blackwhite)
29612961
{
29622962
if(darktable.develop->proxy.exposure.handle_event)
2963-
darktable.develop->proxy.exposure.handle_event(event, blackwhite);
2963+
darktable.develop->proxy.exposure.handle_event(controller, n_press, x, blackwhite);
29642964
}
29652965

29662966
void dt_dev_modulegroups_set(dt_develop_t *dev,

src/develop/develop.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ typedef struct dt_dev_proxy_exposure_t
102102
struct dt_iop_module_t *module;
103103
float (*get_exposure)(struct dt_iop_module_t *exp);
104104
float (*get_black)(struct dt_iop_module_t *exp);
105-
void (*handle_event)(GdkEvent *event, gboolean blackwhite);
105+
void (*handle_event)(gpointer, int, gdouble, const gboolean);
106106
} dt_dev_proxy_exposure_t;
107107

108108
struct dt_dev_pixelpipe_t;
@@ -471,7 +471,7 @@ float dt_dev_exposure_get_exposure(dt_develop_t *dev);
471471
/** get exposure black level */
472472
float dt_dev_exposure_get_black(dt_develop_t *dev);
473473

474-
void dt_dev_exposure_handle_event(GdkEvent *event, gboolean blackwhite);
474+
void dt_dev_exposure_handle_event(gpointer controller, int n_press, gdouble x, const gboolean blackwhite);
475475

476476
/*
477477
* modulegroups plugin hooks

src/gui/accelerators.c

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,7 @@ static gchar *_shortcut_lua_command(GtkWidget *widget,
919919

920920
if(DT_IS_BAUHAUS_WIDGET(widget) && s->element == DT_ACTION_ELEMENT_DEFAULT)
921921
{
922-
if(DT_BAUHAUS_WIDGET(widget)->type == DT_BAUHAUS_COMBOBOX)
922+
if(dt_bauhaus_widget_get_type(widget) == DT_BAUHAUS_COMBOBOX)
923923
{
924924
int value = GPOINTER_TO_INT(dt_bauhaus_combobox_get_data(widget));
925925
dt_introspection_type_enum_tuple_t *values
@@ -1034,8 +1034,7 @@ gboolean dt_shortcut_tooltip_callback(GtkWidget *widget,
10341034
int show_element = 0;
10351035
dt_shortcut_t lua_shortcut = { .speed = 1.0 };
10361036

1037-
gchar *original_markup =
1038-
dt_bauhaus_widget_get_tooltip_markup(widget, darktable.control->element);
1037+
gchar *original_markup = dt_bauhaus_widget_get_tooltip_markup(widget, x, y);
10391038
const gchar *widget_name = gtk_widget_get_name(widget);
10401039

10411040
if(!strcmp(widget_name, "actions_view") || !strcmp(widget_name, "shortcuts_view"))
@@ -1129,23 +1128,6 @@ gboolean dt_shortcut_tooltip_callback(GtkWidget *widget,
11291128
_("scroll to change default speed"),
11301129
_("right-click to exit mapping mode"));
11311130
}
1132-
else if(DT_IS_BAUHAUS_WIDGET(widget)
1133-
&& DT_BAUHAUS_WIDGET(widget)->type == DT_BAUHAUS_SLIDER
1134-
&& darktable.control->element == 2) // DT_ACTION_ELEMENT_FORCE
1135-
{
1136-
float hard_min = dt_bauhaus_slider_get_hard_min(widget);
1137-
float hard_max = dt_bauhaus_slider_get_hard_max(widget);
1138-
if(dt_bauhaus_slider_get_soft_min(widget) != hard_min ||
1139-
dt_bauhaus_slider_get_soft_max(widget) != hard_max)
1140-
{
1141-
dt_util_str_cat(&original_markup,
1142-
_("%sright-click to type a specific value between <b>%s</b> and <b>%s</b>"
1143-
"\nor hold ctrl+shift while dragging to ignore soft limits."),
1144-
original_markup ? "\n\n" : "",
1145-
dt_bauhaus_slider_get_text(widget, hard_min),
1146-
dt_bauhaus_slider_get_text(widget, hard_max));
1147-
}
1148-
}
11491131
}
11501132

11511133
if(!def) def = _action_find_definition(action);

src/gui/gtk.c

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3595,28 +3595,26 @@ static void _notebook_size_callback(GtkNotebook *notebook,
35953595
// GTK_STATE_FLAG_PRELIGHT does not seem to get set on the label on
35963596
// hover so state-flags-changed cannot update
35973597
// darktable.control->element for shortcut mapping
3598-
static gboolean _notebook_motion_notify_callback(GtkWidget *widget,
3599-
const GdkEventMotion *event,
3600-
gpointer user_data)
3598+
static void _notebook_motion_notify_callback(GtkEventControllerMotion *controller,
3599+
double x,
3600+
double y,
3601+
GtkNotebook *notebook)
36013602
{
36023603
GtkAllocation notebook_alloc, label_alloc;
3603-
gtk_widget_get_allocation(widget, &notebook_alloc);
3604+
gtk_widget_get_allocation(GTK_WIDGET(notebook), &notebook_alloc);
36043605

3605-
GtkNotebook *notebook = GTK_NOTEBOOK(widget);
36063606
const int n = gtk_notebook_get_n_pages(notebook);
36073607
for(int i = 0; i < n; i++)
36083608
{
36093609
gtk_widget_get_allocation(gtk_notebook_get_tab_label
36103610
(notebook, gtk_notebook_get_nth_page(notebook, i)),
36113611
&label_alloc);
3612-
if(event->x + notebook_alloc.x < label_alloc.x + label_alloc.width)
3612+
if(x + notebook_alloc.x < label_alloc.x + label_alloc.width)
36133613
{
36143614
darktable.control->element = i;
36153615
break;
36163616
}
36173617
}
3618-
3619-
return FALSE;
36203618
}
36213619

36223620
static float _action_process_tabs(const gpointer target,
@@ -3739,7 +3737,7 @@ static gboolean _notebook_button_press_callback(GtkNotebook *notebook,
37393737
const GdkEventButton *event,
37403738
gpointer user_data)
37413739
{
3742-
if(event->type == GDK_2BUTTON_PRESS)
3740+
if(event->type == GDK_2BUTTON_PRESS && gtk_get_event_widget((GdkEvent*)event) == GTK_WIDGET(notebook))
37433741
_reset_all_bauhaus(notebook, gtk_notebook_get_nth_page(notebook, gtk_notebook_get_current_page(notebook)));
37443742

37453743
return FALSE;
@@ -3770,8 +3768,7 @@ GtkWidget *dt_ui_notebook_page(GtkNotebook *notebook,
37703768
{
37713769
g_signal_connect(G_OBJECT(notebook), "size-allocate",
37723770
G_CALLBACK(_notebook_size_callback), NULL);
3773-
g_signal_connect(G_OBJECT(notebook), "motion-notify-event",
3774-
G_CALLBACK(_notebook_motion_notify_callback), NULL);
3771+
dt_gui_connect_motion(notebook, _notebook_motion_notify_callback, NULL, NULL, notebook);
37753772
g_signal_connect(G_OBJECT(notebook), "scroll-event",
37763773
G_CALLBACK(_notebook_scroll_callback), NULL);
37773774
g_signal_connect(G_OBJECT(notebook), "button-press-event",
@@ -4396,6 +4393,43 @@ gboolean dt_gui_long_click(const guint second,
43964393
return second - delay > first;
43974394
}
43984395

4396+
GtkGestureSingle *(dt_gui_connect_click)(GtkWidget *widget,
4397+
GCallback pressed,
4398+
GCallback released,
4399+
gpointer data)
4400+
{
4401+
GtkGesture *gesture = gtk_gesture_multi_press_new(widget);
4402+
g_object_weak_ref(G_OBJECT (widget), (GWeakNotify) g_object_unref, gesture);
4403+
// GTK4 GtkGesture *gesture = gtk_gesture_click_new();
4404+
// gtk_widget_add_controller(widget, GTK_EVENT_CONTROLLER(gesture));
4405+
4406+
if(pressed) g_signal_connect(gesture, "pressed", pressed, data);
4407+
if(released) g_signal_connect(gesture, "released", released, data);
4408+
4409+
return (GtkGestureSingle *)gesture;
4410+
}
4411+
4412+
GtkEventController *(dt_gui_connect_motion)(GtkWidget *widget,
4413+
GCallback motion,
4414+
GCallback enter,
4415+
GCallback leave,
4416+
gpointer data)
4417+
{
4418+
GtkEventController *controller = gtk_event_controller_motion_new(widget);
4419+
gtk_event_controller_set_propagation_phase(controller, GTK_PHASE_TARGET);
4420+
g_object_weak_ref(G_OBJECT (widget), (GWeakNotify) g_object_unref, controller);
4421+
// GTK4 gtk_widget_add_controller(widget, GTK_EVENT_CONTROLLER(controller));
4422+
4423+
gtk_widget_add_events(widget, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); // still needed for now by _main_do_event_keymap
4424+
4425+
if(motion) g_signal_connect(controller, "motion", motion, data);
4426+
if(enter) g_signal_connect(controller, "enter", enter, data);
4427+
if(leave) g_signal_connect(controller, "leave", leave, data);
4428+
4429+
return controller;
4430+
}
4431+
4432+
43994433
static int busy_nest_count = 0;
44004434
static GdkCursor* busy_prev_cursor = NULL;
44014435

@@ -4498,7 +4532,7 @@ GtkWidget *(dt_gui_box_add)(const char *file, const int line, const char *functi
44984532
else if(gtk_widget_get_parent(*list))
44994533
dt_print(DT_DEBUG_ALWAYS, "%s:%d %s: trying to add widget that already has a parent to box (#%d)", file, line, function, i);
45004534
else
4501-
gtk_container_add(GTK_CONTAINER(box), GTK_WIDGET(*list));
4535+
gtk_container_add(GTK_CONTAINER(box), GTK_WIDGET(*list)); // GTK4 gtk_box_append
45024536
}
45034537

45044538
return GTK_WIDGET(box);

src/gui/gtk.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,37 @@ void dt_gui_hide_collapsible_section(const dt_gui_collapsible_section_t *cs);
533533
gboolean dt_gui_long_click(const guint second,
534534
const guint first);
535535

536+
#define ASSERT_FUNC_TYPE(func, expected_type) (void)(1 ? (func) : (expected_type)0)
537+
538+
GtkGestureSingle *(dt_gui_connect_click)(GtkWidget *widget,
539+
GCallback pressed,
540+
GCallback released,
541+
gpointer data);
542+
#define dt_gui_connect_click(widget, pressed, released, data) ( \
543+
ASSERT_FUNC_TYPE(pressed, void(*)(GtkGestureSingle *, int, double, double, __typeof__(data))), \
544+
ASSERT_FUNC_TYPE(released, void(*)(GtkGestureSingle *, int, double, double, __typeof__(data))), \
545+
dt_gui_connect_click(GTK_WIDGET(widget), G_CALLBACK(pressed), G_CALLBACK(released), (data)))
546+
#define dt_gui_connect_click_all(widget, pressed, released, data) \
547+
gtk_gesture_single_set_button(dt_gui_connect_click(widget, pressed, released, data), 0)
548+
549+
#define dt_gui_claim(gesture) \
550+
gtk_gesture_set_state(GTK_GESTURE(gesture), GTK_EVENT_SEQUENCE_CLAIMED)
551+
552+
GtkEventController *(dt_gui_connect_motion)(GtkWidget *widget,
553+
GCallback motion,
554+
GCallback enter,
555+
GCallback leave,
556+
gpointer data);
557+
#define dt_gui_connect_motion(widget, motion, enter, leave, data) ( \
558+
ASSERT_FUNC_TYPE(motion, void(*)(GtkEventControllerMotion *, double, double, __typeof__(data))), \
559+
ASSERT_FUNC_TYPE(enter, void(*)(GtkEventControllerMotion *, double, double, __typeof__(data))), \
560+
ASSERT_FUNC_TYPE(leave, void(*)(GtkEventControllerMotion *, __typeof__(data))), \
561+
dt_gui_connect_motion(GTK_WIDGET(widget), G_CALLBACK(motion), G_CALLBACK(enter), G_CALLBACK(leave), (data)))
562+
563+
// GTK4 gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(controller));
564+
#define dt_modifier_eq(controller, mask)\
565+
dt_modifier_is(dt_key_modifier_state(), mask)
566+
536567
// control whether the mouse pointer displays as a "busy" cursor, e.g. watch or timer
537568
// the calls may be nested, but must be matched
538569
void dt_gui_cursor_set_busy();

src/iop/exposure.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -814,25 +814,37 @@ static float _exposure_proxy_get_black(dt_iop_module_t *self)
814814
}
815815

816816

817-
static void _exposure_proxy_handle_event(GdkEvent *event, const gboolean blackwhite)
817+
static void _exposure_proxy_handle_event(gpointer controller,
818+
int n_press,
819+
double x,
820+
const gboolean blackwhite)
818821
{
819822
dt_iop_module_t *self = darktable.develop->proxy.exposure.module;
820823
if(self && self->gui_data)
821824
{
822825
static gboolean black = FALSE;
823-
if(event->type == GDK_BUTTON_PRESS || event->type == GDK_SCROLL)
826+
if((n_press > 0 && GTK_IS_GESTURE_SINGLE(controller)) // button press
827+
|| !n_press) // scroll event
824828
black = blackwhite;
825829

826830
if(black)
827-
event->button.x *= -1;
831+
x *= -1;
828832

829833
const dt_iop_exposure_params_t *p = self->params;
830834
dt_iop_exposure_gui_data_t *g = self->gui_data;
831835
GtkWidget *widget = black ? g->black :
832836
p->mode == EXPOSURE_MODE_DEFLICKER
833-
? g->deflicker_target_level : g->exposure;
834-
gtk_widget_realize(widget);
835-
gtk_widget_event(widget, event);
837+
? g->deflicker_target_level : g->exposure;
838+
if(!n_press)
839+
darktable.bauhaus->scroll(widget, controller);
840+
else
841+
if(GTK_IS_GESTURE_SINGLE(controller))
842+
if(n_press > 0)
843+
darktable.bauhaus->press(controller, n_press, x, 0, widget);
844+
else
845+
darktable.bauhaus->release(controller, -n_press, x, 0, widget);
846+
else
847+
darktable.bauhaus->motion(controller, x, 0, widget);
836848

837849
gchar *text = dt_bauhaus_slider_get_text(widget, dt_bauhaus_slider_get(widget));
838850
dt_action_widget_toast(DT_ACTION(self), widget, "%s", text);

src/libs/filtering.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,7 @@ static gboolean _widget_init(dt_lib_filtering_rule_t *rule, const dt_collection_
12461246

12471247
// operator type
12481248
rule->w_operator = dt_bauhaus_combobox_new(NULL);
1249-
DT_BAUHAUS_WIDGET(rule->w_operator)->show_quad = FALSE;
1249+
dt_bauhaus_widget_set_quad_visibility(rule->w_operator, FALSE);
12501250
dt_bauhaus_combobox_add_aligned(rule->w_operator, _("and"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT);
12511251
dt_bauhaus_combobox_add_aligned(rule->w_operator, _("or"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT);
12521252
dt_bauhaus_combobox_add_aligned(rule->w_operator, _("and not"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT);
@@ -1264,7 +1264,7 @@ static gboolean _widget_init(dt_lib_filtering_rule_t *rule, const dt_collection_
12641264
{
12651265
rule->w_prop = dt_bauhaus_combobox_new(NULL);
12661266
dt_bauhaus_combobox_set_selected_text_align(rule->w_prop, DT_BAUHAUS_COMBOBOX_ALIGN_MIDDLE);
1267-
DT_BAUHAUS_WIDGET(rule->w_prop)->show_quad = FALSE;
1267+
dt_bauhaus_widget_set_quad_visibility(rule->w_prop, FALSE);
12681268
_rule_populate_prop_combo(rule);
12691269
g_object_set_data(G_OBJECT(rule->w_prop), "rule", rule);
12701270
dt_bauhaus_combobox_set_from_value(rule->w_prop, prop);

0 commit comments

Comments
 (0)