Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
905 changes: 480 additions & 425 deletions src/bauhaus/bauhaus.c

Large diffs are not rendered by default.

252 changes: 87 additions & 165 deletions src/bauhaus/bauhaus.h

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion src/develop/blend_gui.c
Original file line number Diff line number Diff line change
Expand Up @@ -2766,7 +2766,6 @@ void dt_iop_gui_init_masks(GtkWidget *blendw, dt_iop_module_t *module)

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

dt_bauhaus_combobox_add(bd->masks_combo, _("no mask used"));
g_signal_connect(G_OBJECT(bd->masks_combo), "value-changed",
Expand Down
4 changes: 2 additions & 2 deletions src/develop/develop.c
Original file line number Diff line number Diff line change
Expand Up @@ -2957,10 +2957,10 @@ float dt_dev_exposure_get_black(dt_develop_t *dev)
return instance && instance->get_black && instance->module->enabled ? instance->get_black(instance->module) : 0.0f;
}

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

void dt_dev_modulegroups_set(dt_develop_t *dev,
Expand Down
4 changes: 2 additions & 2 deletions src/develop/develop.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ typedef struct dt_dev_proxy_exposure_t
struct dt_iop_module_t *module;
float (*get_exposure)(struct dt_iop_module_t *exp);
float (*get_black)(struct dt_iop_module_t *exp);
void (*handle_event)(GdkEvent *event, gboolean blackwhite);
void (*handle_event)(gpointer, int, gdouble, const gboolean);
} dt_dev_proxy_exposure_t;

struct dt_dev_pixelpipe_t;
Expand Down Expand Up @@ -471,7 +471,7 @@ float dt_dev_exposure_get_exposure(dt_develop_t *dev);
/** get exposure black level */
float dt_dev_exposure_get_black(dt_develop_t *dev);

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

