Skip to content

Commit 0bafe71

Browse files
committed
convert bauhaus to gtkgestures
prep for gtk4
1 parent 27e1b95 commit 0bafe71

File tree

8 files changed

+247
-158
lines changed

8 files changed

+247
-158
lines changed

src/bauhaus/bauhaus.c

Lines changed: 118 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -61,23 +61,10 @@ static const dt_action_def_t _action_def_slider, _action_def_combo,
6161
static const double INNER_PADDING = 4.0;
6262

6363
// fwd declare
64-
static void _popup_show(GtkWidget *w);
6564
static void _popup_reject(void);
6665
static void _popup_hide(void);
6766
static gboolean _popup_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data);
6867
static gboolean _popup_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data);
69-
static gboolean _widget_draw(GtkWidget *widget, cairo_t *crf);
70-
static gboolean _widget_scroll(GtkWidget *widget, GdkEventScroll *event);
71-
static gboolean _widget_key_press(GtkWidget *widget, GdkEventKey *event);
72-
static gboolean _widget_button_press(GtkWidget *widget, GdkEventButton *event);
73-
static gboolean _widget_button_release(GtkWidget *widget, GdkEventButton *event);
74-
static gboolean _widget_motion_notify(GtkWidget *widget, GdkEventMotion *event);
75-
static void _widget_get_preferred_width(GtkWidget *widget,
76-
gint *minimum_size,
77-
gint *natural_size);
78-
static void _widget_get_preferred_height(GtkWidget *widget,
79-
gint *minimum_height,
80-
gint *natural_height);
8168
static void _combobox_set(dt_bauhaus_widget_t *w,
8269
const int pos,
8370
const gboolean mute);
@@ -681,41 +668,22 @@ static void _window_show(GtkWidget *w, gpointer user_data)
681668
gtk_grab_add(GTK_WIDGET(user_data));
682669
}
683670

684-
static void dt_bh_init(DtBauhausWidget *w)
671+
static void _widget_leave(GtkEventControllerMotion *controller,
672+
GtkWidget *widget)
685673
{
686-
w->field = NULL;
687-
688-
w->section = NULL;
674+
// gtk_widget_set_state_flags triggers resize&draw avalanche
675+
// instead add GTK_STATE_FLAG_PRELIGHT in _widget_draw
676+
darktable.bauhaus->hovered = !controller ? widget : NULL;
689677

690-
// no quad icon and no toggle button:
691-
w->quad_paint = 0;
692-
w->quad_paint_data = NULL;
693-
w->quad_toggle = 0;
694-
w->show_quad = TRUE;
695-
w->show_label = TRUE;
696-
697-
gtk_widget_add_events(GTK_WIDGET(w), GDK_POINTER_MOTION_MASK
698-
| GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
699-
| GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK
700-
| GDK_FOCUS_CHANGE_MASK
701-
| darktable.gui->scroll_mask);
702-
703-
gtk_widget_set_can_focus(GTK_WIDGET(w), TRUE);
704-
dt_gui_add_class(GTK_WIDGET(w), "dt_bauhaus");
678+
gtk_widget_queue_draw(widget);
705679
}
706680

707-
static gboolean _widget_enter_leave(GtkWidget *widget, GdkEventCrossing *event)
681+
static void _widget_enter(GtkEventControllerMotion *controller,
682+
double x,
683+
double y,
684+
GtkWidget *widget)
708685
{
709-
if(event->type == GDK_ENTER_NOTIFY)
710-
// gtk_widget_set_state_flags triggers resize&draw avalanche
711-
// instead add GTK_STATE_FLAG_PRELIGHT in _widget_draw
712-
darktable.bauhaus->hovered = widget;
713-
else
714-
darktable.bauhaus->hovered = NULL;
715-
716-
gtk_widget_queue_draw(widget);
717-
718-
return FALSE;
686+
_widget_leave(NULL, widget);
719687
}
720688

721689
static void _widget_finalize(GObject *widget)
@@ -740,31 +708,6 @@ static void _widget_finalize(GObject *widget)
740708
G_OBJECT_CLASS(dt_bh_parent_class)->finalize(widget);
741709
}
742710

743-
static void dt_bh_class_init(DtBauhausWidgetClass *class)
744-
{
745-
darktable.bauhaus->signals[DT_BAUHAUS_VALUE_CHANGED_SIGNAL]
746-
= g_signal_new("value-changed", G_TYPE_FROM_CLASS(class),
747-
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
748-
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
749-
darktable.bauhaus->signals[DT_BAUHAUS_QUAD_PRESSED_SIGNAL]
750-
= g_signal_new("quad-pressed", G_TYPE_FROM_CLASS(class),
751-
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
752-
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
753-
754-
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(class);
755-
widget_class->draw = _widget_draw;
756-
widget_class->scroll_event = _widget_scroll;
757-
widget_class->key_press_event = _widget_key_press;
758-
widget_class->button_press_event = _widget_button_press;
759-
widget_class->button_release_event = _widget_button_release;
760-
widget_class->motion_notify_event = _widget_motion_notify;
761-
widget_class->get_preferred_width = _widget_get_preferred_width;
762-
widget_class->get_preferred_height = _widget_get_preferred_height;
763-
widget_class->enter_notify_event = _widget_enter_leave;
764-
widget_class->leave_notify_event = _widget_enter_leave;
765-
G_OBJECT_CLASS(class)->finalize = _widget_finalize;
766-
}
767-
768711
void dt_bauhaus_load_theme()
769712
{
770713
GtkWidget *root_window = dt_ui_main_window(darktable.gui->ui);
@@ -3536,43 +3479,48 @@ static gboolean _popup_key_press(GtkWidget *widget,
35363479
return TRUE;
35373480
}
35383481

3539-
static gboolean _widget_button_press(GtkWidget *widget,
3540-
GdkEventButton *event)
3482+
static void _widget_button_press(GtkGestureSingle *gesture,
3483+
int n_press,
3484+
double x,
3485+
double y,
3486+
GtkWidget *widget)
35413487
{
3542-
dt_bauhaus_widget_t *w = (dt_bauhaus_widget_t *)widget;
3488+
dt_bauhaus_widget_t *w = DT_BAUHAUS_WIDGET(widget);
35433489
_request_focus(w);
35443490
gtk_widget_grab_focus(widget);
35453491

35463492
const int width = gtk_widget_get_allocated_width(widget);
35473493
const int w3 = width - w->margin.left - w->padding.left
35483494
- w->margin.right - w->padding.right;
3549-
const double ex = event->x - w->margin.left - w->padding.left;
3550-
const double ey = event->y - w->margin.top - w->padding.top;
3495+
const double ex = x - w->margin.left - w->padding.left;
3496+
const double ey = y - w->margin.top - w->padding.top;
3497+
guint button = gtk_gesture_single_get_current_button(gesture);
35513498

3552-
if(w->quad_paint && event->window == gtk_widget_get_window(widget)
3553-
&& event->x > width - _widget_get_quad_width(w)
3554-
- w->margin.right - w->padding.right)
3499+
gboolean passthrough_from_histogram = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture)) != widget;
3500+
if(w->quad_paint
3501+
&& !passthrough_from_histogram
3502+
&& x > width - _widget_get_quad_width(w)
3503+
- w->margin.right - w->padding.right)
35553504
{
35563505
dt_bauhaus_widget_press_quad(widget);
35573506
}
3558-
else if(event->button == GDK_BUTTON_PRIMARY
3559-
&& event->type == GDK_2BUTTON_PRESS)
3507+
else if(button == GDK_BUTTON_PRIMARY && n_press == 2)
35603508
{
3561-
if(!(dt_modifier_is(event->state, GDK_CONTROL_MASK) && w->field
3509+
if(!(dt_modifier_eq(gesture, GDK_CONTROL_MASK) && w->field
35623510
&& dt_gui_presets_autoapply_for_module((dt_iop_module_t *)w->module, widget)))
35633511
dt_bauhaus_widget_reset(widget); // reset to default.
35643512
// never called for combo, as we popup the other window under your cursor before.
35653513
// (except in weird corner cases where the popup is under the -1st entry
35663514
_popup_hide();
35673515
}
3568-
else if(event->button == GDK_BUTTON_SECONDARY || w->type == DT_BAUHAUS_COMBOBOX)
3516+
else if(button == GDK_BUTTON_SECONDARY || w->type == DT_BAUHAUS_COMBOBOX)
35693517
{
3570-
darktable.bauhaus->opentime = event->time;
3571-
darktable.bauhaus->mouse_x = event->x;
3572-
darktable.bauhaus->mouse_y = event->y;
3518+
darktable.bauhaus->opentime = gdk_event_get_time(gtk_get_current_event());
3519+
darktable.bauhaus->mouse_x = x;
3520+
darktable.bauhaus->mouse_y = y;
35733521
_popup_show(widget);
35743522
}
3575-
else if(event->button == GDK_BUTTON_MIDDLE)
3523+
else if(button == GDK_BUTTON_MIDDLE)
35763524
{
35773525
_slider_zoom_range(w, 0); // reset zoom range to soft min/max
35783526
_slider_zoom_toast(w);
@@ -3581,7 +3529,7 @@ static gboolean _widget_button_press(GtkWidget *widget,
35813529
{
35823530
dt_bauhaus_slider_data_t *d = &w->data.slider;
35833531
d->is_dragging = -1;
3584-
if(!dt_modifier_is(event->state, 0) || event->window != gtk_widget_get_window(widget))
3532+
if(!dt_modifier_eq(gesture, 0) || passthrough_from_histogram)
35853533
darktable.bauhaus->mouse_x = ex;
35863534
else if(ey > darktable.bauhaus->line_height / 2.0f)
35873535
{
@@ -3590,58 +3538,66 @@ static gboolean _widget_button_press(GtkWidget *widget,
35903538

35913539
darktable.bauhaus->mouse_x = NAN;
35923540
}
3593-
else
3594-
return FALSE;
35953541
}
35963542

3597-
return TRUE;
3543+
dt_gui_claim(gesture);
35983544
}
35993545

3600-
static gboolean _widget_button_release(GtkWidget *widget,
3601-
GdkEventButton *event)
3546+
static void _widget_button_release(GtkGestureSingle *gesture,
3547+
int n_press,
3548+
double x,
3549+
double y,
3550+
GtkWidget *widget)
36023551
{
3603-
dt_bauhaus_widget_t *w = (dt_bauhaus_widget_t *)widget;
3552+
dt_bauhaus_widget_t *w = DT_BAUHAUS_WIDGET(widget);
36043553
dt_bauhaus_widget_release_quad(widget);
36053554

3606-
if(w->type != DT_BAUHAUS_SLIDER) return FALSE;
3555+
if(w->type != DT_BAUHAUS_SLIDER) return;
36073556

36083557
dt_bauhaus_slider_data_t *d = &w->data.slider;
3609-
if(event->button == GDK_BUTTON_PRIMARY && d->is_dragging)
3558+
if(gtk_gesture_single_get_current_button(gesture) == GDK_BUTTON_PRIMARY
3559+
&& d->is_dragging)
36103560
{
36113561
d->is_dragging = 0;
36123562
if(d->timeout_handle) g_source_remove(d->timeout_handle);
36133563
d->timeout_handle = 0;
36143564
_slider_set_normalized(w, d->pos);
3615-
3616-
return TRUE;
36173565
}
3618-
return FALSE;
36193566
}
36203567

3621-
static gboolean _widget_motion_notify(GtkWidget *widget,
3622-
GdkEventMotion *event)
3568+
static void _widget_button_stopped(GtkGestureSingle *gesture,
3569+
dt_bauhaus_widget_t *w)
36233570
{
3624-
dt_bauhaus_widget_t *w = (dt_bauhaus_widget_t *)widget;
3571+
}
3572+
3573+
static void _widget_motion(GtkEventControllerMotion *controller,
3574+
double x,
3575+
double y,
3576+
GtkWidget *widget)
3577+
{
3578+
dt_bauhaus_widget_t *w = DT_BAUHAUS_WIDGET(widget);
36253579
dt_bauhaus_slider_data_t *d = &w->data.slider;
36263580

3627-
const int width = gdk_window_get_width(event->window);
3581+
GtkAllocation allocation;
3582+
gtk_widget_get_allocation(widget, &allocation);
3583+
const int width = allocation.width;
36283584
const int w3 = width - w->margin.left - w->padding.left
36293585
- w->margin.right - w->padding.right;
3630-
const double ex = event->x - w->margin.left - w->padding.left;
3586+
const double ex = x - w->margin.left - w->padding.left;
36313587

36323588
if(w->type == DT_BAUHAUS_COMBOBOX)
36333589
{
36343590
darktable.control->element =
3635-
event->x <= width - _widget_get_quad_width(w) || !w->quad_paint
3591+
x <= width - _widget_get_quad_width(w) || !w->quad_paint
36363592
? DT_ACTION_ELEMENT_SELECTION : DT_ACTION_ELEMENT_BUTTON;
36373593
}
3638-
else if(d->is_dragging && event->state & GDK_BUTTON1_MASK)
3594+
else if(d->is_dragging)
36393595
{
36403596
const float r = _slider_right_pos((float)w3, w);
36413597

36423598
if(dt_isnan(darktable.bauhaus->mouse_x))
36433599
{
3644-
if(dt_modifier_is(event->state, 0))
3600+
if(dt_modifier_eq(controller, 0))
36453601
_slider_set_normalized(w, (ex / w3) / r);
36463602
else
36473603
darktable.bauhaus->mouse_x = ex;
@@ -3651,6 +3607,7 @@ static gboolean _widget_motion_notify(GtkWidget *widget,
36513607
const float scaled_step =
36523608
w3 * r * dt_bauhaus_slider_get_step(widget) / (d->max - d->min);
36533609
const float steps = floorf((ex - darktable.bauhaus->mouse_x) / scaled_step);
3610+
GdkEventMotion *event = (GdkEventMotion *)gtk_get_current_event(); // TODO cleanup
36543611
_slider_add_step(widget, copysignf(1, d->factor) * steps, event->state, FALSE);
36553612

36563613
darktable.bauhaus->mouse_x += steps * scaled_step;
@@ -3669,7 +3626,63 @@ static gboolean _widget_motion_notify(GtkWidget *widget,
36693626
w->quad_paint ? DT_ACTION_ELEMENT_BUTTON : DT_ACTION_ELEMENT_VALUE;
36703627

36713628
gtk_widget_queue_draw(widget);
3672-
return TRUE;
3629+
}
3630+
3631+
static void dt_bh_class_init(DtBauhausWidgetClass *class)
3632+
{
3633+
darktable.bauhaus->signals[DT_BAUHAUS_VALUE_CHANGED_SIGNAL]
3634+
= g_signal_new("value-changed", G_TYPE_FROM_CLASS(class),
3635+
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
3636+
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
3637+
darktable.bauhaus->signals[DT_BAUHAUS_QUAD_PRESSED_SIGNAL]
3638+
= g_signal_new("quad-pressed", G_TYPE_FROM_CLASS(class),
3639+
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
3640+
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
3641+
3642+
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(class);
3643+
widget_class->draw = _widget_draw;
3644+
// widget_class->snapshot = _widget_snapshot;
3645+
widget_class->scroll_event = _widget_scroll;
3646+
widget_class->key_press_event = _widget_key_press;
3647+
widget_class->get_preferred_width = _widget_get_preferred_width;
3648+
widget_class->get_preferred_height = _widget_get_preferred_height;
3649+
// widget_class->measure = _widget_measure;
3650+
G_OBJECT_CLASS(class)->finalize = _widget_finalize;
3651+
3652+
// for histogram -> exposure proxy
3653+
darktable.bauhaus->press = _widget_button_press;
3654+
darktable.bauhaus->release = _widget_button_release;
3655+
darktable.bauhaus->motion = _widget_motion;
3656+
darktable.bauhaus->scroll = _widget_scroll;
3657+
}
3658+
3659+
static void dt_bh_init(DtBauhausWidget *w)
3660+
{
3661+
w->field = NULL;
3662+
w->section = NULL;
3663+
3664+
// no quad icon and no toggle button:
3665+
w->quad_paint = 0;
3666+
w->quad_paint_data = NULL;
3667+
w->quad_toggle = 0;
3668+
w->show_quad = TRUE;
3669+
w->show_label = TRUE;
3670+
3671+
GtkWidget *widget = GTK_WIDGET(w);
3672+
gtk_widget_add_events(widget, GDK_FOCUS_CHANGE_MASK | darktable.gui->scroll_mask);
3673+
3674+
GtkGestureSingle *gesture = dt_gui_connect_click(w, _widget_button_press, _widget_button_release, widget);
3675+
gtk_gesture_single_set_button(gesture, 0);
3676+
g_signal_connect(gesture, "stopped", G_CALLBACK(_widget_button_stopped), w);
3677+
3678+
dt_gui_connect_motion(w, _widget_motion, _widget_enter, _widget_leave, widget);
3679+
3680+
// GtkEventController *controller = gtk_event_controller_scroll_new(GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES | GTK_EVENT_CONTROLLER_SCROLL_DISCRETE);
3681+
// gtk_widget_add_controller(GTK_WIDGET(w), GTK_EVENT_CONTROLLER(controller));
3682+
// g_signal_connect(controller, "scroll", G_CALLBACK(_widget_scroll), w);
3683+
3684+
gtk_widget_set_can_focus(widget, TRUE);
3685+
dt_gui_add_class(widget, "dt_bauhaus");
36733686
}
36743687

36753688
void dt_bauhaus_combobox_mute_scrolling(GtkWidget *widget)

src/bauhaus/bauhaus.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,12 @@ typedef struct dt_bauhaus_t
255255
GdkRGBA graph_bg, graph_exterior, graph_border, graph_fg, graph_grid, graph_fg_active, graph_overlay, inset_histogram;
256256
GdkRGBA graph_colors[3]; // primaries
257257
GdkRGBA colorlabels[DT_COLORLABELS_LAST];
258+
259+
// for use by histogram -> exposure proxy
260+
void (*press)(GtkGestureSingle*, int, double, double, GtkWidget*);
261+
void (*release)(GtkGestureSingle*, int, double, double, GtkWidget*);
262+
void (*motion)(GtkEventControllerMotion*, double, double, GtkWidget*);
263+
gboolean (*scroll)(GtkWidget*, GdkEventScroll*);
258264
} dt_bauhaus_t;
259265

260266
#define DT_BAUHAUS_SPACE 0

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

0 commit comments

Comments
 (0)