/*
* modulegroups plugin hooks
Expand Down
22 changes: 2 additions & 20 deletions src/gui/accelerators.c
Original file line number Diff line number Diff line change
Expand Up @@ -919,7 +919,7 @@ static gchar *_shortcut_lua_command(GtkWidget *widget,

if(DT_IS_BAUHAUS_WIDGET(widget) && s->element == DT_ACTION_ELEMENT_DEFAULT)
{
if(DT_BAUHAUS_WIDGET(widget)->type == DT_BAUHAUS_COMBOBOX)
if(dt_bauhaus_widget_get_type(widget) == DT_BAUHAUS_COMBOBOX)
{
int value = GPOINTER_TO_INT(dt_bauhaus_combobox_get_data(widget));
dt_introspection_type_enum_tuple_t *values
Expand Down Expand Up @@ -1034,8 +1034,7 @@ gboolean dt_shortcut_tooltip_callback(GtkWidget *widget,
int show_element = 0;
dt_shortcut_t lua_shortcut = { .speed = 1.0 };

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

if(!strcmp(widget_name, "actions_view") || !strcmp(widget_name, "shortcuts_view"))
Expand Down Expand Up @@ -1129,23 +1128,6 @@ gboolean dt_shortcut_tooltip_callback(GtkWidget *widget,
_("scroll to change default speed"),
_("right-click to exit mapping mode"));
}
else if(DT_IS_BAUHAUS_WIDGET(widget)
&& DT_BAUHAUS_WIDGET(widget)->type == DT_BAUHAUS_SLIDER
&& darktable.control->element == 2) // DT_ACTION_ELEMENT_FORCE
{
float hard_min = dt_bauhaus_slider_get_hard_min(widget);
float hard_max = dt_bauhaus_slider_get_hard_max(widget);
if(dt_bauhaus_slider_get_soft_min(widget) != hard_min ||
dt_bauhaus_slider_get_soft_max(widget) != hard_max)
{
dt_util_str_cat(&original_markup,
_("%sright-click to type a specific value between <b>%s</b> and <b>%s</b>"
"\nor hold ctrl+shift while dragging to ignore soft limits."),
original_markup ? "\n\n" : "",
dt_bauhaus_slider_get_text(widget, hard_min),
dt_bauhaus_slider_get_text(widget, hard_max));
}
}
}

if(!def) def = _action_find_definition(action);
Expand Down
58 changes: 46 additions & 12 deletions src/gui/gtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -3595,28 +3595,26 @@ static void _notebook_size_callback(GtkNotebook *notebook,
// GTK_STATE_FLAG_PRELIGHT does not seem to get set on the label on
// hover so state-flags-changed cannot update
// darktable.control->element for shortcut mapping
static gboolean _notebook_motion_notify_callback(GtkWidget *widget,
const GdkEventMotion *event,
gpointer user_data)
static void _notebook_motion_notify_callback(GtkEventControllerMotion *controller,
double x,
double y,
GtkNotebook *notebook)
{
GtkAllocation notebook_alloc, label_alloc;
gtk_widget_get_allocation(widget, &notebook_alloc);
gtk_widget_get_allocation(GTK_WIDGET(notebook), &notebook_alloc);

GtkNotebook *notebook = GTK_NOTEBOOK(widget);
const int n = gtk_notebook_get_n_pages(notebook);
for(int i = 0; i < n; i++)
{
gtk_widget_get_allocation(gtk_notebook_get_tab_label
(notebook, gtk_notebook_get_nth_page(notebook, i)),
&label_alloc);
if(event->x + notebook_alloc.x < label_alloc.x + label_alloc.width)
if(x + notebook_alloc.x < label_alloc.x + label_alloc.width)
{
darktable.control->element = i;
break;
}
}

return FALSE;
}

static float _action_process_tabs(const gpointer target,
Expand Down Expand Up @@ -3739,7 +3737,7 @@ static gboolean _notebook_button_press_callback(GtkNotebook *notebook,
const GdkEventButton *event,
gpointer user_data)
{
if(event->type == GDK_2BUTTON_PRESS)
if(event->type == GDK_2BUTTON_PRESS && gtk_get_event_widget((GdkEvent*)event) == GTK_WIDGET(notebook))
_reset_all_bauhaus(notebook, gtk_notebook_get_nth_page(notebook, gtk_notebook_get_current_page(notebook)));

return FALSE;
Expand Down Expand Up @@ -3770,8 +3768,7 @@ GtkWidget *dt_ui_notebook_page(GtkNotebook *notebook,
{
g_signal_connect(G_OBJECT(notebook), "size-allocate",
G_CALLBACK(_notebook_size_callback), NULL);
g_signal_connect(G_OBJECT(notebook), "motion-notify-event",
G_CALLBACK(_notebook_motion_notify_callback), NULL);
dt_gui_connect_motion(notebook, _notebook_motion_notify_callback, NULL, NULL, notebook);
g_signal_connect(G_OBJECT(notebook), "scroll-event",
G_CALLBACK(_notebook_scroll_callback), NULL);
g_signal_connect(G_OBJECT(notebook), "button-press-event",
Expand Down Expand Up @@ -4396,6 +4393,43 @@ gboolean dt_gui_long_click(const guint second,
return second - delay > first;
}

GtkGestureSingle *(dt_gui_connect_click)(GtkWidget *widget,
GCallback pressed,
GCallback released,
gpointer data)
{
GtkGesture *gesture = gtk_gesture_multi_press_new(widget);
g_object_weak_ref(G_OBJECT (widget), (GWeakNotify) g_object_unref, gesture);
// GTK4 GtkGesture *gesture = gtk_gesture_click_new();
// gtk_widget_add_controller(widget, GTK_EVENT_CONTROLLER(gesture));

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);
gtk_event_controller_set_propagation_phase(controller, GTK_PHASE_TARGET);
g_object_weak_ref(G_OBJECT (widget), (GWeakNotify) g_object_unref, controller);
// GTK4 gtk_widget_add_controller(widget, GTK_EVENT_CONTROLLER(controller));

gtk_widget_add_events(widget, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); // still needed for now by _main_do_event_keymap

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;
}


static int busy_nest_count = 0;
static GdkCursor* busy_prev_cursor = NULL;

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

return GTK_WIDGET(box);
Expand Down
31 changes: 31 additions & 0 deletions src/gui/gtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,37 @@ void dt_gui_hide_collapsible_section(const dt_gui_collapsible_section_t *cs);
gboolean dt_gui_long_click(const guint second,
const guint first);

#define ASSERT_FUNC_TYPE(func, expected_type) (void)(1 ? (func) : (expected_type)0)

GtkGestureSingle *(dt_gui_connect_click)(GtkWidget *widget,
GCallback pressed,
GCallback released,
gpointer data);
#define dt_gui_connect_click(widget, pressed, released, data) ( \
ASSERT_FUNC_TYPE(pressed, void(*)(GtkGestureSingle *, int, double, double, __typeof__(data))), \
ASSERT_FUNC_TYPE(released, void(*)(GtkGestureSingle *, int, double, double, __typeof__(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) ( \
ASSERT_FUNC_TYPE(motion, void(*)(GtkEventControllerMotion *, double, double, __typeof__(data))), \
ASSERT_FUNC_TYPE(enter, void(*)(GtkEventControllerMotion *, double, double, __typeof__(data))), \
ASSERT_FUNC_TYPE(leave, void(*)(GtkEventControllerMotion *, __typeof__(data))), \
dt_gui_connect_motion(GTK_WIDGET(widget), G_CALLBACK(motion), G_CALLBACK(enter), G_CALLBACK(leave), (data)))

// GTK4 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)

// control whether the mouse pointer displays as a "busy" cursor, e.g. watch or timer
// the calls may be nested, but must be matched
void dt_gui_cursor_set_busy();
Expand Down
24 changes: 18 additions & 6 deletions src/iop/exposure.c
Original file line number Diff line number Diff line change
Expand Up @@ -814,25 +814,37 @@ static float _exposure_proxy_get_black(dt_iop_module_t *self)
}


static void _exposure_proxy_handle_event(GdkEvent *event, const gboolean blackwhite)
static void _exposure_proxy_handle_event(gpointer controller,
int n_press,
double x,
const gboolean blackwhite)
{
dt_iop_module_t *self = darktable.develop->proxy.exposure.module;
if(self && self->gui_data)
{
static gboolean black = FALSE;
if(event->type == GDK_BUTTON_PRESS || event->type == GDK_SCROLL)
if((n_press > 0 && GTK_IS_GESTURE_SINGLE(controller)) // button press
|| !n_press) // scroll event
black = blackwhite;

if(black)
event->button.x *= -1;
x *= -1;

const dt_iop_exposure_params_t *p = self->params;
dt_iop_exposure_gui_data_t *g = self->gui_data;
GtkWidget *widget = black ? g->black :
p->mode == EXPOSURE_MODE_DEFLICKER
? g->deflicker_target_level : g->exposure;
gtk_widget_realize(widget);
gtk_widget_event(widget, event);
? g->deflicker_target_level : g->exposure;
if(!n_press)
darktable.bauhaus->scroll(widget, controller);
else
if(GTK_IS_GESTURE_SINGLE(controller))
if(n_press > 0)
darktable.bauhaus->press(controller, n_press, x, 0, widget);
else
darktable.bauhaus->release(controller, -n_press, x, 0, widget);
else
darktable.bauhaus->motion(controller, x, 0, widget);

gchar *text = dt_bauhaus_slider_get_text(widget, dt_bauhaus_slider_get(widget));
dt_action_widget_toast(DT_ACTION(self), widget, "%s", text);
Expand Down
4 changes: 2 additions & 2 deletions src/libs/filtering.c
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,7 @@ static gboolean _widget_init(dt_lib_filtering_rule_t *rule, const dt_collection_

// operator type
rule->w_operator = dt_bauhaus_combobox_new(NULL);
DT_BAUHAUS_WIDGET(rule->w_operator)->show_quad = FALSE;
dt_bauhaus_widget_set_quad_visibility(rule->w_operator, FALSE);
dt_bauhaus_combobox_add_aligned(rule->w_operator, _("and"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT);
dt_bauhaus_combobox_add_aligned(rule->w_operator, _("or"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT);
dt_bauhaus_combobox_add_aligned(rule->w_operator, _("and not"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT);
Expand All @@ -1264,7 +1264,7 @@ static gboolean _widget_init(dt_lib_filtering_rule_t *rule, const dt_collection_
{
rule->w_prop = dt_bauhaus_combobox_new(NULL);
dt_bauhaus_combobox_set_selected_text_align(rule->w_prop, DT_BAUHAUS_COMBOBOX_ALIGN_MIDDLE);
DT_BAUHAUS_WIDGET(rule->w_prop)->show_quad = FALSE;
dt_bauhaus_widget_set_quad_visibility(rule->w_prop, FALSE);
_rule_populate_prop_combo(rule);
g_object_set_data(G_OBJECT(rule->w_prop), "rule", rule);
dt_bauhaus_combobox_set_from_value(rule->w_prop, prop);
Expand Down
Loading
Loading