diff --git a/DefineOptions.cmake b/DefineOptions.cmake index 729faed12ecb..2c1f64f2a4cd 100644 --- a/DefineOptions.cmake +++ b/DefineOptions.cmake @@ -1,20 +1,20 @@ -option(USE_CAMERA_SUPPORT "Detect and use camera support if available." ON) -option(USE_COLORD "Enable colord support" ON) -option(USE_MAP "Build Map View parts" ON) -option(USE_LUA "Build lua scripting support" ON) +option(USE_CAMERA_SUPPORT "Detect and use camera support if available." OFF) +option(USE_COLORD "Enable colord support" OFF) +option(USE_MAP "Build Map View parts" OFF) +option(USE_LUA "Build lua scripting support" OFF) option(DONT_USE_INTERNAL_LUA "Never fall back to the intree copy of lua" ON) -option(USE_KWALLET "Build kwallet password storage back-end" ON) -option(USE_LIBSECRET "Build libsecret password storage back-end" ON) +option(USE_KWALLET "Build kwallet password storage back-end" OFF) +option(USE_LIBSECRET "Build libsecret password storage back-end" OFF) option(USE_UNITY "Use libunity to report progress in the launcher" OFF) option(USE_OPENMP "Use OpenMP threading support." ON) option(USE_OPENCL "Use OpenCL support." ON) -option(USE_GRAPHICSMAGICK "Use GraphicsMagick library for image import." ON) +option(USE_GRAPHICSMAGICK "Use GraphicsMagick library for image import." OFF) option(USE_IMAGEMAGICK "Use ImageMagick library for image import." OFF) option(USE_DARKTABLE_PROFILING OFF) option(CUSTOM_CFLAGS "Don't override compiler optimization flags." OFF) option(BINARY_PACKAGE_BUILD "Sets march optimization to generic" OFF) option(USE_XMLLINT "Run xmllint to test if darktableconfig.xml is valid" ON) -option(USE_PORTMIDI "Enable MIDI device support using PortMidi" ON) +option(USE_PORTMIDI "Enable MIDI device support using PortMidi" OFF) option(USE_OPENJPEG "Enable JPEG 2000 support" ON) option(USE_JXL "Enable JPEG XL support" ON) option(USE_WEBP "Enable WebP support" ON) @@ -26,17 +26,17 @@ option(USE_LIBRAW "Enable LibRaw support" ON) option(DONT_USE_INTERNAL_LIBRAW "If possible, use system instead of intree copy of LibRaw" OFF) option(BUILD_CMSTEST "Build a test program to check your system's color management setup" ON) option(USE_OPENEXR "Enable OpenEXR support" ON) -option(BUILD_PRINT "Build the print module" ON) +option(BUILD_PRINT "Build the print module" OFF) option(BUILD_RS_IDENTIFY "Build the darktable-rs-identify debug aid" ON) option(BUILD_SSE2_CODEPATHS "(EXPERIMENTAL OPTION, DO NOT DISABLE) Building SSE2-optimized codepaths" ON) option(VALIDATE_APPDATA_FILE "Use appstream-util (if found) to validate the .appdata file" OFF) option(BUILD_MSYS2_INSTALL "Build an MSYS2 version of the install, aka for Windows platform, but without dependency installs" OFF) option(BUILD_NOISE_TOOLS "Build tools for generating noise profiles" OFF) option(BUILD_CURVE_TOOLS "Build tools for generating base and tone curves" OFF) -option(USE_GMIC "Use G'MIC image processing framework." ON) +option(USE_GMIC "Use G'MIC image processing framework." OFF) option(USE_ICU "Use ICU - International Components for Unicode." ON) option(FORCE_COLORED_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." OFF) -option(USE_SDL2 "Enable SDL2 support" ON) +option(USE_SDL2 "Enable SDL2 support" OFF) if (USE_OPENCL) option(TESTBUILD_OPENCL_PROGRAMS "Test-compile OpenCL programs (needs LLVM and Clang 7+)" ON) @@ -45,7 +45,7 @@ else () endif () if(APPLE) - option(USE_MAC_INTEGRATION "Enable macOS integration" ON) + option(USE_MAC_INTEGRATION "Enable macOS integration" OFF) else(APPLE) set(USE_MAC_INTEGRATION OFF) endif(APPLE) diff --git a/cmake/modules/FindGTK4.cmake b/cmake/modules/FindGTK4.cmake new file mode 100644 index 000000000000..ef28243e33a4 --- /dev/null +++ b/cmake/modules/FindGTK4.cmake @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.18) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK4 REQUIRED IMPORTED_TARGET gtk4) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 07dbcdd5669f..e31f8215e4a3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -124,7 +124,6 @@ FILE(GLOB SOURCE_FILES "dtgtk/drawingarea.c" "dtgtk/expander.c" "dtgtk/gradientslider.c" - "dtgtk/icon.c" "dtgtk/paint.c" "dtgtk/range.c" "dtgtk/resetlabel.c" @@ -294,11 +293,11 @@ include_directories(SYSTEM ${Glib_INCLUDE_DIRS}) list(APPEND LIBS ${Glib_LIBRARIES}) # GTK3 pulls in ATK, GDK, GDK-PIXBUF, CAIRO, GLIB, PANGO -find_package(GTK3 3.24.15 REQUIRED) -add_definitions("-DGDK_VERSION_MIN_REQUIRED=GDK_VERSION_3_24") -#add_definitions("-DGDK_VERSION_MAX_ALLOWED=GDK_VERSION_MIN_REQUIRED") -include_directories(SYSTEM ${GTK3_INCLUDE_DIRS}) -list(APPEND LIBS ${GTK3_LIBRARIES}) +find_package(GTK4 4.8.3 REQUIRED) +add_definitions("-DGDK_VERSION_MIN_REQUIRED=GDK_VERSION_4_0") +add_definitions("-DGDK_VERSION_MAX_ALLOWED=GDK_VERSION_4_18") +include_directories(SYSTEM ${GTK4_INCLUDE_DIRS}) +list(APPEND LIBS ${GTK4_LIBRARIES}) # Check for libxml2 / broken cmake module can't be included in the foreach() below find_package(LibXml2 2.6 REQUIRED) diff --git a/src/bauhaus/bauhaus.c b/src/bauhaus/bauhaus.c index 3b42552261fa..02fcceff9fc8 100644 --- a/src/bauhaus/bauhaus.c +++ b/src/bauhaus/bauhaus.c @@ -23,15 +23,13 @@ #include "control/conf.h" #include "develop/develop.h" #include "develop/imageop.h" +#include "dtgtk/drawingarea.h" #include "gui/accelerators.h" #include "gui/color_picker_proxy.h" #include "gui/gtk.h" #ifdef GDK_WINDOWING_QUARTZ #include "osx/osx.h" #endif -#ifdef GDK_WINDOWING_WAYLAND -#include -#endif #include @@ -766,7 +764,7 @@ static void _widget_finalize(GObject *widget) void dt_bauhaus_load_theme() { GtkWidget *root_window = dt_ui_main_window(darktable.gui->ui); - GtkStyleContext *ctx = gtk_style_context_new(); + GtkStyleContext *ctx = gtk_widget_get_style_context(root_window); GtkWidgetPath *path = gtk_widget_path_new(); const int pos = gtk_widget_path_append_type(path, GTK_TYPE_WIDGET); gtk_widget_path_iter_add_class(path, pos, "dt_bauhaus"); @@ -1128,7 +1126,7 @@ gchar *dt_bauhaus_widget_get_tooltip_markup(GtkWidget *widget, && DT_IS_BAUHAUS_WIDGET(widget) && DT_BAUHAUS_WIDGET(widget)->tooltip ? g_markup_escape_text(DT_BAUHAUS_WIDGET(widget)->tooltip, -1) - : gtk_widget_get_tooltip_markup(widget); + : g_strdup(gtk_widget_get_tooltip_markup(widget)); if(!darktable.control->mapping_widget && dt_bauhaus_widget_get_type(widget) == DT_BAUHAUS_SLIDER) { @@ -2606,11 +2604,17 @@ static gboolean _popup_draw(GtkWidget *widget, return TRUE; } -static gboolean _widget_draw(GtkWidget *widget, - cairo_t *cr) + +static void _widget_snapshot(GtkWidget* widget, + GtkSnapshot* snapshot) { GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); + + graphene_rect_t bounds; + graphene_rect_init(&bounds, 0, 0, allocation.width, allocation.height); + cairo_t* cr = gtk_snapshot_append_cairo(snapshot, &bounds); + dt_bauhaus_widget_t *w = DT_BAUHAUS_WIDGET(widget); const int width = allocation.width, height = allocation.height; GtkStyleContext *context = gtk_widget_get_style_context(widget); @@ -2624,7 +2628,9 @@ static gboolean _widget_draw(GtkWidget *widget, gtk_style_context_get_color(context, state, text_color); gtk_style_context_get_color(context, state, fg_color); - gtk_style_context_get(context, state, "background-color", &bg_color, NULL); + // gtk_style_context_get(context, state, "background-color", &bg_color, NULL); + GdkRGBA color = {.red = 0.0f, .green = 0.0f, .blue = 0.0f, .alpha = 1.0f}; + bg_color = gdk_rgba_copy(&color); // translate to account for the widget spacing const int h2 = height - w->margin.top - w->margin.bottom; @@ -2759,8 +2765,6 @@ static gboolean _widget_draw(GtkWidget *widget, gdk_rgba_free(text_color); gdk_rgba_free(fg_color); gdk_rgba_free(bg_color); - - return TRUE; } static gint _natural_width(GtkWidget *widget, @@ -2832,34 +2836,35 @@ static gint _natural_width(GtkWidget *widget, return natural_size; } -static void _widget_get_preferred_width(GtkWidget *widget, - gint *minimum_width, - gint *natural_width) -{ - dt_bauhaus_widget_t *w = (dt_bauhaus_widget_t *)widget; - _margins_retrieve(w); - - *natural_width = _natural_width(widget, FALSE) - + w->margin.left + w->margin.right + w->padding.left + w->padding.right; -} - -static void _widget_get_preferred_height(GtkWidget *widget, - gint *minimum_height, - gint *natural_height) +static void _widget_measure(GtkWidget* widget, + GtkOrientation orientation, + int for_size, + int* minimum, + int* natural, + int* minimum_baseline, + int* natural_baseline) { dt_bauhaus_widget_t *w = (dt_bauhaus_widget_t *)widget; _margins_retrieve(w); - - *minimum_height = w->margin.top + w->margin.bottom + w->padding.top + w->padding.bottom - + darktable.bauhaus->line_height; - if(w->type == DT_BAUHAUS_SLIDER) + if(orientation == GTK_ORIENTATION_HORIZONTAL) { - // the lower thing to draw is indicator. See _draw_baseline for compute details - *minimum_height += INNER_PADDING - + darktable.bauhaus->baseline_size + 1.5f * darktable.bauhaus->border_width; + + *natural = _natural_width(widget, FALSE) + + w->margin.left + w->margin.right + w->padding.left + w->padding.right; } + else + { + *minimum = w->margin.top + w->margin.bottom + w->padding.top + w->padding.bottom + + darktable.bauhaus->line_height; + if(w->type == DT_BAUHAUS_SLIDER) + { + // the lower thing to draw is indicator. See _draw_baseline for compute details + *minimum += INNER_PADDING + + darktable.bauhaus->baseline_size + 1.5f * darktable.bauhaus->border_width; + } - *natural_height = *minimum_height; + *natural = *minimum; + } } static void _popup_hide() @@ -2886,6 +2891,7 @@ static void _popup_hide() static void _popup_show(GtkWidget *widget) { + return; // GTK4 dt_bauhaus_widget_t *w = DT_BAUHAUS_WIDGET(widget); dt_bauhaus_t *bh = darktable.bauhaus; dt_bauhaus_popup_t *pop = &bh->popup; @@ -3064,19 +3070,21 @@ static void _slider_add_step(GtkWidget *widget, dt_bauhaus_slider_set(widget, CLAMP(value + delta, d->min, d->max)); } -static gboolean _widget_scroll(GtkWidget *widget, - GdkEventScroll *event) +static gboolean _widget_scroll(GtkEventControllerScroll* self, + gdouble dx, + gdouble dy, + GtkWidget *widget) { - if(dt_gui_ignore_scroll(event)) return FALSE; +// GTK4 +// if(dt_gui_ignore_scroll(event)) return FALSE; - // handle speed adjustment in mapping mode in dispatcher - if(darktable.control->mapping_widget) - return dt_shortcut_dispatcher(widget, (GdkEvent*)event, NULL); +// // handle speed adjustment in mapping mode in dispatcher +// if(darktable.control->mapping_widget) +// return dt_shortcut_dispatcher(widget, (GdkEvent*)event, NULL); gtk_widget_grab_focus(widget); - int delta_y = 0; - if(dt_gui_get_scroll_unit_delta(event, &delta_y)) + int delta_y = dx + dy; { if(delta_y == 0) return TRUE; @@ -3085,15 +3093,17 @@ static gboolean _widget_scroll(GtkWidget *widget, if(w->type == DT_BAUHAUS_SLIDER) { - gboolean force = darktable.control->element == DT_ACTION_ELEMENT_FORCE - && event->window == gtk_widget_get_window(widget); - if(force && dt_modifier_is(event->state, GDK_SHIFT_MASK | GDK_CONTROL_MASK)) - { - _slider_zoom_range(w, delta_y); - _slider_zoom_toast(w); - } - else - _slider_add_step(widget, - delta_y, event->state, force); + // GTK4 + // gboolean force = darktable.control->element == DT_ACTION_ELEMENT_FORCE + // && event->window == gtk_widget_get_window(widget); + // if(force && dt_modifier_is(event->state, GDK_SHIFT_MASK | GDK_CONTROL_MASK)) + // { + // _slider_zoom_range(w, delta_y); + // _slider_zoom_toast(w); + // } + // else + // _slider_add_step(widget, - delta_y, event->state, force); + _slider_add_step(widget, - delta_y, gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(self)), FALSE); } else _combobox_next_sensitive(w, delta_y, 0, FALSE); @@ -3556,7 +3566,7 @@ static void _widget_button_press(GtkGestureSingle *gesture, } else if(button == GDK_BUTTON_SECONDARY || w->type == DT_BAUHAUS_COMBOBOX) { - bh->opentime = gdk_event_get_time(gtk_get_current_event()); + bh->opentime = gtk_event_controller_get_current_event_time(GTK_EVENT_CONTROLLER(gesture)); bh->mouse_x = x; bh->mouse_y = y; _popup_show(widget); @@ -3669,20 +3679,17 @@ static void dt_bh_class_init(DtBauhausWidgetClass *class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(class); - widget_class->draw = _widget_draw; - // widget_class->snapshot = _widget_snapshot; - widget_class->scroll_event = _widget_scroll; - widget_class->key_press_event = _widget_key_press; - widget_class->get_preferred_width = _widget_get_preferred_width; - widget_class->get_preferred_height = _widget_get_preferred_height; - // widget_class->measure = _widget_measure; + widget_class->snapshot = _widget_snapshot; + // widget_class->scroll_event = _widget_scroll; + // widget_class->key_press_event = _widget_key_press; + widget_class->measure = _widget_measure; G_OBJECT_CLASS(class)->finalize = _widget_finalize; // for histogram -> exposure proxy bh->press = _widget_button_press; bh->release = _widget_button_release; bh->motion = _widget_motion; - bh->scroll = _widget_scroll; + // bh->scroll = _widget_scroll; GTK4 } static void dt_bh_init(DtBauhausWidget *w) @@ -3707,9 +3714,9 @@ static void dt_bh_init(DtBauhausWidget *w) dt_gui_connect_motion(w, _widget_motion, _widget_enter, _widget_leave, widget); - // GtkEventController *controller = gtk_event_controller_scroll_new(GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES | GTK_EVENT_CONTROLLER_SCROLL_DISCRETE); - // gtk_widget_add_controller(GTK_WIDGET(w), GTK_EVENT_CONTROLLER(controller)); - // g_signal_connect(controller, "scroll", G_CALLBACK(_widget_scroll), w); + GtkEventController *controller = gtk_event_controller_scroll_new(GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES | GTK_EVENT_CONTROLLER_SCROLL_DISCRETE); + gtk_widget_add_controller(GTK_WIDGET(w), GTK_EVENT_CONTROLLER(controller)); + g_signal_connect(controller, "scroll", G_CALLBACK(_widget_scroll), w); gtk_widget_set_can_focus(widget, TRUE); dt_gui_add_class(widget, "dt_bauhaus"); diff --git a/src/common/darktable.c b/src/common/darktable.c index 27aba5d0254b..455fa23529ca 100644 --- a/src/common/darktable.c +++ b/src/common/darktable.c @@ -1895,6 +1895,18 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load dt_view_manager_gui_init(darktable.view_manager); } + + + + + + // g_log_set_always_fatal(G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL); + + + + + + /* init lua last, since it's user made stuff it must be in the real environment */ #ifdef USE_LUA darktable_splash_screen_set_progress(_("initializing Lua")); @@ -2657,6 +2669,386 @@ void dt_print_mem_usage(char *info) #endif } + + + + + + +// GTK4 + + +void gtk_container_add(GtkContainer *container, GtkWidget *child) +{ + g_return_if_fail(GTK_IS_WIDGET (container)); + g_return_if_fail(GTK_IS_WIDGET (child)); + + if(GTK_IS_BOX(container)) + { + gtk_box_append(GTK_BOX (container), child); + } + else if(GTK_IS_GRID(container)) + { + gtk_grid_attach (GTK_GRID (container), child, 0, 0, 1, 1); + } + else if(GTK_IS_OVERLAY(container)) + { + gtk_overlay_set_child(GTK_OVERLAY(container), child); + } + else if(GTK_IS_SCROLLED_WINDOW(container)) + { + gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(container), child); + } + else if(GTK_IS_FRAME(container)) + { + gtk_frame_set_child(GTK_FRAME(container), child); + } + else if(GTK_IS_WINDOW(container)) + { + gtk_window_set_child(GTK_WINDOW(container), child); + } + else if(GTK_IS_EXPANDER(container)) + { + gtk_expander_set_child(GTK_EXPANDER(container), child); + } + else if(GTK_IS_LIST_BOX(container)) + { + gtk_list_box_append(GTK_LIST_BOX (container), child); + } + else if(GTK_IS_STACK (container)) + { + gtk_stack_add_named(GTK_STACK(container), child, G_OBJECT_TYPE_NAME(child)); + } + else if(GTK_IS_NOTEBOOK(container)) + { + gtk_notebook_append_page(GTK_NOTEBOOK (container), child, NULL); + } + else if(GTK_IS_POPOVER(container)) + { + gtk_popover_set_child(GTK_POPOVER(container), child); + } + else if(GTK_IS_VIEWPORT(container)) + { + gtk_viewport_set_child(GTK_VIEWPORT(container), child); + } + else if(GTK_IS_BUTTON(container)) + { + gtk_button_set_child(GTK_BUTTON(container), child); + } + else if(GTK_IS_CHECK_BUTTON(container)) + { + gtk_check_button_set_child(GTK_CHECK_BUTTON(container), child); + } + else if(GTK_IS_REVEALER(container)) + { + gtk_revealer_set_child(GTK_REVEALER(container), child); + } + else if(GTK_IS_FLOW_BOX(container)) + { + gtk_flow_box_append(GTK_FLOW_BOX(container), child); + } + else { + g_warning("gtk_container_add: unsupported container type %s", + G_OBJECT_TYPE_NAME (container)); + } +} + +GtkWidget *gtk_bin_get_child(gpointer bin) +{ + g_return_val_if_fail(GTK_IS_WIDGET (bin), NULL); + + if(GTK_IS_OVERLAY(bin)) + { + return gtk_overlay_get_child(GTK_OVERLAY(bin)); + } + else if(GTK_IS_SCROLLED_WINDOW(bin)) + { + return gtk_scrolled_window_get_child(GTK_SCROLLED_WINDOW(bin)); + } + else if(GTK_IS_FRAME(bin)) + { + return gtk_frame_get_child(GTK_FRAME(bin)); + } + else if(GTK_IS_WINDOW(bin)) + { + return gtk_window_get_child(GTK_WINDOW(bin)); + } + else if(GTK_IS_EXPANDER(bin)) + { + return gtk_expander_get_child(GTK_EXPANDER(bin)); + } + else if(GTK_IS_POPOVER(bin)) + { + return gtk_popover_get_child(GTK_POPOVER(bin)); + } + else if(GTK_IS_VIEWPORT(bin)) + { + return gtk_viewport_get_child(GTK_VIEWPORT(bin)); + } + else if(GTK_IS_BUTTON(bin)) + { + return gtk_button_get_child(GTK_BUTTON(bin)); + } + else if(GTK_IS_CHECK_BUTTON(bin)) + { + static GtkWidget *label = NULL; + // GTK4 check box no longer contains a label object; + // just allow code to gtk_label_set_ellipsize without error + if(!label) label = gtk_label_new(NULL); + return label; + } + else if(GTK_IS_REVEALER(bin)) + { + return gtk_revealer_get_child(GTK_REVEALER(bin)); + } + else { + g_warning("gtk_bin_get_child: unsupported container type %s", + G_OBJECT_TYPE_NAME (bin)); + return NULL; + } +} + +static void _widget_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + GtkWidget *widget) +{ + GdkEventButton event; + memset(&event, 0, sizeof(event)); + event.type = n_press > 1 ? GDK_DOUBLE_BUTTON_PRESS + n_press - 2 : GDK_BUTTON_PRESS; + event.window = gtk_widget_get_window(widget); + event.send_event = TRUE; + event.time = GDK_CURRENT_TIME; + event.x = x; + event.y = y; + event.axes = NULL; + event.state = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(gesture)); + event.button = gtk_gesture_single_get_current_button(gesture); + event.device = gdk_seat_get_pointer(gdk_display_get_default_seat(gdk_display_get_default())); + gboolean ret = FALSE; + g_signal_emit_by_name(widget, "button-press-event", &event, &ret); + if(ret) dt_gui_claim(gesture); +} + +static void _widget_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + GtkWidget *widget) +{ + GdkEventButton event; + memset(&event, 0, sizeof(event)); + event.type = GDK_BUTTON_RELEASE; + event.window = gtk_widget_get_window(widget); + event.send_event = TRUE; + event.time = GDK_CURRENT_TIME; + event.x = x; + event.y = y; + event.axes = NULL; + event.state = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(gesture)); + event.button = gtk_gesture_single_get_current_button(gesture); + event.device = gdk_seat_get_pointer(gdk_display_get_default_seat(gdk_display_get_default())); + gboolean ret = FALSE; + g_signal_emit_by_name(widget, "button-release-event", &event, &ret); + if(ret) dt_gui_claim(gesture); +} + +static void _widget_motion(GtkEventControllerMotion *controller, + double x, + double y, + GtkWidget *widget) +{ + GdkEventMotion event; + memset(&event, 0, sizeof(event)); + event.type = GDK_MOTION_NOTIFY; + event.window = gtk_widget_get_window(widget); + event.send_event = TRUE; + event.time = GDK_CURRENT_TIME; + event.x = x; + event.y = y; + event.axes = NULL; + event.state = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(controller)); + event.device = gdk_seat_get_pointer(gdk_display_get_default_seat(gdk_display_get_default())); + gboolean ret = FALSE; + g_signal_emit_by_name(widget, "motion-notify-event", &event, &ret); +} + +static void _widget_enter(GtkEventControllerMotion *controller, + double x, + double y, + GtkWidget *widget) +{ + GdkEventCrossing event; + memset(&event, 0, sizeof(event)); + event.type = GDK_ENTER_NOTIFY; + event.window = gtk_widget_get_window(widget); + event.send_event = TRUE; + event.time = GDK_CURRENT_TIME; + event.x = x; + event.y = y; + event.state = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(controller)); + gboolean ret = FALSE; + g_signal_emit_by_name(widget, "enter-notify-event", &event, &ret); +} + +static void _widget_leave(GtkEventControllerMotion *controller, + GtkWidget *widget) +{ + GdkEventCrossing event; + memset(&event, 0, sizeof(event)); + event.type = GDK_LEAVE_NOTIFY; + event.window = gtk_widget_get_window(widget); + event.send_event = TRUE; + event.time = GDK_CURRENT_TIME; + event.state = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(controller)); + gboolean ret = FALSE; + g_signal_emit_by_name(widget, "leave-notify-event", &event, &ret); +} + +static gboolean _widget_scroll(GtkEventControllerScroll* self, + gdouble dx, + gdouble dy, + GtkWidget *widget) +{ + GdkEventScroll event; + memset(&event, 0, sizeof(event)); + event.type = GDK_SCROLL; + event.window = gtk_widget_get_window(widget); + event.send_event = TRUE; + event.time = GDK_CURRENT_TIME; + event.x = 0; + event.y = 0; + event.state = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(self)); + event.direction = GDK_SCROLL_SMOOTH; + event.delta_x = dx; + event.delta_y = dy; + event.device = gdk_seat_get_pointer(gdk_display_get_default_seat(gdk_display_get_default())); + gboolean ret = FALSE; + g_signal_emit_by_name(widget, "scroll-event", &event, &ret); + return ret; +} + +void _map(GtkWidget *widget) +{ + GtkWidgetClass *parent_class = GTK_WIDGET_CLASS(g_type_class_peek_parent(GTK_WIDGET_GET_CLASS(widget))); + parent_class->map(widget); + + gboolean press = g_signal_has_handler_pending(widget, g_signal_lookup("button-press-event", G_TYPE_FROM_INSTANCE(widget)), 0, FALSE); + gboolean release = g_signal_has_handler_pending(widget, g_signal_lookup("button-release-event", G_TYPE_FROM_INSTANCE(widget)), 0, FALSE); + if(press || release) + { + dt_gui_connect_click_all(widget, press ? _widget_button_press: NULL, + release ? _widget_button_release: NULL, widget); + } + gboolean motion = g_signal_has_handler_pending(widget, g_signal_lookup("motion-notify-event", G_TYPE_FROM_INSTANCE(widget)), 0, FALSE); + gboolean enter = g_signal_has_handler_pending(widget, g_signal_lookup("enter-notify-event", G_TYPE_FROM_INSTANCE(widget)), 0, FALSE); + gboolean leave = g_signal_has_handler_pending(widget, g_signal_lookup("leave-notify-event", G_TYPE_FROM_INSTANCE(widget)), 0, FALSE); + if(motion || enter || leave) + { + dt_gui_connect_motion(widget, motion ? _widget_motion : NULL, + enter ? _widget_enter : NULL, + leave ? _widget_leave : NULL, widget); + } + gboolean scroll = g_signal_has_handler_pending(widget, g_signal_lookup("scroll-event", G_TYPE_FROM_INSTANCE(widget)), 0, FALSE); + if(scroll) + { + GtkEventController *controller = gtk_event_controller_scroll_new(GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES | GTK_EVENT_CONTROLLER_SCROLL_DISCRETE); + gtk_widget_add_controller(widget, GTK_EVENT_CONTROLLER(controller)); + g_signal_connect(controller, "scroll", G_CALLBACK(_widget_scroll), widget); + } +} + +void dt_add_legacy_signals(GtkWidgetClass *klass) +{ + klass->map = _map; + g_signal_new ("button-press-event", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_BOOLEAN,// return type + 1, // number of params + G_TYPE_POINTER); + g_signal_new ("button-release-event", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_BOOLEAN, + 1, G_TYPE_POINTER); + g_signal_new ("motion-notify-event", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_BOOLEAN, + 1, G_TYPE_POINTER); + g_signal_new ("enter-notify-event", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_BOOLEAN, + 1, G_TYPE_POINTER); + g_signal_new ("leave-notify-event", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_BOOLEAN, + 1, G_TYPE_POINTER); + g_signal_new ("scroll-event", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_BOOLEAN, + 1, G_TYPE_POINTER); + g_signal_new ("key-press-event", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_BOOLEAN, + 1, G_TYPE_POINTER); + + + + + g_signal_new ("drag-data-received", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 0); + g_signal_new ("drag-motion", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 0); + g_signal_new ("drag-leave", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 0); +} + // 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 diff --git a/src/common/darktable.h b/src/common/darktable.h index 359759598121..4ca3be5d9f0e 100644 --- a/src/common/darktable.h +++ b/src/common/darktable.h @@ -982,6 +982,590 @@ static inline gboolean dt_check_gimpmode_ok(const char *mode) return darktable.gimp.mode ? !darktable.gimp.error && strcmp(darktable.gimp.mode, mode) == 0 : FALSE; } + + + +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-const-variable" +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-value" +#pragma GCC diagnostic ignored "-Wuninitialized" +// #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" +// #pragma GCC diagnostic ignored "-Wimplicit-function-declaration" +#pragma GCC diagnostic ignored "-Wswitch" + +typedef int gboolean; +typedef GtkBoxClass GtkEventBoxClass; +typedef struct {void *dummy;} *GdkAtom; +typedef struct {void *dummy;} GdkWindow; +typedef struct {void *dummy;} GdkScreen; +typedef struct {void *dummy;} GtkContainer; +typedef struct {void *dummy;} GtkMenu; +typedef struct {void *dummy;} GtkMenuItem; +typedef struct {void *dummy;} GtkMenuShell; +typedef struct {void *dummy;} GdkDragContext; +typedef struct {void *dummy;} GdkVisual; +typedef struct {void *dummy;} GtkSelectionData; +typedef struct {void *dummy;} GtkWidgetPath; +typedef struct {void *dummy;} GdkKeymap; +typedef struct {void *dummy;} GtkTargetList; +typedef struct {void *dummy;} GtkFileChooserButton; +typedef struct {void *dummy;} GtkRadioButton; + +typedef enum +{ + GDK_X_CURSOR = 0, + GDK_ARROW = 2, + GDK_BASED_ARROW_DOWN = 4, + GDK_BASED_ARROW_UP = 6, + GDK_BOAT = 8, + GDK_BOGOSITY = 10, + GDK_BOTTOM_LEFT_CORNER = 12, + GDK_BOTTOM_RIGHT_CORNER = 14, + GDK_BOTTOM_SIDE = 16, + GDK_BOTTOM_TEE = 18, + GDK_BOX_SPIRAL = 20, + GDK_CENTER_PTR = 22, + GDK_CIRCLE = 24, + GDK_CLOCK = 26, + GDK_COFFEE_MUG = 28, + GDK_CROSS = 30, + GDK_CROSS_REVERSE = 32, + GDK_CROSSHAIR = 34, + GDK_DIAMOND_CROSS = 36, + GDK_DOT = 38, + GDK_DOTBOX = 40, + GDK_DOUBLE_ARROW = 42, + GDK_DRAFT_LARGE = 44, + GDK_DRAFT_SMALL = 46, + GDK_DRAPED_BOX = 48, + GDK_EXCHANGE = 50, + GDK_FLEUR = 52, + GDK_GOBBLER = 54, + GDK_GUMBY = 56, + GDK_HAND1 = 58, + GDK_HAND2 = 60, + GDK_HEART = 62, + GDK_ICON = 64, + GDK_IRON_CROSS = 66, + GDK_LEFT_PTR = 68, + GDK_LEFT_SIDE = 70, + GDK_LEFT_TEE = 72, + GDK_LEFTBUTTON = 74, + GDK_LL_ANGLE = 76, + GDK_LR_ANGLE = 78, + GDK_MAN = 80, + GDK_MIDDLEBUTTON = 82, + GDK_MOUSE = 84, + GDK_PENCIL = 86, + GDK_PIRATE = 88, + GDK_PLUS = 90, + GDK_QUESTION_ARROW = 92, + GDK_RIGHT_PTR = 94, + GDK_RIGHT_SIDE = 96, + GDK_RIGHT_TEE = 98, + GDK_RIGHTBUTTON = 100, + GDK_RTL_LOGO = 102, + GDK_SAILBOAT = 104, + GDK_SB_DOWN_ARROW = 106, + GDK_SB_H_DOUBLE_ARROW = 108, + GDK_SB_LEFT_ARROW = 110, + GDK_SB_RIGHT_ARROW = 112, + GDK_SB_UP_ARROW = 114, + GDK_SB_V_DOUBLE_ARROW = 116, + GDK_SHUTTLE = 118, + GDK_SIZING = 120, + GDK_SPIDER = 122, + GDK_SPRAYCAN = 124, + GDK_STAR = 126, + GDK_TARGET = 128, + GDK_TCROSS = 130, + GDK_TOP_LEFT_ARROW = 132, + GDK_TOP_LEFT_CORNER = 134, + GDK_TOP_RIGHT_CORNER = 136, + GDK_TOP_SIDE = 138, + GDK_TOP_TEE = 140, + GDK_TREK = 142, + GDK_UL_ANGLE = 144, + GDK_UMBRELLA = 146, + GDK_UR_ANGLE = 148, + GDK_WATCH = 150, + GDK_XTERM = 152, + GDK_LAST_CURSOR, + GDK_BLANK_CURSOR = -2, + GDK_CURSOR_IS_PIXMAP = -1 +} GdkCursorType; +typedef struct GtkFileFilterInfo +{ + // GtkFileFilterFlags contains; + + const gchar *filename; + const gchar *uri; + const gchar *display_name; + const gchar *mime_type; +} GtkFileFilterInfo; +typedef enum +{ + GTK_WINDOW_TOPLEVEL, + GTK_WINDOW_POPUP +} GtkWindowType; + +typedef struct GtkTargetEntry +{ + gchar *target; + guint flags; + guint info; +} GtkTargetEntry; +typedef enum +{ + GTK_DRAG_RESULT_SUCCESS, + GTK_DRAG_RESULT_NO_TARGET, + GTK_DRAG_RESULT_USER_CANCELLED, + GTK_DRAG_RESULT_TIMEOUT_EXPIRED, + GTK_DRAG_RESULT_GRAB_BROKEN, + GTK_DRAG_RESULT_ERROR +} GtkDragResult; +typedef enum { + GTK_TARGET_SAME_APP = 1 << 0, /*< nick=same-app >*/ + GTK_TARGET_SAME_WIDGET = 1 << 1, /*< nick=same-widget >*/ + GTK_TARGET_OTHER_APP = 1 << 2, /*< nick=other-app >*/ + GTK_TARGET_OTHER_WIDGET = 1 << 3 /*< nick=other-widget >*/ +} GtkTargetFlags; +typedef enum { + GTK_DEST_DEFAULT_MOTION = 1 << 0, + GTK_DEST_DEFAULT_HIGHLIGHT = 1 << 1, + GTK_DEST_DEFAULT_DROP = 1 << 2, + GTK_DEST_DEFAULT_ALL = 0x07 +} GtkDestDefaults; +typedef enum +{ + GDK_WINDOW_STATE_WITHDRAWN = 1 << 0, + GDK_WINDOW_STATE_ICONIFIED = 1 << 1, + GDK_WINDOW_STATE_MAXIMIZED = 1 << 2, + GDK_WINDOW_STATE_STICKY = 1 << 3, + GDK_WINDOW_STATE_FULLSCREEN = 1 << 4, + GDK_WINDOW_STATE_ABOVE = 1 << 5, + GDK_WINDOW_STATE_BELOW = 1 << 6, + GDK_WINDOW_STATE_FOCUSED = 1 << 7, + GDK_WINDOW_STATE_TILED = 1 << 8, + GDK_WINDOW_STATE_TOP_TILED = 1 << 9, + GDK_WINDOW_STATE_TOP_RESIZABLE = 1 << 10, + GDK_WINDOW_STATE_RIGHT_TILED = 1 << 11, + GDK_WINDOW_STATE_RIGHT_RESIZABLE = 1 << 12, + GDK_WINDOW_STATE_BOTTOM_TILED = 1 << 13, + GDK_WINDOW_STATE_BOTTOM_RESIZABLE = 1 << 14, + GDK_WINDOW_STATE_LEFT_TILED = 1 << 15, + GDK_WINDOW_STATE_LEFT_RESIZABLE = 1 << 16 +} GdkWindowState; + +typedef struct GdkEventCrossing +{ + GdkEventType type; + GdkWindow *window; + gint8 send_event; + GdkWindow *subwindow; + guint32 time; + gdouble x; + gdouble y; + gdouble x_root; + gdouble y_root; + GdkCrossingMode mode; + GdkNotifyType detail; + gboolean focus; + guint state; +} GdkEventCrossing; +typedef struct GdkEventScroll +{ + GdkEventType type; + GdkWindow *window; + gint8 send_event; + guint32 time; + gdouble x; + gdouble y; + guint state; + GdkScrollDirection direction; + GdkDevice *device; + gdouble x_root, y_root; + gdouble delta_x; + gdouble delta_y; + guint is_stop : 1; +} GdkEventScroll; +typedef struct GdkEventKey +{ + GdkEventType type; + GdkWindow *window; + gint8 send_event; + guint32 time; + guint state; + guint keyval; + gint length; + gchar *string; + guint16 hardware_keycode; + guint8 group; + guint is_modifier : 1; +} GdkEventKey; +typedef struct GdkEventButton +{ + GdkEventType type; + GdkWindow *window; + gint8 send_event; + guint32 time; + gdouble x; + gdouble y; + gdouble *axes; + guint state; + guint button; + GdkDevice *device; + gdouble x_root, y_root; +} GdkEventButton; + +typedef struct GdkEventConfigure +{ + GdkEventType type; + GdkWindow *window; + gint8 send_event; + gint x, y; + gint width; + gint height; +} GdkEventConfigure; +typedef struct GdkEventMotion +{ + GdkEventType type; + GdkWindow *window; + gint8 send_event; + guint32 time; + gdouble x; + gdouble y; + gdouble *axes; + guint state; + gint16 is_hint; + GdkDevice *device; + gdouble x_root, y_root; +} GdkEventMotion; +typedef struct GdkEventFocus +{ + GdkEventType type; + GdkWindow *window; + gint8 send_event; + gint16 in; +} GdkEventFocus; +typedef struct GdkEventGrabBroken { + GdkEventType type; + GdkWindow *window; + gint8 send_event; + gboolean keyboard; + gboolean implicit; + GdkWindow *grab_window; +} GdkEventGrabBroken; +typedef struct GdkEventWindowState +{ + GdkEventType type; + GdkWindow *window; + gint8 send_event; + GdkWindowState changed_mask; + GdkWindowState new_window_state; +} GdkEventWindowState; + +typedef union GdkEventOld +{ + GdkEventType type; + // GdkEventAny any; + // GdkEventExpose expose; + // GdkEventVisibility visibility; + GdkEventMotion motion; + GdkEventButton button; + // GdkEventTouch touch; + GdkEventScroll scroll; + GdkEventKey key; + GdkEventCrossing crossing; + GdkEventFocus focus_change; + GdkEventConfigure configure; + // GdkEventProperty property; + // GdkEventSelection selection; + // GdkEventOwnerChange owner_change; + // GdkEventProximity proximity; + // GdkEventDND dnd; + GdkEventWindowState window_state; + // GdkEventSetting setting; + GdkEventGrabBroken grab_broken; + // GdkEventTouchpadSwipe touchpad_swipe; + // GdkEventTouchpadPinch touchpad_pinch; + // GdkEventPadButton pad_button; + // GdkEventPadAxis pad_axis; + // GdkEventPadGroupMode pad_group_mode; +} GdkEventOld; +#define GdkEvent GdkEventOld + +#define cairo_pattern_get_rgba(...) NULL +#define g_date_time_get_day_of_month(...) 0 +#define gdk_cairo_surface_create_from_pixbuf(...) NULL +#define gdk_cursor_new_from_surface(...) NULL +#define gdk_device_get_axis_use(...) 0 +#define gdk_device_get_mode(...) 0 +#define gdk_device_get_n_axes(...) 0 +#define gdk_device_get_n_keys(...) 0 +#define gdk_device_get_state(...) NULL +#define gdk_device_get_window_at_position(...) NULL +#define gdk_display_get_default_cursor_size(...) 0 +#define gdk_display_get_monitor_at_window(...) NULL +#define gdk_display_get_monitor(...) NULL +#define gdk_display_get_n_monitors(...) 1 +#define gdk_drag_status(...) +#define gdk_event_free(...) +#define gdk_event_get_axis(...) +#define gdk_event_get_keyval(...) +#define gdk_event_get_pointer_emulated(...) 0 +#define gdk_event_get_source_device(...) NULL +#define gdk_event_handler_set(...) +#define gdk_event_new(...) NULL +#define GDK_IS_WAYLAND_DISPLAY(...) 0 +#define gdk_keymap_get_entries_for_keyval(...) 0 +#define gdk_keymap_get_for_display(...) NULL +#define gdk_keymap_get_modifier_mask(...) 0 +#define gdk_keymap_get_modifier_state(...) 0 +#define gdk_keymap_translate_keyboard_state(...) 0 +#define gdk_monitor_get_workarea(...) +#define gdk_property_get(...) +#define gdk_screen_get_default(...) NULL +#define gdk_screen_get_resolution(...) 0 +#define gdk_screen_get_rgba_visual(...) NULL +#define gdk_screen_set_resolution(...) +#define gdk_seat_get_slaves(...) NULL +#define gdk_seat_grab(...) +#define gdk_seat_ungrab(...) +#define gdk_threads_add_idle(...) +#define gdk_window_get_cursor(...) NULL +#define gdk_window_get_device_position(...) +#define gdk_window_get_display(...) NULL +#define gdk_window_get_height(...) 0 +#define gdk_window_get_origin(...) +#define gdk_window_get_state(...) 0 +#define gdk_window_get_toplevel(...) NULL +#define gdk_window_get_user_data(...) +#define gdk_window_get_width(...) 0 +#define gdk_window_move_to_rect(...) +#define gdk_window_move(...) +#define gdk_window_resize(...) +#define gdk_window_set_cursor(...) +#define gdk_window_set_transient_for(...) +#define gtk_box_query_child_packing(...) +#define gtk_box_reorder_child(...) +#define gtk_box_set_center_widget(...) +#define gtk_button_box_set_child_non_homogeneous(...) +#define gtk_button_clicked(...) +#define gtk_calendar_get_date(...) +#define gtk_calendar_mark_day(...) +#define gtk_calendar_select_month(...) +#define gtk_check_menu_item_get_active(...) 0 +#define gtk_check_menu_item_new_with_label(...) NULL +#define gtk_check_menu_item_set_active(...) +#define gtk_check_menu_item_set_inconsistent(...) +#define gtk_clipboard_set_text(...) +#define gtk_container_child_get_property(...) +#define gtk_container_child_get(...) +#define gtk_container_child_set(...) +#define gtk_container_foreach(...) +#define gtk_container_get_children(...) NULL +#define gtk_container_get_focus_child(...) NULL +#define gtk_container_remove(...) +#define gtk_container_set_border_width(...) +#define gtk_container_set_focus_child(...) +#define gtk_dialog_run(...) 0 +#define gtk_drag_begin_with_coordinates(...) NULL +#define gtk_drag_dest_set(...) +#define gtk_drag_dest_unset(...) +#define gtk_drag_finish(...) +#define gtk_drag_get_source_widget(...) NULL +#define gtk_drag_set_icon_pixbuf(...) +#define gtk_drag_set_icon_surface(...) +#define gtk_drag_set_icon_widget(...) +#define gtk_drag_source_set(...) +#define gtk_drag_source_unset(...) +#define gtk_entry_get_layout(...) NULL +#define gtk_entry_get_text(...) "test" +#define gtk_entry_set_max_width_chars(...) +#define gtk_entry_set_text(...) +#define gtk_entry_set_width_chars(...) +#define gtk_event_box_set_visible_window(...) +#define GTK_EVENT_BOX(...) NULL +#define gtk_file_chooser_add_filter(...) +#define gtk_file_chooser_button_new(...) NULL +#define gtk_file_chooser_button_set_title(...) +#define gtk_file_chooser_button_set_width_chars(...) +#define gtk_file_chooser_get_current_folder(...) NULL +#define gtk_file_chooser_get_filename(...) NULL +#define gtk_file_chooser_get_filenames(...) NULL +#define gtk_file_chooser_get_uri(...) NULL +#define gtk_file_chooser_select_filename(...) +#define gtk_file_chooser_set_current_folder(...) +#define gtk_file_chooser_set_current_folder(...) +#define gtk_file_chooser_set_current_name(...) +#define gtk_file_chooser_set_do_overwrite_confirmation(...) +#define gtk_file_chooser_set_extra_widget(...) +#define gtk_file_chooser_set_filename(...) +#define gtk_file_chooser_unselect_all(...) +#define gtk_file_filter_add_custom(...) +#define gtk_file_filter_add_pattern(...) +#define gtk_file_filter_set_name(...) +#define gtk_font_button_set_show_size(...) +#define gtk_gesture_multi_press_new(...) NULL +#define gtk_get_event_widget(...) NULL +#define gtk_grab_add(...) +#define gtk_grab_remove(...) +#define gtk_header_bar_set_custom_title(...) +#define gtk_header_bar_set_has_subtitle(...) +#define gtk_header_bar_set_show_close_button(...) +#define gtk_icon_theme_append_search_path(...) +#define gtk_init_check(...) +#define gtk_init(...) gtk_init() +#define GTK_IS_CHECK_MENU_ITEM(...) 0 +#define GTK_IS_EVENT_BOX(...) 0 +#define gtk_label_set_line_wrap(...) +#define gtk_layout_move(...) +#define gtk_layout_new(...) NULL +#define gtk_layout_put(...) +#define gtk_main_do_event(...) +#define gtk_menu_item_get_label(...) NULL +#define gtk_menu_item_get_submenu(...) NULL +#define gtk_menu_item_new_with_label(...) NULL +#define gtk_menu_item_new_with_mnemonic(...) NULL +#define gtk_menu_item_set_submenu(...) +#define GTK_MENU_ITEM(...) NULL +#define gtk_menu_new(...) NULL +#define gtk_menu_popup_at_pointer(...) +#define gtk_menu_popup_at_widget(...) +#define gtk_menu_shell_append(...) +#define gtk_menu_shell_insert(...) +#define gtk_menu_shell_prepend(...) +#define GTK_MENU_SHELL(...) NULL +#define GTK_MENU(...) NULL +#define gtk_native_dialog_run(...) 0 +#define gtk_overlay_reorder_overlay(...) +#define gtk_overlay_set_overlay_pass_through(...) +#define gtk_parse_args(...) 0 +#define gtk_popover_get_default_widget(...) NULL +#define gtk_popover_get_relative_to(...) NULL +#define gtk_popover_new(...) NULL +#define gtk_popover_set_modal(...) +#define gtk_popover_set_position(...) +#define gtk_popover_set_relative_to(...) +#define gtk_popover_set_relative_to(...) +#define gtk_propagate_event(...) +#define gtk_radio_button_new_with_label_from_widget(...) NULL +#define gtk_scrolled_window_set_shadow_type(...) NULL +#define gtk_search_entry_handle_event(...) 0 +#define gtk_selection_data_get_data(...) NULL +#define gtk_selection_data_get_length(...) 0 +#define gtk_selection_data_set(...) +#define gtk_separator_menu_item_new(...) NULL +#define gtk_show_uri_on_window(...) 0 +#define gtk_stack_set_homogeneous(...) +#define gtk_style_context_get(...) +#define gtk_style_context_list_classes(...) NULL +#define gtk_style_context_new(...) NULL +#define gtk_style_context_set_path(...) +#define gtk_style_context_set_screen(...) +#define gtk_target_list_new(...) NULL +#define gtk_target_list_unref(...) +#define gtk_text_view_add_child_in_window(...) +#define gtk_text_view_im_context_filter_keypress(...) 0 +#define gtk_tooltip_trigger_tooltip_query(...) +#define gtk_tree_view_column_cell_get_size(...) +#define gtk_tree_view_create_row_drag_icon(...) NULL +#define gtk_tree_view_get_tooltip_context(...) 0 +#define gtk_tree_view_set_search_entry(...) +#define GTK_TYPE_CONTAINER(...) 0 +#define gtk_viewport_set_shadow_type(...) +#define gtk_widget_add_events(...) +#define gtk_widget_destroy(...) +#define gtk_widget_draw(...) +#define gtk_widget_event(...) 0 +#define gtk_widget_get_preferred_height(...) 0 +#define gtk_widget_get_preferred_width(...) 0 +#define gtk_widget_get_screen(...) NULL +#define gtk_widget_get_tooltip_text(...) NULL +#define gtk_widget_get_toplevel(...) NULL +#define gtk_widget_get_window(...) NULL +#define gtk_widget_has_grab(...) 0 +#define gtk_widget_path_append_type(...) 0 +#define gtk_widget_path_free(...) +#define gtk_widget_path_iter_add_class(...) +#define gtk_widget_path_iter_add_class(...) +#define gtk_widget_path_new(...) NULL +#define gtk_widget_set_app_paintable(...) +#define gtk_widget_set_can_default(...) +#define gtk_widget_set_events(...) +#define gtk_widget_set_has_window(...) +#define gtk_widget_set_no_show_all(...) +#define gtk_widget_set_visual(...) +#define gtk_widget_size_allocate(...) +#define gtk_widget_style_get_property(...) +#define gtk_widget_translate_coordinates(...) +#define gtk_window_get_position(...) +#define gtk_window_get_size(...) +#define gtk_window_get_window_type(...) 0 +#define gtk_window_move(...) +#define gtk_window_resize(...) +#define gtk_window_set_attached_to(...) +#define gtk_window_set_gravity(...) +#define gtk_window_set_keep_above(...) +#define gtk_window_set_position(...) +#define gtk_window_set_transient_for(...) +#define gtk_window_set_type_hint(...) +#define gtk_window_set_urgency_hint(...) +#define gtk_get_current_event(...) (GdkEventOld[]){{GDK_KEY_PRESS}} +static void gtk_widget_destroyed(){}; +static void gtk_main_quit(){}; +static void gtk_main(){}; +static void gtk_widget_show_all(GtkWidget*w){}; +typedef void (*GtkCallback)(GtkWidget *widget, gpointer data); +#define GDK_NONE NULL +#define GDK_2BUTTON_PRESS 0123 +#define GDK_3BUTTON_PRESS 0124 +#define GDK_WINDOW_STATE 0125 +#define GDK_DOUBLE_BUTTON_PRESS GDK_2BUTTON_PRESS +#define GDK_TRIPLE_BUTTON_PRESS GDK_3BUTTON_PRESS +#define GTK_SHADOW_NONE 0 +#define GDK_MOD1_MASK GDK_ALT_MASK +#define GDK_MOD2_MASK 0 +#define GDK_MOD5_MASK 0 +#define GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR 0 +#define GDK_SCROLL_MASK 0 +#define GDK_SMOOTH_SCROLL_MASK 0 + + + + +void dt_add_legacy_signals(GtkWidgetClass *widget_class); + +#define gtk_scrolled_window_new(...) gtk_scrolled_window_new() +#define gtk_window_new(...) gtk_window_new() + +#define gtk_style_context_get_border(context, state, border) gtk_style_context_get_border(context, border) +#define gtk_style_context_get_color(context, state, color) gtk_style_context_get_color(context, color) +#define gtk_style_context_get_margin(context, state, margin) gtk_style_context_get_margin(context, margin) +#define gtk_style_context_get_padding(context, state, padding) gtk_style_context_get_padding(context, padding) + +#define GTK_BIN(bin) (gpointer)bin +GtkWidget *gtk_bin_get_child(gpointer bin); +#define GTK_CONTAINER(container) (GtkContainer *)(container) +#define GTK_IS_CONTAINER(container) GTK_IS_WIDGET(container) +void gtk_container_add(GtkContainer *container, GtkWidget *child); +#define gtk_event_box_new() gtk_box_new(0,0) +#define gtk_box_pack_end(box, child, expand, fill, padding) gtk_box_prepend(box, child) +#define gtk_box_pack_start(box, child, expand, fill, padding) gtk_box_append(box, child) +#define gtk_paned_pack1(paned, child, resize, shrink) gtk_paned_set_start_child(paned, child) +#define gtk_paned_pack2(paned, child, resize, shrink) gtk_paned_set_end_child(paned, child) + +#undef GTK_TOGGLE_BUTTON +#define GTK_TOGGLE_BUTTON(button) (gpointer)button +#define gtk_toggle_button_get_active(button) (GTK_IS_CHECK_BUTTON(button) ? gtk_check_button_get_active(GTK_CHECK_BUTTON(button)) : gtk_toggle_button_get_active((GtkToggleButton *)(button))) +#define gtk_toggle_button_set_active(button, active) (GTK_IS_CHECK_BUTTON(button) ? gtk_check_button_set_active(GTK_CHECK_BUTTON(button), active) : gtk_toggle_button_set_active((GtkToggleButton *)(button), active)) + +#define gdk_cursor_new_from_name(display, name) gdk_cursor_new_from_name(name, NULL) +#define gtk_image_new_from_icon_name(name, size) gtk_image_new_from_icon_name(name) + G_END_DECLS // clang-format off diff --git a/src/control/control.c b/src/control/control.c index ca397e2831a1..452e4e6133d4 100644 --- a/src/control/control.c +++ b/src/control/control.c @@ -257,11 +257,33 @@ void dt_control_allow_change_cursor() void dt_control_change_cursor(dt_cursor_t curs) { - GdkWindow *window = gtk_widget_get_window(dt_ui_main_window(darktable.gui->ui)); + GtkWidget *window = dt_ui_main_window(darktable.gui->ui); if(!darktable.control->lock_cursor_shape && window) { - GdkCursor *cursor = gdk_cursor_new_for_display(gdk_window_get_display(window), curs); - gdk_window_set_cursor(window, cursor); + GdkCursor *cursor = gdk_cursor_new_from_name(gdk_window_get_display(window), + curs == GDK_X_CURSOR ? "crosshair" : + curs == GDK_BOTTOM_LEFT_CORNER ? "sw-resize" : + curs == GDK_BOTTOM_RIGHT_CORNER ? "se-resize" : + curs == GDK_BOTTOM_SIDE ? "s-resize" : + curs == GDK_CROSS ? "crosshair" : + curs == GDK_CROSSHAIR ? "crosshair" : + curs == GDK_FLEUR ? "move" : + curs == GDK_HAND1 ? "pointer" : + curs == GDK_LEFT_PTR ? "default" : + curs == GDK_LEFT_SIDE ? "w-resize" : + curs == GDK_PLUS ? "cell" : + curs == GDK_QUESTION_ARROW ? "help" : + curs == GDK_RIGHT_SIDE ? "e-resize" : + curs == GDK_SB_H_DOUBLE_ARROW ? "ew-resize" : + curs == GDK_SB_V_DOUBLE_ARROW ? "ns-resize" : + curs == GDK_TOP_LEFT_CORNER ? "nw-resize" : + curs == GDK_TOP_RIGHT_CORNER ? "ne-resize" : + curs == GDK_TOP_SIDE ? "n-resize" : + curs == GDK_WATCH ? "wait" : + curs == GDK_PIRATE ? NULL : // no direct equivalent + curs == GDK_BLANK_CURSOR ? NULL : // invisible + "default"); + gtk_widget_set_cursor(window, cursor); g_object_unref(cursor); } } @@ -285,7 +307,7 @@ void dt_control_change_cursor(dt_cursor_t curs) gboolean dt_control_running() { - return dt_atomic_get_int(&darktable.control->running) == DT_CONTROL_STATE_RUNNING; + return darktable.control && dt_atomic_get_int(&darktable.control->running) == DT_CONTROL_STATE_RUNNING; } void dt_control_quit() @@ -393,11 +415,12 @@ void dt_control_cleanup(const gboolean withgui) // ================================================================================ gboolean dt_control_configure(GtkWidget *da, - GdkEventConfigure *event, + gint width, + gint height, gpointer user_data) { // re-configure all components: - dt_view_manager_configure(darktable.view_manager, event->width, event->height); + dt_view_manager_configure(darktable.view_manager, width, height); return TRUE; } diff --git a/src/control/control.h b/src/control/control.h index d4a0c8e192f0..20899c57a925 100644 --- a/src/control/control.h +++ b/src/control/control.h @@ -53,7 +53,7 @@ void dt_control_button_released(double x, double y, int which, uint32_t state); void dt_control_mouse_moved(double x, double y, double pressure, int which); void dt_control_mouse_leave(void); void dt_control_mouse_enter(void); -gboolean dt_control_configure(GtkWidget *da, GdkEventConfigure *event, gpointer user_data); +gboolean dt_control_configure(GtkWidget *da, gint width, gint height, gpointer user_data); void dt_control_log(const char *msg, ...) __attribute__((format(printf, 1, 2))); void dt_toast_log(const char *msg, ...) __attribute__((format(printf, 1, 2))); void dt_toast_markup_log(const char *msg, ...) __attribute__((format(printf, 1, 2))); diff --git a/src/develop/blend_gui.c b/src/develop/blend_gui.c index e21ad170a7cf..54db2fdf0439 100644 --- a/src/develop/blend_gui.c +++ b/src/develop/blend_gui.c @@ -586,7 +586,7 @@ static void _add_wrapped_box(GtkWidget *container, gchar *help_url) { GtkWidget *event_box = gtk_event_box_new(); - GtkWidget *revealer = gtk_revealer_new(); + GtkWidget *revealer = dt_gui_expand(gtk_revealer_new()); gtk_container_add(GTK_CONTAINER(revealer), GTK_WIDGET(box)); gtk_container_add(GTK_CONTAINER(event_box), revealer); gtk_container_add(GTK_CONTAINER(container), event_box); @@ -602,7 +602,7 @@ static void _box_set_visible(GtkBox *box, gboolean visible) GtkRevealer *revealer = GTK_REVEALER(gtk_widget_get_parent(GTK_WIDGET(box))); gtk_revealer_set_transition_duration(revealer, dt_conf_get_int("darkroom/ui/transition_duration")); - gtk_revealer_set_reveal_child(revealer, visible); + gtk_revealer_set_reveal_child(revealer, TRUE);//GTK4 visible); } static void _blendop_masks_mode_callback(const dt_develop_mask_mode_t mask_mode, diff --git a/src/develop/imageop.c b/src/develop/imageop.c index fec321b2ded0..90b2f94371ad 100644 --- a/src/develop/imageop.c +++ b/src/develop/imageop.c @@ -39,7 +39,6 @@ #include "dtgtk/button.h" #include "dtgtk/expander.h" #include "dtgtk/gradientslider.h" -#include "dtgtk/icon.h" #include "gui/accelerators.h" #include "gui/color_picker_proxy.h" #include "gui/drag_and_drop.h" @@ -455,19 +454,23 @@ static gboolean _header_enter_notify_callback(GtkWidget *eventbox, return FALSE; } -static gboolean _header_motion_notify_show_callback(GtkWidget *eventbox, - GdkEventCrossing *event, - dt_iop_module_t *module) +static void _header_motion_notify_show_callback + (GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *module) { + GdkEventCrossing *event = NULL; // GTK4 darktable.control->element = DT_ACTION_ELEMENT_SHOW; - return dt_iop_show_hide_header_buttons(module, event, TRUE, FALSE); + dt_iop_show_hide_header_buttons(module, event, TRUE, FALSE); } -static gboolean _header_motion_notify_hide_callback(GtkWidget *eventbox, - GdkEventCrossing *event, - dt_iop_module_t *module) +static void _header_motion_notify_hide_callback + (GtkEventControllerMotion *controller, + dt_iop_module_t *module) { - return dt_iop_show_hide_header_buttons(module, event, FALSE, FALSE); + GdkEventCrossing *event = NULL; // GTK4 + dt_iop_show_hide_header_buttons(module, event, FALSE, FALSE); } static void _header_menu_deactivate_callback(GtkMenuShell *menushell, @@ -1288,6 +1291,7 @@ void dt_iop_gui_init(dt_iop_module_t *module) --darktable.bauhaus->skip_accel; dt_pthread_mutex_init(&module->gui_lock, NULL); if(module->gui_init) module->gui_init(module); + if(module->widget) g_object_ref(module->widget); ++darktable.bauhaus->skip_accel; --darktable.gui->reset; } @@ -2216,7 +2220,12 @@ void dt_iop_gui_cleanup_module(dt_iop_module_t *module) module->widget_list = NULL; DT_CONTROL_SIGNAL_DISCONNECT_ALL(module, module->so->op); if(module->gui_cleanup) module->gui_cleanup(module); - gtk_widget_destroy(module->expander ? module->expander : module->widget); + GtkWidget *top = module->expander ? module->expander : module->widget; + GtkWidget *parent = gtk_widget_get_parent(top); + if(parent) + gtk_box_remove(GTK_BOX(parent), top); + else + g_object_unref(top); dt_iop_gui_cleanup_blending(module); dt_pthread_mutex_destroy(&module->gui_lock); dt_free_align(module->gui_data); @@ -2233,6 +2242,7 @@ void dt_iop_gui_update(dt_iop_module_t *module) if(module->params && module->gui_update) { +if(0) { // GTK4 if(module->widget && dt_conf_get_bool("plugins/darkroom/show_warnings")) { GtkWidget *label_widget = dt_gui_container_first_child @@ -2241,6 +2251,7 @@ void dt_iop_gui_update(dt_iop_module_t *module) gtk_widget_destroy(label_widget); module->has_trouble = FALSE; } +} module->gui_update(module); } dt_iop_gui_update_blending(module); @@ -2536,48 +2547,45 @@ 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 == GDK_BUTTON_PRIMARY) - { + guint button = gtk_gesture_single_get_current_button(gesture); + if(button == GDK_BUTTON_PRIMARY) dt_iop_request_focus(module); - return TRUE; - } - else if(e->button == GDK_BUTTON_SECONDARY) - { + else if(button == GDK_BUTTON_SECONDARY) _presets_popup_callback(NULL, NULL, module); - return TRUE; - } - return FALSE; + dt_gui_claim(gesture); } -static gboolean _iop_plugin_header_button_release(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(GTK_IS_BUTTON(gtk_get_event_widget((GdkEvent*)e))) return FALSE; - - dt_iop_module_t *module = (dt_iop_module_t *)user_data; + if(n_press > 1) return; - if(e->button == GDK_BUTTON_PRIMARY) + guint button = gtk_gesture_single_get_current_button(gesture); + if(button == GDK_BUTTON_PRIMARY) { - if(dt_modifier_is(e->state, GDK_SHIFT_MASK | GDK_CONTROL_MASK)) + if(dt_modifier_eq(gesture, GDK_SHIFT_MASK | GDK_CONTROL_MASK)) ; // do nothing (for easier dragging) - 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); @@ -2587,16 +2595,17 @@ static gboolean _iop_plugin_header_button_release(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 == GDK_BUTTON_SECONDARY) + else if(button == GDK_BUTTON_SECONDARY) { _presets_popup_callback(NULL, NULL, module); - return TRUE; + dt_gui_claim(gesture); + return; } - return FALSE; } static void _header_size_callback(GtkWidget *widget, @@ -2740,7 +2749,7 @@ gboolean dt_iop_show_hide_header_buttons(dt_iop_module_t *module, gtk_widget_set_visible(GTK_WIDGET(button->data), show_buttons && !always_hide && !disabled); gtk_widget_set_opacity(GTK_WIDGET(button->data), opacity); } - if(GTK_IS_DRAWING_AREA(button->data)) + if(button && GTK_IS_DRAWING_AREA(button->data)) { // temporarily or permanently (de)activate width trigger widget if(dynamic) @@ -2755,6 +2764,7 @@ gboolean dt_iop_show_hide_header_buttons(dt_iop_module_t *module, GtkWidget *space = gtk_drawing_area_new(); gtk_box_pack_end(GTK_BOX(header), space, TRUE, TRUE, 0); gtk_widget_show(space); + if(0) // GTK4 g_signal_connect(G_OBJECT(space), "size-allocate", G_CALLBACK(_header_size_callback), header); } @@ -2874,7 +2884,7 @@ void dt_iop_add_remove_mask_indicator(dt_iop_module_t *module, gboolean add) child && GTK_IS_BUTTON(child->data); child = g_list_previous(child)); - if(GTK_IS_DRAWING_AREA(child->data)) + if(child && GTK_IS_DRAWING_AREA(child->data)) // GTK4 { GValue position = G_VALUE_INIT; g_value_init (&position, G_TYPE_INT); @@ -2960,6 +2970,7 @@ gboolean _iop_tooltip_callback(GtkWidget *widget, gtk_box_pack_start(GTK_BOX(vbox), grid, FALSE, FALSE, 0); + if(0) // GTK4 g_signal_connect(G_OBJECT(vbox), "size-allocate", G_CALLBACK(_iop_tooltip_reposition), module->header); @@ -3123,28 +3134,21 @@ void dt_iop_gui_set_expander(dt_iop_module_t *module) gtk_drag_source_set(header_evb, GDK_BUTTON1_MASK, target_list, 1, GDK_ACTION_COPY); gtk_drag_dest_set(expander, GTK_DEST_DEFAULT_DROP | GTK_DEST_DEFAULT_HIGHLIGHT, target_list, 1, GDK_ACTION_COPY); +if(0) { // GTK4 g_signal_connect(expander, "drag-motion", G_CALLBACK(_on_drag_motion), module); g_signal_connect(expander, "drag-drop", G_CALLBACK(_on_drag_drop), module); - +} module->header = header; /* setup the header box */ - g_signal_connect(G_OBJECT(header_evb), "button-release-event", - G_CALLBACK(_iop_plugin_header_button_release), 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); + dt_gui_connect_click_all(header_evb, _iop_plugin_header_button_press, NULL, module); + dt_gui_connect_motion(header_evb, NULL, _header_motion_notify_show_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); - 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); - g_signal_connect(G_OBJECT(body_evb), "leave-notify-event", - G_CALLBACK(_header_motion_notify_hide_callback), module); + dt_gui_connect_click_all(body_evb, _iop_plugin_body_button_press, NULL, module); + dt_gui_connect_motion(body_evb, NULL, _header_motion_notify_show_callback, + _header_motion_notify_hide_callback, module); /* * initialize the header widgets @@ -3253,7 +3257,7 @@ void dt_iop_gui_set_expander(dt_iop_module_t *module) /* update header */ dt_iop_gui_update_header(module); - gtk_widget_set_hexpand(module->widget, FALSE); + // gtk_widget_set_hexpand(module->widget, FALSE);// GTK4 gtk_widget_set_vexpand(module->widget, FALSE); gtk_widget_show_all(expander); diff --git a/src/develop/imageop_gui.c b/src/develop/imageop_gui.c index 1b11d6e1d29d..42c2efaadcc7 100644 --- a/src/develop/imageop_gui.c +++ b/src/develop/imageop_gui.c @@ -280,7 +280,13 @@ GtkWidget *dt_iop_togglebutton_new(dt_iop_module_t *self, const char *section, c } gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), FALSE); - if(GTK_IS_BOX(box)) gtk_box_pack_end(GTK_BOX(box), w, FALSE, FALSE, 0); + if(GTK_IS_BOX(box)) + { + GtkWidget *other = gtk_widget_get_last_child(box); + for(; other; other = gtk_widget_get_prev_sibling(other)) + if(!GTK_IS_BUTTON(other)) break; + gtk_box_insert_child_after(GTK_BOX(box), w, other); + } dt_action_define_iop(self, section, label, w, &dt_action_def_toggle); diff --git a/src/dtgtk/button.c b/src/dtgtk/button.c index 500479f586bc..d3b91e194d79 100644 --- a/src/dtgtk/button.c +++ b/src/dtgtk/button.c @@ -27,10 +27,15 @@ static void dtgtk_button_init(GtkDarktableButton *button) { } -static gboolean _button_draw(GtkWidget *widget, cairo_t *cr) +static void _button_snapshot(GtkWidget* widget, + GtkSnapshot* snapshot) { - g_return_val_if_fail(widget != NULL, FALSE); - g_return_val_if_fail(DTGTK_IS_BUTTON(widget), FALSE); + g_return_if_fail(widget != NULL); + g_return_if_fail(DTGTK_IS_BUTTON(widget)); + + graphene_rect_t bounds; + graphene_rect_init(&bounds, 0, 0, gtk_widget_get_width(widget), gtk_widget_get_height(widget)); + cairo_t* cr = gtk_snapshot_append_cairo(snapshot, &bounds); GtkStateFlags state = gtk_widget_get_state_flags(widget); @@ -100,14 +105,17 @@ static gboolean _button_draw(GtkWidget *widget, cairo_t *cr) DTGTK_BUTTON(widget)->icon(cr, startx, starty, cwidth, cheight, flags, icon_data); } - return FALSE; + cairo_destroy(cr); } +static guint _button_press_signal = 0; + static void dtgtk_button_class_init(GtkDarktableButtonClass *klass) { GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; + widget_class->snapshot = _button_snapshot; - widget_class->draw = _button_draw; + dt_add_legacy_signals(widget_class); } // Public functions diff --git a/src/dtgtk/drawingarea.c b/src/dtgtk/drawingarea.c index 7ba98fecb8d7..3bddf931a0f7 100644 --- a/src/dtgtk/drawingarea.c +++ b/src/dtgtk/drawingarea.c @@ -17,6 +17,7 @@ */ #include "dtgtk/drawingarea.h" +#include "common/darktable.h" G_DEFINE_TYPE(GtkDarktableDrawingArea, dtgtk_drawing_area, GTK_TYPE_DRAWING_AREA); @@ -25,33 +26,67 @@ static GtkSizeRequestMode dtgtk_drawing_area_get_request_mode(GtkWidget *widget) return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH; }; -static void dtgtk_drawing_area_get_preferred_height_for_width(GtkWidget *widget, gint for_width, - gint *min_height, gint *nat_height) +static void _widget_measure(GtkWidget* widget, + GtkOrientation orientation, + int for_size, + int* minimum, + int* natural, + int* minimum_baseline, + int* natural_baseline) { - GtkDarktableDrawingArea *da = DTGTK_DRAWING_AREA(widget); - - if(da->height == 0) - { - // initialize with height = width - *min_height = *nat_height = for_width; - } - else if(da->height == -1) - { - // initialize with aspect ratio - *min_height = *nat_height = for_width * da->aspect; - } - else + if(orientation == GTK_ORIENTATION_VERTICAL) { - *min_height = *nat_height = da->height; + GtkDarktableDrawingArea *da = DTGTK_DRAWING_AREA(widget); + + if(da->height == 0) + { + // initialize with height = width + *minimum = *natural = for_size; + } + else if(da->height == -1) + { + // initialize with aspect ratio + *minimum = *natural = for_size * da->aspect; + } + else + { + *minimum = *natural = da->height; + } } } +static guint _drawing_area_draw_signal = 0; + +static void _widget_snapshot(GtkWidget* widget, + GtkSnapshot* snapshot) +{ + graphene_rect_t bounds; + graphene_rect_init(&bounds, 0, 0, gtk_widget_get_width(widget), gtk_widget_get_height(widget)); + cairo_t* cr = gtk_snapshot_append_cairo(snapshot, &bounds); + + g_signal_emit(widget, _drawing_area_draw_signal, 0, cr); + + cairo_destroy(cr); +} + static void dtgtk_drawing_area_class_init(GtkDarktableDrawingAreaClass *class) { GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(class); - widget_class->get_request_mode = dtgtk_drawing_area_get_request_mode; - widget_class->get_preferred_height_for_width = dtgtk_drawing_area_get_preferred_height_for_width; + widget_class->measure = _widget_measure; + widget_class->snapshot = _widget_snapshot; + + _drawing_area_draw_signal = + g_signal_new ("draw", + G_TYPE_FROM_CLASS(class), + G_SIGNAL_RUN_LAST, + 0, // class offset + NULL, NULL, // accumulator, data + g_cclosure_marshal_VOID__POINTER, // marshaller + G_TYPE_NONE, 1, // return type + G_TYPE_POINTER); // parameter: cairo_t* + + dt_add_legacy_signals(widget_class); } static void dtgtk_drawing_area_init(GtkDarktableDrawingArea *da) @@ -59,6 +94,17 @@ static void dtgtk_drawing_area_init(GtkDarktableDrawingArea *da) } // public functions +GtkWidget *dtgtk_drawing_area_new(void) +{ + GtkDarktableDrawingArea *da; + da = g_object_new(dtgtk_drawing_area_get_type(), NULL); + da->aspect = 1.0f; // square by default + da->height = -1; + + return (GtkWidget *)da; +} + + GtkWidget *dtgtk_drawing_area_new_with_aspect_ratio(double aspect) { GtkDarktableDrawingArea *da; diff --git a/src/dtgtk/drawingarea.h b/src/dtgtk/drawingarea.h index 9425aa0b1fce..0dffbea31e06 100644 --- a/src/dtgtk/drawingarea.h +++ b/src/dtgtk/drawingarea.h @@ -45,11 +45,14 @@ struct _GtkDarktableDrawingArea GType dtgtk_drawing_area_get_type(void); +GtkWidget *dtgtk_drawing_area_new(void); GtkWidget *dtgtk_drawing_area_new_with_aspect_ratio(double aspect); GtkWidget *dtgtk_drawing_area_new_with_height(int height); void dtgtk_drawing_area_set_aspect_ratio(GtkWidget *w, double aspect); void dtgtk_drawing_area_set_height(GtkWidget *w, int height); +#define gtk_drawing_area_new dtgtk_drawing_area_new + G_END_DECLS // clang-format off diff --git a/src/dtgtk/expander.c b/src/dtgtk/expander.c index 543816e38e83..9e333f8422c6 100644 --- a/src/dtgtk/expander.c +++ b/src/dtgtk/expander.c @@ -272,24 +272,25 @@ GtkWidget *dtgtk_expander_new(GtkWidget *header, GtkWidget *body) expander->body = body; expander->header_evb = gtk_event_box_new(); - gtk_container_add(GTK_CONTAINER(expander->header_evb), expander->header); + dt_gui_box_add(expander->header_evb, expander->header); expander->body_evb = gtk_event_box_new(); if(expander->body) - gtk_container_add(GTK_CONTAINER(expander->body_evb), expander->body); + dt_gui_box_add(expander->body_evb, expander->body); GtkWidget *frame = gtk_frame_new(NULL); - gtk_container_add(GTK_CONTAINER(frame), expander->body_evb); + gtk_frame_set_child(GTK_FRAME(frame), expander->body_evb); expander->frame = gtk_revealer_new(); gtk_revealer_set_transition_duration(GTK_REVEALER(expander->frame), 0); gtk_revealer_set_reveal_child(GTK_REVEALER(expander->frame), TRUE); - gtk_container_add(GTK_CONTAINER(expander->frame), frame); + gtk_revealer_set_child(GTK_REVEALER(expander->frame), frame); + gtk_widget_set_hexpand(body, TRUE); dt_gui_box_add(expander, expander->header_evb, expander->frame); - + if(0) { // GTK4 g_signal_connect(expander->header_evb, "drag-begin", G_CALLBACK(_expander_drag_begin), NULL); g_signal_connect(expander->header_evb, "drag-end", G_CALLBACK(_expander_drag_end), NULL); g_signal_connect(expander, "drag-leave", G_CALLBACK(_expander_drag_leave), NULL); g_signal_connect(expander, "size-allocate", G_CALLBACK(_expander_resize), frame); - + } return GTK_WIDGET(expander); } diff --git a/src/dtgtk/gradientslider.c b/src/dtgtk/gradientslider.c index 9d7100dafb95..30bcaba0fcf1 100644 --- a/src/dtgtk/gradientslider.c +++ b/src/dtgtk/gradientslider.c @@ -38,7 +38,7 @@ G_DEFINE_TYPE(GtkDarktableGradientSlider, _gradient_slider, GTK_TYPE_DRAWING_ARE // Class overrides static void _gradient_slider_get_preferred_height(GtkWidget *widget, gint *min_height, gint *nat_height); static void _gradient_slider_get_preferred_width(GtkWidget *widget, gint *min_width, gint *nat_width); -static gboolean _gradient_slider_draw(GtkWidget *widget, cairo_t *cr); +static void _gradient_slider_snapshot(GtkWidget *widget, GtkSnapshot *snapshot); static void _gradient_slider_destroy(GtkWidget *widget); // Events @@ -442,24 +442,25 @@ static gboolean _gradient_slider_key_press_event(GtkWidget *widget, GdkEventKey static void _gradient_slider_class_init(GtkDarktableGradientSliderClass *klass) { GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; - - widget_class->get_preferred_height = _gradient_slider_get_preferred_height; - widget_class->get_preferred_width = _gradient_slider_get_preferred_width; - widget_class->draw = _gradient_slider_draw; - widget_class->destroy = _gradient_slider_destroy; - - widget_class->enter_notify_event = _gradient_slider_enter_notify_event; - widget_class->leave_notify_event = _gradient_slider_leave_notify_event; - widget_class->button_press_event = _gradient_slider_button_press; - widget_class->button_release_event = _gradient_slider_button_release; - widget_class->motion_notify_event = _gradient_slider_motion_notify; - widget_class->scroll_event = _gradient_slider_scroll_event; - widget_class->key_press_event = _gradient_slider_key_press_event; + widget_class->snapshot = _gradient_slider_snapshot; + // widget_class->get_preferred_height = _gradient_slider_get_preferred_height; + // widget_class->get_preferred_width = _gradient_slider_get_preferred_width; + // widget_class->draw = _gradient_slider_draw; + // widget_class->destroy = _gradient_slider_destroy; + + // widget_class->enter_notify_event = _gradient_slider_enter_notify_event; + // widget_class->leave_notify_event = _gradient_slider_leave_notify_event; + // widget_class->button_press_event = _gradient_slider_button_press; + // widget_class->button_release_event = _gradient_slider_button_release; + // widget_class->motion_notify_event = _gradient_slider_motion_notify; + // widget_class->scroll_event = _gradient_slider_scroll_event; + // widget_class->key_press_event = _gradient_slider_key_press_event; _signals[VALUE_CHANGED] = g_signal_new("value-changed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); _signals[VALUE_RESET] = g_signal_new("value-reset", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + dt_add_legacy_signals(widget_class); } static void _gradient_slider_init(GtkDarktableGradientSlider *gslider) @@ -533,14 +534,18 @@ static void _gradient_slider_destroy(GtkWidget *widget) gslider->colors = NULL; - GTK_WIDGET_CLASS(parent_class)->destroy(widget); + // GTK_WIDGET_CLASS(parent_class)->destroy(widget); } -static gboolean _gradient_slider_draw(GtkWidget *widget, cairo_t *cr) +static void _gradient_slider_snapshot(GtkWidget *widget, GtkSnapshot *snapshot) { - g_return_val_if_fail(DTGTK_IS_GRADIENT_SLIDER(widget), FALSE); + g_return_if_fail(DTGTK_IS_GRADIENT_SLIDER(widget)); GtkDarktableGradientSlider *gslider = DTGTK_GRADIENT_SLIDER(widget); + graphene_rect_t bounds; + graphene_rect_init(&bounds, 0, 0, gtk_widget_get_width(widget), gtk_widget_get_height(widget)); + cairo_t* cr = gtk_snapshot_append_cairo(snapshot, &bounds); + assert(gslider->position > 0); GtkStyleContext *context = gtk_widget_get_style_context(widget); @@ -650,7 +655,7 @@ static gboolean _gradient_slider_draw(GtkWidget *widget, cairo_t *cr) } } - return FALSE; + cairo_destroy(cr); } gint _list_find_by_position(gconstpointer a, gconstpointer b) diff --git a/src/dtgtk/icon.c b/src/dtgtk/icon.c deleted file mode 100644 index 049cbd34a892..000000000000 --- a/src/dtgtk/icon.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - This file is part of darktable, - Copyright (C) 2011-2020 darktable developers. - - darktable is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - darktable is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with darktable. If not, see . -*/ -#include "icon.h" -#include "gui/gtk.h" -#include - -G_DEFINE_TYPE(GtkDarktableIcon, dtgtk_icon, GTK_TYPE_EVENT_BOX); - -static gboolean _icon_draw(GtkWidget *widget, cairo_t *cr); - -static void dtgtk_icon_class_init(GtkDarktableIconClass *klass) -{ - GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; - widget_class->draw = _icon_draw; -} - -static void dtgtk_icon_init(GtkDarktableIcon *icon) -{ -} - -static gboolean _icon_draw(GtkWidget *widget, cairo_t *cr) -{ - g_return_val_if_fail(widget != NULL, FALSE); - g_return_val_if_fail(DTGTK_IS_ICON(widget), FALSE); - - /* begin cairo drawing */ - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - - GtkStateFlags state = gtk_widget_get_state_flags(widget); - - GdkRGBA fg_color; - GtkStyleContext *context = gtk_widget_get_style_context(widget); - gtk_style_context_get_color(context, state, &fg_color); - - gdk_cairo_set_source_rgba(cr, &fg_color); - - /* draw icon */ - if(DTGTK_ICON(widget)->icon) - DTGTK_ICON(widget)->icon(cr, 0, 0, allocation.width, allocation.height, DTGTK_ICON(widget)->icon_flags, - DTGTK_ICON(widget)->icon_data); - - return FALSE; -} - -// Public functions -GtkWidget *dtgtk_icon_new(DTGTKCairoPaintIconFunc paint, gint paintflags, void *paintdata) -{ - GtkDarktableIcon *icon; - icon = g_object_new(dtgtk_icon_get_type(), NULL); - gtk_event_box_set_visible_window(GTK_EVENT_BOX(icon), FALSE); - icon->icon = paint; - icon->icon_flags = paintflags; - icon->icon_data = paintdata; - gtk_widget_set_name(GTK_WIDGET(icon), "dt-icon"); - return (GtkWidget *)icon; -} - -void dtgtk_icon_set_paint(GtkWidget *icon, DTGTKCairoPaintIconFunc paint, gint paintflags, void *paintdata) -{ - g_return_if_fail(icon != NULL); - DTGTK_ICON(icon)->icon = paint; - DTGTK_ICON(icon)->icon_flags = paintflags; - DTGTK_ICON(icon)->icon_data = paintdata; - gtk_widget_queue_draw(icon); -} - -// 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 -// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified; -// clang-format on - diff --git a/src/dtgtk/icon.h b/src/dtgtk/icon.h deleted file mode 100644 index 3922c5d9149d..000000000000 --- a/src/dtgtk/icon.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - This file is part of darktable, - Copyright (C) 2011-2020 darktable developers. - - darktable is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - darktable is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with darktable. If not, see . -*/ - -#pragma once - -#include "paint.h" -#include - -G_BEGIN_DECLS - -#define DTGTK_TYPE_ICON dtgtk_icon_get_type() -G_DECLARE_FINAL_TYPE(GtkDarktableIcon, dtgtk_icon, DTGTK, ICON, GtkEventBox) - -struct _GtkDarktableIcon -{ - GtkEventBox widget; - DTGTKCairoPaintIconFunc icon; - gint icon_flags; - void *icon_data; -}; - -/** instantiate a new darktable icon control passing paint function as content */ -GtkWidget *dtgtk_icon_new(DTGTKCairoPaintIconFunc paint, gint paintflags, void *paintdata); - -/** set the paint function for a icon */ -void dtgtk_icon_set_paint(GtkWidget *icon, DTGTKCairoPaintIconFunc paint, gint paintflags, void *paintdata); - -G_END_DECLS - -// 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 -// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified; -// clang-format on - diff --git a/src/dtgtk/range.c b/src/dtgtk/range.c index 4fae45590752..b9ec382aabdb 100644 --- a/src/dtgtk/range.c +++ b/src/dtgtk/range.c @@ -19,6 +19,7 @@ #include "bauhaus/bauhaus.h" #include "control/control.h" #include "gui/gtk.h" +#include "dtgtk/drawingarea.h" #include #include @@ -27,7 +28,7 @@ #define BAR_WIDTH 4 // define GTypes -G_DEFINE_TYPE(GtkDarktableRangeSelect, dtgtk_range_select, GTK_TYPE_EVENT_BOX); +G_DEFINE_TYPE(GtkDarktableRangeSelect, dtgtk_range_select, GTK_TYPE_BOX); typedef struct _range_date_popup { @@ -171,13 +172,13 @@ static void _range_select_destroy(GtkWidget *widget) g_free(range->cur_help); range->cur_help = NULL; - GTK_WIDGET_CLASS(dtgtk_range_select_parent_class)->destroy(widget); + // GTK_WIDGET_CLASS(dtgtk_range_select_parent_class)->destroy(widget); } static void dtgtk_range_select_class_init(GtkDarktableRangeSelectClass *klass) { GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; - widget_class->destroy = _range_select_destroy; + // widget_class->destroy = _range_select_destroy; _signals[VALUE_CHANGED] = g_signal_new("value-changed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); diff --git a/src/dtgtk/range.h b/src/dtgtk/range.h index 2dc5c3c9269d..b9d437251e95 100644 --- a/src/dtgtk/range.h +++ b/src/dtgtk/range.h @@ -37,7 +37,7 @@ G_BEGIN_DECLS #define DTGTK_TYPE_RANGE_SELECT dtgtk_range_select_get_type() -G_DECLARE_FINAL_TYPE(GtkDarktableRangeSelect, dtgtk_range_select, DTGTK, RANGE_SELECT, GtkEventBox) +G_DECLARE_FINAL_TYPE(GtkDarktableRangeSelect, dtgtk_range_select, DTGTK, RANGE_SELECT, GtkBox) typedef double (*DTGTKTranslateValueFunc)(const double value); typedef gchar *(*DTGTKPrintValueFunc)(const double value, const gboolean detailled); @@ -63,7 +63,7 @@ typedef enum dt_range_type_t struct _GtkDarktableRangeSelect { - GtkEventBox widget; + GtkBox widget; dt_range_type_t type; diff --git a/src/dtgtk/resetlabel.c b/src/dtgtk/resetlabel.c index dcc43ebbc746..d4a1bff1d647 100644 --- a/src/dtgtk/resetlabel.c +++ b/src/dtgtk/resetlabel.c @@ -18,7 +18,7 @@ #include "dtgtk/resetlabel.h" -G_DEFINE_TYPE(GtkDarktableResetLabel, dtgtk_reset_label, GTK_TYPE_EVENT_BOX); +G_DEFINE_TYPE(GtkDarktableResetLabel, dtgtk_reset_label, GTK_TYPE_BOX); static void dtgtk_reset_label_class_init(GtkDarktableResetLabelClass *klass) { @@ -64,6 +64,7 @@ GtkWidget *dtgtk_reset_label_new(const gchar *text, dt_iop_module_t *module, voi gtk_widget_set_tooltip_text(GTK_WIDGET(label), _("double-click to reset")); gtk_container_add(GTK_CONTAINER(label), GTK_WIDGET(label->lb)); gtk_widget_add_events(GTK_WIDGET(label), GDK_BUTTON_PRESS_MASK); + if(0) // GTK g_signal_connect(G_OBJECT(label), "button-press-event", G_CALLBACK(_reset_label_callback), (gpointer)NULL); return (GtkWidget *)label; diff --git a/src/dtgtk/resetlabel.h b/src/dtgtk/resetlabel.h index 19d8199c9e5b..531c0182a5c0 100644 --- a/src/dtgtk/resetlabel.h +++ b/src/dtgtk/resetlabel.h @@ -24,11 +24,11 @@ G_BEGIN_DECLS #define DTGTK_TYPE_RESET_LABEL dtgtk_reset_label_get_type() -G_DECLARE_FINAL_TYPE(GtkDarktableResetLabel, dtgtk_reset_label, DTGTK, RESET_LABEL, GtkEventBox) +G_DECLARE_FINAL_TYPE(GtkDarktableResetLabel, dtgtk_reset_label, DTGTK, RESET_LABEL, GtkBox) struct _GtkDarktableResetLabel { - GtkEventBox widget; + GtkBox widget; GtkLabel *lb; dt_iop_module_t *module; int offset; // offset in params to reset diff --git a/src/dtgtk/sidepanel.c b/src/dtgtk/sidepanel.c index 8dd664f2e9d9..5d30662be1a0 100644 --- a/src/dtgtk/sidepanel.c +++ b/src/dtgtk/sidepanel.c @@ -33,8 +33,8 @@ static void dtgtk_side_panel_get_preferred_width(GtkWidget *widget, gint *minimum_size, gint *natural_size) { - GTK_WIDGET_CLASS(dtgtk_side_panel_parent_class)->get_preferred_width - (widget, minimum_size, natural_size); + // GTK_WIDGET_CLASS(dtgtk_side_panel_parent_class)->get_preferred_width + // (widget, minimum_size, natural_size); const int width = dt_ui_panel_get_size(darktable.gui->ui, @@ -47,10 +47,10 @@ static void dtgtk_side_panel_get_preferred_width(GtkWidget *widget, static void dtgtk_side_panel_class_init(GtkDarktableSidePanelClass *class) { - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(class); + // GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(class); - widget_class->get_request_mode = dtgtk_side_panel_get_request_mode; - widget_class->get_preferred_width = dtgtk_side_panel_get_preferred_width; + // widget_class->get_request_mode = dtgtk_side_panel_get_request_mode; + // widget_class->get_preferred_width = dtgtk_side_panel_get_preferred_width; } static void dtgtk_side_panel_init(GtkDarktableSidePanel *panel) diff --git a/src/dtgtk/thumbnail.c b/src/dtgtk/thumbnail.c index dc9cfe99fcd8..74c8f0841f48 100644 --- a/src/dtgtk/thumbnail.c +++ b/src/dtgtk/thumbnail.c @@ -32,8 +32,8 @@ #include "common/selection.h" #include "common/variables.h" #include "control/control.h" +#include "dtgtk/drawingarea.h" #include "dtgtk/button.h" -#include "dtgtk/icon.h" #include "dtgtk/thumbnail_btn.h" #include "gui/drag_and_drop.h" #include "gui/accelerators.h" @@ -953,18 +953,17 @@ 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, + dt_thumbnail_t *thumb) { - if(!user_data) return TRUE; - dt_thumbnail_t *thumb = (dt_thumbnail_t *)user_data; + if(!thumb) return; // 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_rating_press(GtkWidget *widget, @@ -1244,20 +1243,24 @@ static gboolean _event_box_enter_leave(GtkWidget *widget, return FALSE; } -static gboolean _event_image_enter_leave(GtkWidget *widget, - GdkEventCrossing *event, - gpointer user_data) +static void _event_image_leave(GtkEventControllerMotion *controller, + dt_thumbnail_t *thumb) { - dt_thumbnail_t *thumb = (dt_thumbnail_t *)user_data; - // we ensure that the image has mouse over - if(!thumb->mouse_over && event->type == GDK_ENTER_NOTIFY + if(!thumb->mouse_over && controller == NULL && !thumb->disable_mouseover) dt_control_set_mouse_over_id(thumb->imgid); _set_flag(thumb->w_image_box, GTK_STATE_FLAG_PRELIGHT, - (event->type == GDK_ENTER_NOTIFY)); - return FALSE; + (controller == NULL)); +} + +static void _event_image_enter(GtkEventControllerMotion *controller, + double x, + double y, + dt_thumbnail_t *thumb) +{ + _event_image_leave(NULL, thumb); } static gboolean _event_btn_enter_leave(GtkWidget *widget, @@ -1331,13 +1334,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, + dt_thumbnail_t *thumb) { + 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 @@ -1348,7 +1350,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; } @@ -1403,16 +1405,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); @@ -1442,12 +1437,7 @@ GtkWidget *dt_thumbnail_create_widget(dt_thumbnail_t *thumb, | GDK_STRUCTURE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK); - g_signal_connect(G_OBJECT(evt_image), "motion-notify-event", - G_CALLBACK(_event_main_motion), thumb); - g_signal_connect(G_OBJECT(evt_image), "enter-notify-event", - G_CALLBACK(_event_image_enter_leave), thumb); - g_signal_connect(G_OBJECT(evt_image), "leave-notify-event", - G_CALLBACK(_event_image_enter_leave), thumb); + dt_gui_connect_motion(evt_image, _event_main_motion, _event_image_enter, _event_image_leave, thumb); gtk_widget_show(evt_image); gtk_overlay_add_overlay(GTK_OVERLAY(thumb->w_image_box), evt_image); thumb->w_image = gtk_drawing_area_new(); @@ -1461,12 +1451,7 @@ GtkWidget *dt_thumbnail_create_widget(dt_thumbnail_t *thumb, | GDK_POINTER_MOTION_MASK); g_signal_connect(G_OBJECT(thumb->w_image), "draw", G_CALLBACK(_event_image_draw), thumb); - g_signal_connect(G_OBJECT(thumb->w_image), "motion-notify-event", - G_CALLBACK(_event_main_motion), thumb); - g_signal_connect(G_OBJECT(thumb->w_image), "enter-notify-event", - G_CALLBACK(_event_image_enter_leave), thumb); - g_signal_connect(G_OBJECT(thumb->w_image), "leave-notify-event", - G_CALLBACK(_event_image_enter_leave), thumb); + dt_gui_connect_motion(thumb->w_image, _event_main_motion, _event_image_enter, _event_image_leave, thumb); g_signal_connect(G_OBJECT(thumb->w_image), "style-updated", G_CALLBACK(_event_image_style_updated), thumb); gtk_widget_show(thumb->w_image); diff --git a/src/dtgtk/thumbnail_btn.c b/src/dtgtk/thumbnail_btn.c index b2e42d004cd5..ef45d351c95a 100644 --- a/src/dtgtk/thumbnail_btn.c +++ b/src/dtgtk/thumbnail_btn.c @@ -28,9 +28,11 @@ static void dtgtk_thumbnail_btn_class_init(GtkDarktableThumbnailBtnClass *klass) { GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; - widget_class->draw = _thumbnail_btn_draw; - widget_class->enter_notify_event = _thumbnail_btn_enter_leave_notify_callback; - widget_class->leave_notify_event = _thumbnail_btn_enter_leave_notify_callback; + // widget_class->draw = _thumbnail_btn_draw; + // widget_class->enter_notify_event = _thumbnail_btn_enter_leave_notify_callback; + // widget_class->leave_notify_event = _thumbnail_btn_enter_leave_notify_callback; + + dt_add_legacy_signals(widget_class); } static void dtgtk_thumbnail_btn_init(GtkDarktableThumbnailBtn *button) diff --git a/src/dtgtk/togglebutton.c b/src/dtgtk/togglebutton.c index 5a978d2b3078..3f06a265bf04 100644 --- a/src/dtgtk/togglebutton.c +++ b/src/dtgtk/togglebutton.c @@ -23,23 +23,30 @@ G_DEFINE_TYPE(GtkDarktableToggleButton, dtgtk_togglebutton, GTK_TYPE_TOGGLE_BUTTON); -static gboolean _togglebutton_draw(GtkWidget *widget, cairo_t *cr); +static void _togglebutton_snapshot(GtkWidget *widget, GtkSnapshot* snapshot); static void dtgtk_togglebutton_class_init(GtkDarktableToggleButtonClass *klass) { GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; - widget_class->draw = _togglebutton_draw; + widget_class->snapshot = _togglebutton_snapshot; + + dt_add_legacy_signals(widget_class); } static void dtgtk_togglebutton_init(GtkDarktableToggleButton *slider) { } -static gboolean _togglebutton_draw(GtkWidget *widget, cairo_t *cr) +static void _togglebutton_snapshot(GtkWidget* widget, + GtkSnapshot* snapshot) { - g_return_val_if_fail(widget != NULL, FALSE); - g_return_val_if_fail(DTGTK_IS_TOGGLEBUTTON(widget), FALSE); + g_return_if_fail(widget != NULL); + g_return_if_fail(DTGTK_IS_TOGGLEBUTTON(widget)); + + graphene_rect_t bounds; + graphene_rect_init(&bounds, 0, 0, gtk_widget_get_width(widget), gtk_widget_get_height(widget)); + cairo_t* cr = gtk_snapshot_append_cairo(snapshot, &bounds); GtkStateFlags state = gtk_widget_get_state_flags(widget); @@ -126,7 +133,7 @@ static gboolean _togglebutton_draw(GtkWidget *widget, cairo_t *cr) DTGTK_TOGGLEBUTTON(widget)->icon(cr, startx, starty, cwidth, cheight, flags, icon_data); } - return FALSE; + cairo_destroy(cr); } // Public functions diff --git a/src/gui/accelerators.c b/src/gui/accelerators.c index 97107c9ec830..55be13aa7ca9 100644 --- a/src/gui/accelerators.c +++ b/src/gui/accelerators.c @@ -1016,9 +1016,9 @@ gboolean dt_shortcut_tooltip_callback(GtkWidget *widget, GtkTooltip *tooltip, GtkWidget *vbox) { - GtkWindow *top = GTK_WINDOW(gtk_widget_get_toplevel(widget)); + GtkWindow *top = GTK_WINDOW(gtk_widget_get_root(widget)); if(!gtk_window_is_active(top) - && gtk_window_get_window_type(top) != GTK_WINDOW_POPUP) + )//GTK4 && gtk_window_get_window_type(top) != GTK_WINDOW_POPUP) return FALSE; if(dt_key_modifier_state() & (GDK_BUTTON1_MASK|GDK_BUTTON2_MASK|GDK_BUTTON3_MASK @@ -1219,6 +1219,7 @@ gboolean dt_shortcut_tooltip_callback(GtkWidget *widget, gtk_widget_show_all(vbox); gtk_tooltip_set_custom(tooltip, vbox); + if(0) // GTK4 g_signal_connect(G_OBJECT(vbox), "size-allocate", G_CALLBACK(_tooltip_reposition), widget); return TRUE; @@ -1478,6 +1479,7 @@ static gboolean _insert_shortcut(dt_shortcut_t *shortcut, shortcut->speed = s->speed = roundf(s->speed * e->speed * 1000.) / 1000.; if(fabsf(s->speed) >= .001 && fabsf(s->speed) <= 1000.) { + if(0) // GTK4 _remove_shortcut(existing); if(s->speed != 1.0) { @@ -2519,7 +2521,7 @@ static void _restore_clicked(GtkButton *button, gpointer user_data) { enum { - _DEFAULTS = 1, + _DEFAULTS, _STARTUP, _EDITS, }; @@ -4876,6 +4878,7 @@ dt_action_t *dt_action_define(dt_action_t *owner, } gtk_widget_set_has_tooltip(widget, TRUE); + if(0) // GTK4 g_signal_connect(G_OBJECT(widget), "leave-notify-event", G_CALLBACK(_reset_element_on_leave), NULL); } @@ -4979,17 +4982,15 @@ void dt_shortcut_register(dt_action_t *owner, { if(accel_key != 0 && !darktable.control->accel_initialised) { - GdkKeymap *keymap = gdk_keymap_get_for_display(gdk_display_get_default()); - GdkKeymapKey *keys; gint n_keys, i = 0; - if(!gdk_keymap_get_entries_for_keyval(keymap, accel_key, &keys, &n_keys)) return; + if(!gdk_display_map_keyval(gdk_display_get_default(), accel_key, &keys, &n_keys)) return; // GTK4 for(int j = 0; j < n_keys; j++) { - gdk_keymap_translate_keyboard_state(keymap, keys[j].keycode, 0, 0, - &keys[j].keycode, NULL, NULL, NULL); + gdk_display_translate_key(gdk_display_get_default(), keys[j].keycode, 0, 0, + &keys[j].keycode, NULL, NULL, NULL); if(_is_kp_key(keys[j].keycode)) keys[j].group = 10; @@ -5001,9 +5002,9 @@ void dt_shortcut_register(dt_action_t *owner, } if(keys[i].level & 1) mods |= GDK_SHIFT_MASK; - if(keys[i].level & 2) mods |= GDK_MOD5_MASK; + if(keys[i].level & 2) mods |= GDK_ALT_MASK; // GTK4 - mods = _mods_fix_primary(mods); + // mods = _mods_fix_primary(mods); // GTK4 dt_shortcut_t s = { .key_device = DT_SHORTCUT_DEVICE_KEYBOARD_MOUSE, .key = keys[i].keycode, diff --git a/src/gui/gtk.c b/src/gui/gtk.c index 78608016895e..c30ac493a565 100644 --- a/src/gui/gtk.c +++ b/src/gui/gtk.c @@ -48,9 +48,6 @@ #include "gui/preferences.h" #include -#ifdef GDK_WINDOWING_WAYLAND -#include -#endif #include #include #include @@ -59,7 +56,7 @@ #ifdef MAC_INTEGRATION #include #endif -#ifdef GDK_WINDOWING_QUARTZ +#ifdef __APPLE__ #include "osx/osx.h" #endif #ifdef _WIN32 @@ -975,15 +972,16 @@ static gboolean _osx_openfile_callback(GtkosxApplication *OSXapp, } #endif -static gboolean _configure(GtkWidget *da, - GdkEventConfigure *event, - const gpointer user_data) +static void _configure(GtkWidget *da, + gint width, + gint height, + const gpointer user_data) { #ifndef GDK_WINDOWING_QUARTZ dt_configure_ppd_dpi((dt_gui_gtk_t *) user_data); #endif - return dt_control_configure(da, event, user_data); + dt_control_configure(da, width, height, user_data); } static gboolean _window_configure(GtkWidget *da, @@ -1396,32 +1394,6 @@ int dt_gui_gtk_init(dt_gui_gtk_t *gui) // Initializing widgets _init_widgets(gui); - widget = dt_ui_center(darktable.gui->ui); - g_signal_connect(G_OBJECT(widget), "configure-event", - G_CALLBACK(_configure), gui); - for(int i = 2; i; i--, widget = dt_ui_snapshot(darktable.gui->ui)) - { - gtk_widget_add_events(widget, - GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK - | GDK_LEAVE_NOTIFY_MASK | darktable.gui->scroll_mask); - - g_signal_connect(G_OBJECT(widget), "draw", - G_CALLBACK(_draw), NULL); - g_signal_connect(G_OBJECT(widget), "motion-notify-event", - G_CALLBACK(_mouse_moved), gui); - g_signal_connect(G_OBJECT(widget), "leave-notify-event", - G_CALLBACK(_center_leave), NULL); - g_signal_connect(G_OBJECT(widget), "enter-notify-event", - G_CALLBACK(_center_enter), NULL); - g_signal_connect(G_OBJECT(widget), "button-press-event", - G_CALLBACK(_button_pressed), NULL); - g_signal_connect(G_OBJECT(widget), "button-release-event", - G_CALLBACK(_button_released), NULL); - g_signal_connect(G_OBJECT(widget), "scroll-event", - G_CALLBACK(_scrolled), NULL); - } - // TODO: left, right, top, bottom: // leave-notify-event @@ -1591,7 +1563,11 @@ void dt_gui_gtk_run(dt_gui_gtk_t *gui) if(dt_control_running()) { g_atomic_int_set(&darktable.gui_running, 1); - gtk_main(); + + //GTK4 gtk_application_new? +while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0) + g_main_context_iteration (NULL, TRUE); + g_atomic_int_set(&darktable.gui_running, 0); } if(darktable.gui->surface) @@ -1651,7 +1627,7 @@ void dt_configure_ppd_dpi(dt_gui_gtk_t *gui) gui->ppd = gui->ppd_thb = dt_get_system_gui_ppd(widget); gui->filter_image = CAIRO_FILTER_GOOD; gui->dpi = dt_get_screen_resolution(widget); - gui->dpi_factor = gui->dpi / DT_UI_DEFAULT_DPI_RESOLUTION; + gui->dpi_factor = 1;//GTK4 gui->dpi / DT_UI_DEFAULT_DPI_RESOLUTION; } static gboolean _focus_in_out_event(GtkWidget *widget, @@ -1708,6 +1684,7 @@ static void _init_widgets(dt_gui_gtk_t *gui) // Creating the main window widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_present(GTK_WINDOW(widget)); gtk_widget_set_name(widget, "main_window"); gui->ui->main_window = widget; @@ -1730,7 +1707,7 @@ static void _init_widgets(dt_gui_gtk_t *gui) // Adding the outermost vbox widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - gtk_container_add(GTK_CONTAINER(container), widget); + gtk_window_set_child(GTK_WINDOW(container), widget); /* connect to signal redraw all */ DT_CONTROL_SIGNAL_CONNECT(DT_SIGNAL_CONTROL_REDRAW_ALL, _ui_widget_redraw_callback, gui->ui->main_window); @@ -1755,6 +1732,34 @@ static void _init_widgets(dt_gui_gtk_t *gui) static const dt_action_def_t _action_def_focus_tabs; +static GtkWidget *_central_image_new() +{ + GtkWidget *widget = gtk_drawing_area_new(); + g_signal_connect(G_OBJECT(widget), "resize", + G_CALLBACK(_configure), darktable.gui); + + gtk_widget_add_events(widget, + GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK | darktable.gui->scroll_mask); + + g_signal_connect(G_OBJECT(widget), "draw", + G_CALLBACK(_draw), NULL); + g_signal_connect(G_OBJECT(widget), "motion-notify-event", + G_CALLBACK(_mouse_moved), darktable.gui); + g_signal_connect(G_OBJECT(widget), "leave-notify-event", + G_CALLBACK(_center_leave), NULL); + g_signal_connect(G_OBJECT(widget), "enter-notify-event", + G_CALLBACK(_center_enter), NULL); + g_signal_connect(G_OBJECT(widget), "button-press-event", + G_CALLBACK(_button_pressed), NULL); + g_signal_connect(G_OBJECT(widget), "button-release-event", + G_CALLBACK(_button_released), NULL); + g_signal_connect(G_OBJECT(widget), "scroll-event", + G_CALLBACK(_scrolled), NULL); + return widget; +} + static void _init_main_table(GtkWidget *container) { GtkWidget *widget; @@ -1794,14 +1799,14 @@ static void _init_main_table(GtkWidget *container) /* setup center drawing area */ GtkWidget *ocda = gtk_overlay_new(); - GtkWidget *cda = gtk_drawing_area_new(); + GtkWidget *cda = _central_image_new(); gtk_widget_set_size_request(cda, DT_PIXEL_APPLY_DPI(50), DT_PIXEL_APPLY_DPI(200)); gtk_widget_set_hexpand(ocda, TRUE); gtk_widget_set_vexpand(ocda, TRUE); gtk_widget_set_app_paintable(cda, TRUE); gtk_widget_set_can_focus(cda, TRUE); - darktable.gui->ui->snapshot = gtk_drawing_area_new(); - gtk_widget_set_no_show_all(darktable.gui->ui->snapshot, TRUE); + darktable.gui->ui->snapshot = _central_image_new(); + gtk_widget_hide(darktable.gui->ui->snapshot); GtkWidget *sidebyside = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(sidebyside), cda, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(sidebyside), darktable.gui->ui->snapshot, TRUE, TRUE, 0); @@ -1895,7 +1900,7 @@ static void _init_main_table(GtkWidget *container) void dt_ui_container_swap_left_right(struct dt_ui_t *ui, const gboolean swap) { - if(swap ^ strcmp("left", gtk_widget_get_name(gtk_widget_get_ancestor(*ui->containers, DTGTK_TYPE_SIDE_PANEL)))) + if(swap ^ g_strcmp0("left", gtk_widget_get_name(gtk_widget_get_ancestor(*ui->containers, DTGTK_TYPE_SIDE_PANEL)))) for(GtkWidget **c = ui->containers; c < ui->containers + 3; c++) {GtkWidget *tmp = *c; *c = c[3]; c[3] = tmp;} } @@ -2456,7 +2461,8 @@ static GtkWidget *_ui_init_panel_container_center(GtkWidget *container, container = widget; widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_widget_set_name(widget, "plugins_vbox_left"); - gtk_container_add(GTK_CONTAINER(container), widget); + gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(container), widget); + gtk_widget_set_vexpand(widget, TRUE); g_signal_connect_swapped(widget, "draw", G_CALLBACK(_side_panel_draw), NULL); GtkWidget *empty = gtk_event_box_new(); @@ -2578,7 +2584,7 @@ static void _ui_init_panel_left(dt_ui_t *ui, gtk_widget_set_name(widget, "left"); GtkWidget *over = gtk_overlay_new(); - gtk_container_add(GTK_CONTAINER(over), widget); + gtk_overlay_set_child(GTK_OVERLAY(over), widget); // we add a transparent overlay over the modules margins to resize the panel GtkWidget *handle = gtk_drawing_area_new(); gtk_widget_set_halign(handle, GTK_ALIGN_END); @@ -2629,7 +2635,7 @@ static void _ui_init_panel_right(dt_ui_t *ui, gtk_widget_set_name(widget, "right"); GtkWidget *over = gtk_overlay_new(); - gtk_container_add(GTK_CONTAINER(over), widget); + gtk_overlay_set_child(GTK_OVERLAY(over), widget); // we add a transparent overlay over the modules margins to resize the panel GtkWidget *handle = gtk_drawing_area_new(); gtk_widget_set_halign(handle, GTK_ALIGN_START); @@ -3396,8 +3402,8 @@ void dt_gui_load_theme(const char *theme) GError *error = NULL; GtkStyleProvider *themes_style_provider = GTK_STYLE_PROVIDER(gtk_css_provider_new()); - gtk_style_context_add_provider_for_screen - (gdk_screen_get_default(), themes_style_provider, GTK_STYLE_PROVIDER_PRIORITY_USER + 1); + gtk_style_context_add_provider_for_display + (gdk_display_get_default(), themes_style_provider, GTK_STYLE_PROVIDER_PRIORITY_USER + 1); usercsspath = g_build_filename(configdir, "user.css", NULL); @@ -3439,14 +3445,7 @@ void dt_gui_load_theme(const char *theme) themecss = newcss; } - if(!gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(themes_style_provider), - themecss, -1, &error)) - { - dt_print(DT_DEBUG_ALWAYS, - "%s: error parsing combined CSS %s: %s", - G_STRFUNC, themecss, error->message); - g_clear_error(&error); - } + gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(themes_style_provider), themecss, -1); g_free(themecss); @@ -3766,6 +3765,7 @@ GtkWidget *dt_ui_notebook_page(GtkNotebook *notebook, gtk_container_child_set(GTK_CONTAINER(notebook), page, "tab-expand", TRUE, "tab-fill", TRUE, NULL); if(page_num == 1 && +FALSE && // GTK4 !g_signal_handler_find(G_OBJECT(notebook), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, _notebook_size_callback, NULL)) { @@ -4108,10 +4108,12 @@ GtkWidget *dt_ui_resize_wrap(GtkWidget *w, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW(sw), - DT_PIXEL_APPLY_DPI(min_size)); +if(0) { // GTK4 g_signal_connect(G_OBJECT(sw), "scroll-event", G_CALLBACK(_resize_wrap_scroll), config_str); g_signal_connect(G_OBJECT(w), "draw", G_CALLBACK(_resize_wrap_draw), config_str); +} gtk_widget_set_margin_bottom(sw, DT_RESIZE_HANDLE_SIZE); w = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(w), sw); @@ -4132,7 +4134,6 @@ GtkWidget *dt_ui_resize_wrap(GtkWidget *w, G_CALLBACK(_resize_wrap_enter_leave), config_str); g_signal_connect_after(G_OBJECT(w), "draw", G_CALLBACK(_resize_wrap_draw_handle), NULL); - return w; } @@ -4347,12 +4348,8 @@ void dt_gui_new_collapsible_section(dt_gui_collapsible_section_t *cs, cs->module = module; // collapsible section header - GtkWidget *destdisp_head = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_BAUHAUS_SPACE); - GtkWidget *header_evb = gtk_event_box_new(); GtkWidget *destdisp = dt_ui_section_label_new(label); cs->label = destdisp; - dt_gui_add_class(destdisp_head, "dt_section_expander"); - gtk_container_add(GTK_CONTAINER(header_evb), destdisp); cs->toggle = dtgtk_togglebutton_new(dtgtk_cairo_paint_solid_arrow, (expanded @@ -4365,19 +4362,17 @@ void dt_gui_new_collapsible_section(dt_gui_collapsible_section_t *cs, cs->container = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_BAUHAUS_SPACE)); gtk_widget_set_name(GTK_WIDGET(cs->container), "collapsible"); - gtk_box_pack_start(GTK_BOX(destdisp_head), header_evb, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(destdisp_head), cs->toggle, FALSE, FALSE, 0); + g_signal_connect(G_OBJECT(cs->toggle), "toggled", + G_CALLBACK(_collapse_button_changed), cs); + g_signal_connect(G_OBJECT(cs->toggle), "button-press-event", // GTK4 should be whole header (but button-press only works on dtgtk) + G_CALLBACK(_collapse_expander_click), cs); + GtkWidget *destdisp_head = dt_gui_hbox(dt_gui_expand(destdisp), cs->toggle); + dt_gui_add_class(destdisp_head, "dt_section_expander"); cs->expander = dtgtk_expander_new(destdisp_head, GTK_WIDGET(cs->container)); gtk_box_pack_end(cs->parent, cs->expander, FALSE, FALSE, 0); dtgtk_expander_set_expanded(DTGTK_EXPANDER(cs->expander), expanded); gtk_widget_set_name(cs->expander, "collapse-block"); - - g_signal_connect(G_OBJECT(cs->toggle), "toggled", - G_CALLBACK(_collapse_button_changed), cs); - - g_signal_connect(G_OBJECT(header_evb), "button-press-event", - G_CALLBACK(_collapse_expander_click), cs); } void dt_gui_collapsible_section_set_label(dt_gui_collapsible_section_t *cs, @@ -4402,11 +4397,9 @@ GtkGestureSingle *(dt_gui_connect_click)(GtkWidget *widget, 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)); - + 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); @@ -4419,11 +4412,8 @@ GtkEventController *(dt_gui_connect_motion)(GtkWidget *widget, GCallback leave, gpointer data) { - GtkEventController *controller = gtk_event_controller_motion_new(widget); - 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 + GtkEventController *controller = gtk_event_controller_motion_new(); + gtk_widget_add_controller(widget, GTK_EVENT_CONTROLLER(controller)); if(motion) g_signal_connect(controller, "motion", motion, data); if(enter) g_signal_connect(controller, "enter", enter, data); @@ -4448,7 +4438,7 @@ void dt_gui_cursor_set_busy() GdkWindow *window = gtk_widget_get_window(toplevel); busy_prev_cursor = gdk_window_get_cursor(window); g_object_ref(busy_prev_cursor); - GdkCursor *watch = gdk_cursor_new_for_display(gtk_widget_get_display(toplevel), GDK_WATCH); + GdkCursor *watch = gdk_cursor_new_from_name(gtk_widget_get_display(toplevel), "wait"); gdk_window_set_cursor(window, watch); g_object_unref(watch); // since the main reason for calling this function is that we won't be running the Gtk main @@ -4535,7 +4525,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)); // GTK4 gtk_box_append + gtk_box_append(box, GTK_WIDGET(*list)); } return GTK_WIDGET(box); diff --git a/src/gui/gtk.h b/src/gui/gtk.h index 9fa8614ea380..4d93317b03b5 100644 --- a/src/gui/gtk.h +++ b/src/gui/gtk.h @@ -387,6 +387,7 @@ void dt_ellipsize_combo(GtkComboBox *cbox); static inline void dt_ui_section_label_set(GtkWidget *label) { + gtk_widget_set_hexpand(label, TRUE); // GTK4 gtk_widget_set_halign(label, GTK_ALIGN_FILL); // make it span the whole available width gtk_label_set_xalign (GTK_LABEL(label), 0.5f); gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END); // ellipsize labels diff --git a/src/gui/import_metadata.c b/src/gui/import_metadata.c index a30ec603d09a..a11d74d0b133 100644 --- a/src/gui/import_metadata.c +++ b/src/gui/import_metadata.c @@ -420,16 +420,16 @@ static void _fill_metadata_grid(dt_import_metadata_t *metadata) const char *str = dt_conf_get_string_const(setting); _set_up_entry(metadata_entry, str, metadata_name, i + DT_META_META_VALUE, metadata); g_free(setting); - g_signal_connect(GTK_ENTRY(metadata_entry), "changed", + g_signal_connect(metadata_entry, "changed", G_CALLBACK(_import_metadata_changed), metadata); - g_signal_connect(GTK_EVENT_BOX(labelev), "button-press-event", + g_signal_connect(labelev, "button-press-event", G_CALLBACK(_import_metadata_reset), metadata_entry); GtkWidget *metadata_imported = gtk_check_button_new(); g_object_set_data(G_OBJECT(metadata_imported), "tagname", md->tagname); _set_up_toggle_button(metadata_imported, flag & DT_METADATA_FLAG_IMPORTED, metadata_name, i + DT_META_META_VALUE, metadata); - g_signal_connect(GTK_TOGGLE_BUTTON(metadata_imported), "toggled", + g_signal_connect(metadata_imported, "toggled", G_CALLBACK(_import_metadata_toggled), metadata); i++; } @@ -459,7 +459,7 @@ void dt_import_metadata_init(dt_import_metadata_t *metadata) gtk_widget_set_tooltip_text(GTK_WIDGET(label), _("metadata to be applied per default" "\ndouble-click on a label to clear the corresponding entry" "\ndouble-click on 'preset' to clear all entries")); - g_signal_connect(GTK_EVENT_BOX(labelev), "button-press-event", + g_signal_connect(labelev, "button-press-event", G_CALLBACK(_import_metadata_reset_all), metadata); @@ -495,15 +495,15 @@ void dt_import_metadata_init(dt_import_metadata_t *metadata) const char *str = dt_conf_get_string_const("ui_last/import_last_tags"); _set_up_entry(entry, str, "tags", metadata->num_grid_rows + DT_META_TAGS_HEADER, metadata); gtk_widget_set_tooltip_text(entry, _("comma separated list of tags")); - g_signal_connect(GTK_ENTRY(entry), "changed", + g_signal_connect(entry, "changed", G_CALLBACK(_import_tags_changed), metadata); - g_signal_connect(GTK_EVENT_BOX(labelev), "button-press-event", + g_signal_connect(labelev, "button-press-event", G_CALLBACK(_import_metadata_reset), entry); GtkWidget *tags_imported = gtk_check_button_new(); _set_up_toggle_button(tags_imported, dt_conf_get_bool("ui_last/import_last_tags_imported"), "tags", metadata->num_grid_rows + DT_META_TAGS_HEADER, metadata); - g_signal_connect(GTK_TOGGLE_BUTTON(tags_imported), "toggled", + g_signal_connect(tags_imported, "toggled", G_CALLBACK(_import_metadata_toggled), metadata); // overall diff --git a/src/gui/preferences.c b/src/gui/preferences.c index bb29b7e05ab3..9ee0ed6f3c98 100644 --- a/src/gui/preferences.c +++ b/src/gui/preferences.c @@ -211,7 +211,7 @@ static void save_usercss(GtkTextBuffer *buffer) // write to file GError *error = NULL; - if(!g_file_set_contents(usercsspath, usercsscontent, -1, &error)) + if(!g_file_set_contents(usercsspath, usercsscontent, -1, &error) && error) { dt_print(DT_DEBUG_ALWAYS, "%s: error saving css to %s: %s", G_STRFUNC, usercsspath, error->message); @@ -594,7 +594,7 @@ void dt_gui_preferences_show() GtkGrid* lua_grid = init_tab_lua(_preferences_dialog, stack); #endif - gtk_widget_show_all(_preferences_dialog); + gtk_widget_show(_preferences_dialog); //open in the appropriate tab if currently in darkroom or lighttable view const gchar *current_view = dt_view_manager_name(darktable.view_manager); diff --git a/src/iop/atrous.c b/src/iop/atrous.c index 46b072a44c3a..0ec526e73ce3 100644 --- a/src/iop/atrous.c +++ b/src/iop/atrous.c @@ -1079,17 +1079,23 @@ void gui_update(dt_iop_module_t *self) // gui stuff: -static gboolean area_enter_leave_notify(GtkWidget *widget, - GdkEventCrossing *event, - dt_iop_module_t *self) +static void _atrous_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { dt_iop_atrous_gui_data_t *g = self->gui_data; - g->in_curve = event->type == GDK_ENTER_NOTIFY; + g->in_curve = controller == NULL; if(!g->dragging) g->x_move = -1; - gtk_widget_queue_draw(widget); - return FALSE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); +} + +static void _atrous_enter(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) +{ + _atrous_leave(NULL, self); } // fills in new parameters based on mouse position (in 0,1) @@ -1426,19 +1432,21 @@ static gboolean area_draw(GtkWidget *widget, return FALSE; } -static gboolean area_motion_notify(GtkWidget *widget, - GdkEventMotion *event, - dt_iop_module_t *self) +static void _atrous_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_atrous_gui_data_t *g = self->gui_data; dt_iop_atrous_params_t *p = self->params; + const int inset = INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); const int height = allocation.height - 2 * inset - DT_RESIZE_HANDLE_SIZE; const int width = allocation.width - 2 * inset; - if(!g->dragging) g->mouse_x = CLAMP(event->x - inset, 0, width) / (float)width; - g->mouse_y = 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + if(!g->dragging) g->mouse_x = CLAMP(x - inset, 0, width) / (float)width; + g->mouse_y = 1.0 - CLAMP(y - inset, 0, height) / (float)height; darktable.control->element = 0; @@ -1452,7 +1460,7 @@ static gboolean area_motion_notify(GtkWidget *widget, *p = g->drag_params; if(g->x_move >= 0) { - const float mx = CLAMP(event->x - inset, 0, width) / (float)width; + const float mx = CLAMP(x - inset, 0, width) / (float)width; if(g->x_move > 0 && g->x_move < BANDS - 1) { const float minx = p->x[g->channel][g->x_move - 1] + 0.001f; @@ -1464,10 +1472,9 @@ static gboolean area_motion_notify(GtkWidget *widget, { get_params(p, g->channel2, g->mouse_x, g->mouse_y + g->mouse_pick, g->mouse_radius); } - gtk_widget_queue_draw(widget); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + g->channel); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + g->channel); } - else if(event->y > height) + else if(y > height) { // move x-positions g->x_move = 0; @@ -1482,8 +1489,6 @@ static gboolean area_motion_notify(GtkWidget *widget, } } darktable.control->element = g->x_move + 1; - - gtk_widget_queue_draw(widget); } else { @@ -1504,61 +1509,57 @@ static gboolean area_motion_notify(GtkWidget *widget, } // don't move x-positions: g->x_move = -1; - gtk_widget_queue_draw(widget); } - return TRUE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } -static gboolean area_button_press(GtkWidget *widget, - GdkEventButton *event, - dt_iop_module_t *self) +static void _atrous_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { - if(event->button == GDK_BUTTON_PRIMARY && event->type == GDK_2BUTTON_PRESS) + dt_iop_atrous_gui_data_t *g = self->gui_data; + if(n_press == 2) { // reset current curve dt_iop_atrous_params_t *p = self->params; const dt_iop_atrous_params_t *const d = self->default_params; - dt_iop_atrous_gui_data_t *g = self->gui_data; reset_mix(self); for(int k = 0; k < BANDS; k++) { p->x[g->channel2][k] = d->x[g->channel2][k]; p->y[g->channel2][k] = d->y[g->channel2][k]; } - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + g->channel2); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + g->channel2); } - else if(event->button == GDK_BUTTON_PRIMARY) + else { // set active point - dt_iop_atrous_gui_data_t *g = self->gui_data; reset_mix(self); const int inset = INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); const int height = allocation.height - 2 * inset - DT_RESIZE_HANDLE_SIZE; const int width = allocation.width - 2 * inset; g->mouse_pick = dt_draw_curve_calc_value(g->minmax_curve, - CLAMP(event->x - inset, 0, width) / (float)width); - g->mouse_pick -= 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + CLAMP(x - inset, 0, width) / (float)width); + g->mouse_pick -= 1.0 - CLAMP(y - inset, 0, height) / (float)height; g->dragging = 1; - return TRUE; + dt_gui_claim(gesture); } - return FALSE; } -static gboolean area_button_release(GtkWidget *widget, - GdkEventButton *event, - dt_iop_module_t *self) +static void _atrous_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { - if(event->button == GDK_BUTTON_PRIMARY) - { - dt_iop_atrous_gui_data_t *g = self->gui_data; - g->dragging = 0; - reset_mix(self); - return TRUE; - } - return FALSE; + dt_iop_atrous_gui_data_t *g = self->gui_data; + g->dragging = 0; + reset_mix(self); } static gboolean area_scrolled(GtkWidget *widget, @@ -1808,16 +1809,8 @@ void gui_init(dt_iop_module_t *self) dt_action_define_iop(self, NULL, N_("graph"), GTK_WIDGET(g->area), &_action_def_equalizer); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(area_draw), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", - G_CALLBACK(area_button_press), self); - g_signal_connect(G_OBJECT(g->area), "button-release-event", - G_CALLBACK(area_button_release), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", - G_CALLBACK(area_motion_notify), self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", - G_CALLBACK(area_enter_leave_notify), self); - g_signal_connect(G_OBJECT(g->area), "enter-notify-event", - G_CALLBACK(area_enter_leave_notify), self); + dt_gui_connect_click(g->area, _atrous_button_press, _atrous_button_release, self); + dt_gui_connect_motion(g->area, _atrous_motion, _atrous_enter, _atrous_leave, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(area_scrolled), self); diff --git a/src/iop/basecurve.c b/src/iop/basecurve.c index a222747199a6..5ae246a77bec 100644 --- a/src/iop/basecurve.c +++ b/src/iop/basecurve.c @@ -1565,15 +1565,14 @@ void cleanup_global(dt_iop_module_so_t *self) self->data = NULL; } -static gboolean dt_iop_basecurve_leave_notify(GtkWidget *widget, - GdkEventCrossing *event, - dt_iop_module_t *self) +static void _basecurve_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { dt_iop_basecurve_gui_data_t *g = self->gui_data; + GdkEventCrossing *event = (GdkEventCrossing *)gtk_get_current_event(); if(!(event->state & GDK_BUTTON1_MASK)) g->selected = -1; - gtk_widget_queue_draw(widget); - return FALSE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } static float to_log(const float x, const float base) @@ -1810,9 +1809,10 @@ static gboolean _move_point_internal(dt_iop_module_t *self, float dy, const guint state); -static gboolean dt_iop_basecurve_motion_notify(GtkWidget *widget, - GdkEventMotion *event, - dt_iop_module_t *self) +static void _basecurve_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_basecurve_gui_data_t *g = self->gui_data; dt_iop_basecurve_params_t *p = self->params; @@ -1821,18 +1821,19 @@ static gboolean dt_iop_basecurve_motion_notify(GtkWidget *widget, dt_iop_basecurve_node_t *basecurve = p->basecurve[ch]; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); const int inset = DT_GUI_CURVE_EDITOR_INSET; int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset; const double old_m_x = g->mouse_x; const double old_m_y = g->mouse_y; - g->mouse_x = event->x - inset; - g->mouse_y = event->y - inset; + g->mouse_x = x - inset; + g->mouse_y = y - inset; const float mx = CLAMP(g->mouse_x, 0, width) / (float)width; const float my = 1.0f - CLAMP(g->mouse_y, 0, height) / (float)height; const float linx = to_lin(mx, g->loglogscale), liny = to_lin(my, g->loglogscale); + GdkEventMotion *event = (GdkEventMotion *)gtk_get_current_event(); if(event->state & GDK_BUTTON1_MASK) { // got a vertex selected: @@ -1847,13 +1848,14 @@ static gboolean dt_iop_basecurve_motion_notify(GtkWidget *widget, const float dy = to_lin(1 - g->mouse_y / height - translate_mouse_y, g->loglogscale) - to_lin(1 - old_m_y / height - translate_mouse_y, g->loglogscale); - return _move_point_internal(self, widget, dx, dy, event->state); + _move_point_internal(self, GTK_WIDGET(g->area), dx, dy, event->state); + return; } else if(nodes < MAXNODES && g->selected >= -1) { // no vertex was close, create a new one! g->selected = _add_node(basecurve, &p->basecurve_nodes[ch], linx, liny); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area); } } else @@ -1875,14 +1877,15 @@ static gboolean dt_iop_basecurve_motion_notify(GtkWidget *widget, } g->selected = nearest; } - if(g->selected >= 0) gtk_widget_grab_focus(widget); - gtk_widget_queue_draw(widget); - return TRUE; + if(g->selected >= 0) gtk_widget_grab_focus(GTK_WIDGET(g->area)); + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } -static gboolean dt_iop_basecurve_button_press(GtkWidget *widget, - GdkEventButton *event, - dt_iop_module_t *self) +static void _basecurve_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { dt_iop_basecurve_params_t *p = self->params; const dt_iop_basecurve_params_t *const d = self->default_params; @@ -1892,18 +1895,20 @@ static gboolean dt_iop_basecurve_button_press(GtkWidget *widget, int nodes = p->basecurve_nodes[ch]; dt_iop_basecurve_node_t *basecurve = p->basecurve[ch]; - if(event->button == GDK_BUTTON_PRIMARY) + dt_gui_claim(gesture); + guint button = gtk_gesture_single_get_current_button(gesture); + if(button == GDK_BUTTON_PRIMARY) { - if(event->type == GDK_BUTTON_PRESS && dt_modifier_is(event->state, GDK_CONTROL_MASK) + if(n_press == 1 && dt_modifier_eq(gesture, GDK_CONTROL_MASK) && nodes < MAXNODES && g->selected == -1) { // if we are not on a node -> add a new node at the current x of the pointer and y of the curve at that x const int inset = DT_GUI_CURVE_EDITOR_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); int width = allocation.width - 2 * inset; - g->mouse_x = event->x - inset; - g->mouse_y = event->y - inset; + g->mouse_x = x - inset; + g->mouse_y = y - inset; const float mx = CLAMP(g->mouse_x, 0, width) / (float)width; const float linx = to_lin(mx, g->loglogscale); @@ -1930,12 +1935,12 @@ static gboolean dt_iop_basecurve_button_press(GtkWidget *widget, (selected < nodes && basecurve[selected].x - linx <= 0.025))) { // evaluate the curve at the current x position - const float y = dt_draw_curve_calc_value(g->minmax_curve, linx); + const float calc_y = dt_draw_curve_calc_value(g->minmax_curve, linx); - if(y >= 0.0 && y <= 1.0) // never add something outside the viewport, you couldn't change it afterwards + if(calc_y >= 0.0 && calc_y <= 1.0) // never add something outside the viewport, you couldn't change it afterwards { // create a new node - selected = _add_node(basecurve, &p->basecurve_nodes[ch], linx, y); + selected = _add_node(basecurve, &p->basecurve_nodes[ch], linx, calc_y); // maybe set the new one as being selected float min = .04f; @@ -1943,17 +1948,16 @@ static gboolean dt_iop_basecurve_button_press(GtkWidget *widget, for(int k = 0; k < nodes; k++) { float other_y = to_log(basecurve[k].y, g->loglogscale); - float dist = (y - other_y) * (y - other_y); + float dist = (calc_y - other_y) * (calc_y - other_y); if(dist < min) g->selected = selected; } - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area); gtk_widget_queue_draw(GTK_WIDGET(g->area)); } } - return TRUE; } - else if(event->type == GDK_2BUTTON_PRESS) + else if(n_press == 2) { // reset current curve p->basecurve_nodes[ch] = d->basecurve_nodes[ch]; @@ -1964,20 +1968,19 @@ static gboolean dt_iop_basecurve_button_press(GtkWidget *widget, p->basecurve[ch][k].y = d->basecurve[ch][k].y; } g->selected = -2; // avoid motion notify re-inserting immediately. - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area); gtk_widget_queue_draw(GTK_WIDGET(g->area)); - return TRUE; } } - else if(event->button == GDK_BUTTON_SECONDARY && g->selected >= 0) + else if(button == GDK_BUTTON_SECONDARY && g->selected >= 0) { if(g->selected == 0 || g->selected == nodes - 1) { float reset_value = g->selected == 0 ? 0 : 1; basecurve[g->selected].y = basecurve[g->selected].x = reset_value; gtk_widget_queue_draw(GTK_WIDGET(g->area)); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget); - return TRUE; + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area); + return; } for(int k = g->selected; k < nodes - 1; k++) @@ -1989,10 +1992,8 @@ static gboolean dt_iop_basecurve_button_press(GtkWidget *widget, g->selected = -2; // avoid re-insertion of that point immediately after this p->basecurve_nodes[ch]--; gtk_widget_queue_draw(GTK_WIDGET(g->area)); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget); - return TRUE; + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area); } - return FALSE; } static gboolean _move_point_internal(dt_iop_module_t *self, @@ -2164,9 +2165,8 @@ void gui_init(dt_iop_module_t *self) | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); gtk_widget_set_can_focus(GTK_WIDGET(g->area), TRUE); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(dt_iop_basecurve_draw), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(dt_iop_basecurve_button_press), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(dt_iop_basecurve_motion_notify), self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(dt_iop_basecurve_leave_notify), self); + dt_gui_connect_click_all(g->area, _basecurve_button_press, NULL, self); + dt_gui_connect_motion(g->area, _basecurve_motion, NULL, _basecurve_leave, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(_scrolled), self); g_signal_connect(G_OBJECT(g->area), "key-press-event", G_CALLBACK(dt_iop_basecurve_key_press), self); } diff --git a/src/iop/bilat.c b/src/iop/bilat.c index 698dbc8aaebb..819e81d420a5 100644 --- a/src/iop/bilat.c +++ b/src/iop/bilat.c @@ -491,11 +491,11 @@ void gui_init(dt_iop_module_t *self) " increase for more powerful local contrast")); // work around multi-instance issue which calls show all a fair bit: - g_object_set(G_OBJECT(g->highlights), "no-show-all", TRUE, NULL); - g_object_set(G_OBJECT(g->shadows), "no-show-all", TRUE, NULL); - g_object_set(G_OBJECT(g->midtone), "no-show-all", TRUE, NULL); - g_object_set(G_OBJECT(g->range), "no-show-all", TRUE, NULL); - g_object_set(G_OBJECT(g->spatial), "no-show-all", TRUE, NULL); + gtk_widget_set_no_show_all(g->highlights, TRUE); + gtk_widget_set_no_show_all(g->shadows, TRUE); + gtk_widget_set_no_show_all(g->midtone, TRUE); + gtk_widget_set_no_show_all(g->range, TRUE); + gtk_widget_set_no_show_all(g->spatial, TRUE); } diff --git a/src/iop/colorchecker.c b/src/iop/colorchecker.c index 41e0b5237e34..957fd58bf781 100644 --- a/src/iop/colorchecker.c +++ b/src/iop/colorchecker.c @@ -1379,22 +1379,22 @@ static gboolean checker_draw(GtkWidget *widget, return TRUE; } -static gboolean checker_motion_notify( - GtkWidget *widget, - GdkEventMotion *event, - dt_iop_module_t *self) +static void _colorchecker_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { // highlight? dt_iop_colorchecker_params_t *p = self->params; dt_iop_colorchecker_gui_data_t *g = self->gui_data; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); const int width = allocation.width; const int height = allocation.height; - const float mouse_x = CLAMP(event->x, 0, width); - const float mouse_y = CLAMP(event->y, 0, height); + const float mouse_x = CLAMP(x, 0, width); + const float mouse_y = CLAMP(y, 0, height); int cells_x = 6, cells_y = 4; if(p->num_patches > 24) { @@ -1404,7 +1404,7 @@ static gboolean checker_motion_notify( const float mx = mouse_x * cells_x / (float)width; const float my = mouse_y * cells_y / (float)height; const int patch = (int)mx + cells_x * (int)my; - if(patch < 0 || patch >= p->num_patches) return FALSE; + if(patch < 0 || patch >= p->num_patches) return; char tooltip[1024]; snprintf(tooltip, sizeof(tooltip), _("(%2.2f %2.2f %2.2f)\n" @@ -1415,21 +1415,22 @@ static gboolean checker_motion_notify( "shift+click while color picking to replace patch"), p->source_L[patch], p->source_a[patch], p->source_b[patch]); gtk_widget_set_tooltip_text(g->area, tooltip); - return TRUE; } -static gboolean checker_button_press( - GtkWidget *widget, GdkEventButton *event, - dt_iop_module_t *self) +static void _colorchecker_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { dt_iop_colorchecker_params_t *p = self->params; dt_iop_colorchecker_gui_data_t *g = self->gui_data; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); int width = allocation.width, height = allocation.height; - const float mouse_x = CLAMP(event->x, 0, width); - const float mouse_y = CLAMP(event->y, 0, height); + const float mouse_x = CLAMP(x, 0, width); + const float mouse_y = CLAMP(y, 0, height); int cells_x = 6, cells_y = 4; if(p->num_patches > 24) { @@ -1439,9 +1440,12 @@ static gboolean checker_button_press( const float mx = mouse_x * cells_x / (float)width; const float my = mouse_y * cells_y / (float)height; int patch = (int)mx + cells_x*(int)my; - if(event->button == GDK_BUTTON_PRIMARY && event->type == GDK_2BUTTON_PRESS) + + dt_gui_claim(gesture); + guint button = gtk_gesture_single_get_current_button(gesture); + if(button == GDK_BUTTON_PRIMARY && n_press == 2) { // reset on double click - if(patch < 0 || patch >= p->num_patches) return FALSE; + if(patch < 0 || patch >= p->num_patches) return; p->target_L[patch] = p->source_L[patch]; p->target_a[patch] = p->source_a[patch]; p->target_b[patch] = p->source_b[patch]; @@ -1450,12 +1454,13 @@ static gboolean checker_button_press( _colorchecker_update_sliders(self); --darktable.gui->reset; gtk_widget_queue_draw(g->area); - return TRUE; + dt_gui_claim(gesture); + return; } - else if(event->button == GDK_BUTTON_SECONDARY && (patch < p->num_patches)) + else if(button == GDK_BUTTON_SECONDARY && (patch < p->num_patches)) { // right click: delete patch, move others up - if(patch < 0 || patch >= p->num_patches) return FALSE; + if(patch < 0 || patch >= p->num_patches) return; memmove(p->target_L+patch, p->target_L+patch+1, sizeof(float)*(p->num_patches-1-patch)); memmove(p->target_a+patch, p->target_a+patch+1, @@ -1475,10 +1480,11 @@ static gboolean checker_button_press( _colorchecker_update_sliders(self); --darktable.gui->reset; gtk_widget_queue_draw(g->area); - return TRUE; + dt_gui_claim(gesture); + return; } - else if((event->button == GDK_BUTTON_PRIMARY) && - dt_modifier_is(event->state, GDK_SHIFT_MASK) && + else if((button == GDK_BUTTON_PRIMARY) && + dt_modifier_eq(gesture, GDK_SHIFT_MASK) && (self->request_color_pick == DT_REQUEST_COLORPICK_MODULE)) { // shift-left while colour picking: replace source colour @@ -1519,11 +1525,12 @@ static gboolean checker_button_press( g->patch = g->drawn_patch = patch; gtk_widget_queue_draw(g->area); } - return TRUE; + dt_gui_claim(gesture); + return; } if(patch >= p->num_patches) patch = p->num_patches-1; dt_bauhaus_combobox_set(g->combobox_patch, patch); - return FALSE; + return; } void gui_init(dt_iop_module_t *self) @@ -1533,16 +1540,10 @@ void gui_init(dt_iop_module_t *self) // custom 24-patch widget in addition to combo box g->area = dtgtk_drawing_area_new_with_aspect_ratio(4.0/6.0); - gtk_widget_add_events(GTK_WIDGET(g->area), - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - | GDK_LEAVE_NOTIFY_MASK); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(checker_draw), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", - G_CALLBACK(checker_button_press), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", - G_CALLBACK(checker_motion_notify), self); + dt_gui_connect_click_all(g->area, _colorchecker_button_press, NULL, self); + dt_gui_connect_motion(g->area, _colorchecker_motion, NULL, NULL, self); g->patch = 0; g->drawn_patch = -1; diff --git a/src/iop/colorcorrection.c b/src/iop/colorcorrection.c index 8a7551e3c5b4..ed92c1a97daf 100644 --- a/src/iop/colorcorrection.c +++ b/src/iop/colorcorrection.c @@ -219,12 +219,17 @@ void gui_update(dt_iop_module_t *self) static gboolean dt_iop_colorcorrection_draw(GtkWidget *widget, cairo_t *cr, dt_iop_module_t *self); -static gboolean dt_iop_colorcorrection_motion_notify(GtkWidget *widget, GdkEventMotion *event, - dt_iop_module_t *self); -static gboolean dt_iop_colorcorrection_button_press(GtkWidget *widget, GdkEventButton *event, - dt_iop_module_t *self); -static gboolean dt_iop_colorcorrection_leave_notify(GtkWidget *widget, GdkEventCrossing *event, - dt_iop_module_t *self); +static void _colorcorrection_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self); +static void _colorcorrection_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self); +static void _colorcorrection_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self); static gboolean dt_iop_colorcorrection_scrolled(GtkWidget *widget, GdkEventScroll *event, dt_iop_module_t *self); static gboolean dt_iop_colorcorrection_key_press(GtkWidget *widget, GdkEventKey *event, @@ -242,17 +247,11 @@ void gui_init(dt_iop_module_t *self) gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _("drag the line for split-toning. " "bright means highlights, dark means shadows. " "use mouse wheel to change saturation.")); - gtk_widget_add_events(GTK_WIDGET(g->area), GDK_POINTER_MOTION_MASK | darktable.gui->scroll_mask - | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); + gtk_widget_add_events(GTK_WIDGET(g->area), darktable.gui->scroll_mask); gtk_widget_set_can_focus(GTK_WIDGET(g->area), TRUE); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(dt_iop_colorcorrection_draw), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(dt_iop_colorcorrection_button_press), - self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(dt_iop_colorcorrection_motion_notify), - self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(dt_iop_colorcorrection_leave_notify), - self); + dt_gui_connect_click(g->area, _colorcorrection_button_press, NULL, self); + dt_gui_connect_motion(g->area, _colorcorrection_motion, NULL, _colorcorrection_leave, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(dt_iop_colorcorrection_scrolled), self); g_signal_connect(G_OBJECT(g->area), "key-press-event", G_CALLBACK(dt_iop_colorcorrection_key_press), self); @@ -346,19 +345,22 @@ static gboolean dt_iop_colorcorrection_draw(GtkWidget *widget, cairo_t *crf, dt_ return TRUE; } -static gboolean dt_iop_colorcorrection_motion_notify(GtkWidget *widget, GdkEventMotion *event, - dt_iop_module_t *self) +static void _colorcorrection_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_colorcorrection_gui_data_t *g = self->gui_data; dt_iop_colorcorrection_params_t *p = self->params; const int inset = DT_COLORCORRECTION_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); int width = allocation.width - 2 * inset, height = allocation.height - 2 * inset; - const float mouse_x = CLAMP(event->x - inset, 0, width); - const float mouse_y = CLAMP(height - 1 - event->y + inset, 0, height); + const float mouse_x = CLAMP(x - inset, 0, width); + const float mouse_y = CLAMP(height - 1 - y + inset, 0, height); const float ma = (2.0 * mouse_x - width) * DT_COLORCORRECTION_MAX / (float)width; const float mb = (2.0 * mouse_y - height) * DT_COLORCORRECTION_MAX / (float)height; + GdkEventMotion *event = (GdkEventMotion *)gtk_get_current_event(); if(event->state & GDK_BUTTON1_MASK) { if(g->selected == 1) @@ -385,15 +387,18 @@ static gboolean dt_iop_colorcorrection_motion_notify(GtkWidget *widget, GdkEvent else if(disthi < thrs * thrs && disthi <= distlo) g->selected = 2; } - if(g->selected > 0) gtk_widget_grab_focus(widget); + if(g->selected > 0) gtk_widget_grab_focus(GTK_WIDGET(g->area)); gtk_widget_queue_draw(GTK_WIDGET(g->area)); - return TRUE; } -static gboolean dt_iop_colorcorrection_button_press(GtkWidget *widget, GdkEventButton *event, - dt_iop_module_t *self) +static void _colorcorrection_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { - if(event->button == GDK_BUTTON_PRIMARY && event->type == GDK_2BUTTON_PRESS) + dt_gui_claim(gesture); + if(n_press == 2) { // double click resets: dt_iop_colorcorrection_gui_data_t *g = self->gui_data; @@ -415,17 +420,14 @@ static gboolean dt_iop_colorcorrection_button_press(GtkWidget *widget, GdkEventB dt_dev_add_history_item(darktable.develop, self, TRUE); } } - return TRUE; } - return FALSE; } -static gboolean dt_iop_colorcorrection_leave_notify(GtkWidget *widget, GdkEventCrossing *event, - dt_iop_module_t *self) +static void _colorcorrection_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { dt_iop_colorcorrection_gui_data_t *g = self->gui_data; gtk_widget_queue_draw(GTK_WIDGET(g->area)); - return TRUE; } static gboolean dt_iop_colorcorrection_scrolled(GtkWidget *widget, GdkEventScroll *event, dt_iop_module_t *self) diff --git a/src/iop/colorequal.c b/src/iop/colorequal.c index c8c8c478c5cc..07c0ebd658f2 100644 --- a/src/iop/colorequal.c +++ b/src/iop/colorequal.c @@ -2742,76 +2742,68 @@ static gboolean _area_scrolled_callback(GtkWidget *widget, return gtk_widget_event(w, (GdkEvent*)event); } -static gboolean _area_motion_notify_callback(GtkWidget *widget, - const GdkEventMotion *event, - const dt_iop_module_t *self) +static void _colorequal_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_colorequal_gui_data_t *g = self->gui_data; if(g->dragging && g->on_node) - _area_set_pos(g, event->y); + _area_set_pos(g, y); else { // look if close to a node const float epsilon = DT_PIXEL_APPLY_DPI(10.0); const int oldsel = g->selected; const int oldon = g->on_node; - g->selected = (int)(((float)event->x - g->points[0][0]) + g->selected = (int)(((float)x - g->points[0][0]) / (g->points[1][0] - g->points[0][0]) + 0.5f) % NODES; - g->on_node = fabsf(g->points[g->selected][1] - (float)event->y) < epsilon; + g->on_node = fabsf(g->points[g->selected][1] - (float)y) < epsilon; darktable.control->element = g->selected; if(oldsel != g->selected || oldon != g->on_node) gtk_widget_queue_draw(GTK_WIDGET(g->area)); } - - return TRUE; } -static gboolean _area_button_press_callback(GtkWidget *widget, - GdkEventButton *event, - dt_iop_module_t *self) +static void _colorequal_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { dt_iop_colorequal_gui_data_t *g = self->gui_data; - if(event->button == GDK_BUTTON_MIDDLE - || (event->button == GDK_BUTTON_PRIMARY // Ctrl+Click alias for macOS - && dt_modifier_is(event->state, GDK_CONTROL_MASK))) + guint button = gtk_gesture_single_get_current_button(gesture); + if(button == GDK_BUTTON_MIDDLE + || (button == GDK_BUTTON_PRIMARY // Ctrl+Click alias for macOS + && dt_modifier_eq(gesture, GDK_CONTROL_MASK))) { dt_conf_set_bool("plugins/darkroom/colorequal/show_sliders", gtk_notebook_get_n_pages(g->notebook) != 4); gui_update(self); } - else if(event->button == GDK_BUTTON_PRIMARY) + else if(button == GDK_BUTTON_PRIMARY) { - if(event->type == GDK_2BUTTON_PRESS) - { + dt_gui_claim(gesture); + if(n_press == 2) _area_reset_nodes(g); - return TRUE; - } else - { g->dragging = TRUE; - } } - else - return gtk_widget_event(_get_slider(g, g->selected), (GdkEvent*)event); - - return FALSE; + // FIXME + // else + // return gtk_widget_event(_get_slider(g, g->selected), (GdkEvent*)event); } -static gboolean _area_button_release_callback(GtkWidget *widget, - const GdkEventButton *event, - const dt_iop_module_t *self) +static void _colorequal_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { dt_iop_colorequal_gui_data_t *g = self->gui_data; - - if(event->button == GDK_BUTTON_PRIMARY) - { - g->dragging = FALSE; - return TRUE; - } - - return FALSE; + g->dragging = FALSE; } static gboolean _area_size_callback(GtkWidget *widget, @@ -3016,19 +3008,10 @@ void gui_init(dt_iop_module_t *self) dt_action_define_iop(self, NULL, N_("graph"), GTK_WIDGET(g->area), &_action_def_coloreq); gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _("double-click to reset the curve\nmiddle-click to toggle sliders visibility\nalt+scroll to change page")); gtk_widget_set_can_focus(GTK_WIDGET(g->area), TRUE); - gtk_widget_add_events(GTK_WIDGET(g->area), - GDK_BUTTON_PRESS_MASK - | GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_SCROLL_MASK - | GDK_SMOOTH_SCROLL_MASK); + gtk_widget_add_events(GTK_WIDGET(g->area), darktable.gui->scroll_mask); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(_iop_colorequalizer_draw), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", - G_CALLBACK(_area_button_press_callback), self); - g_signal_connect(G_OBJECT(g->area), "button-release-event", - G_CALLBACK(_area_button_release_callback), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", - G_CALLBACK(_area_motion_notify_callback), self); + dt_gui_connect_click_all(g->area, _colorequal_button_press, _colorequal_button_release, self); + dt_gui_connect_motion(g->area, _colorequal_motion, NULL, NULL, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(_area_scrolled_callback), self); g_signal_connect(G_OBJECT(g->area), "size_allocate", diff --git a/src/iop/colorzones.c b/src/iop/colorzones.c index 93c022a8f7ef..20c3d2053315 100644 --- a/src/iop/colorzones.c +++ b/src/iop/colorzones.c @@ -1919,15 +1919,18 @@ static gboolean _area_scrolled_callback(GtkWidget *widget, return TRUE; } -static gboolean _area_motion_notify_callback(GtkWidget *widget, - GdkEventMotion *event, - dt_iop_module_t *self) +static void _colorzones_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_colorzones_gui_data_t *g = self->gui_data; dt_iop_colorzones_params_t *p = self->params; const int inset = DT_IOP_COLORZONES_INSET; + GdkEventMotion *event = (GdkEventMotion *)gtk_get_current_event(); + GtkWidget *widget = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(controller)); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); @@ -1940,8 +1943,8 @@ static gboolean _area_motion_notify_callback(GtkWidget *widget, const float mx = g->mouse_x; const float my = g->mouse_y; - g->mouse_x = CLAMP(event->x - inset, 0, width) / (float)width; - g->mouse_y = 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + g->mouse_x = CLAMP(x - inset, 0, width) / (float)width; + g->mouse_y = 1.0 - CLAMP(y - inset, 0, height) / (float)height; if(event->state & GDK_BUTTON1_MASK) { @@ -1953,7 +1956,7 @@ static gboolean _area_motion_notify_callback(GtkWidget *widget, gtk_widget_queue_draw(GTK_WIDGET(g->area)); } - return TRUE; + return; } const int ch = g->channel; @@ -1963,8 +1966,8 @@ static gboolean _area_motion_notify_callback(GtkWidget *widget, const double old_m_x = g->mouse_x; const double old_m_y = fabs(g->mouse_y); - g->mouse_x = CLAMP(event->x - inset, 0, width) / (float)width; - g->mouse_y = 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + g->mouse_x = CLAMP(x - inset, 0, width) / (float)width; + g->mouse_y = 1.0 - CLAMP(y - inset, 0, height) / (float)height; darktable.control->element = (int)(8.0 * @@ -2003,7 +2006,8 @@ static gboolean _area_motion_notify_callback(GtkWidget *widget, g->zoom_factor, g->offset_y); dt_iop_color_picker_reset(self, TRUE); - return _move_point_internal(self, widget, g->selected, dx, dy, event->state); + _move_point_internal(self, widget, g->selected, dx, dy, event->state); + return; } } @@ -2019,7 +2023,7 @@ static gboolean _area_motion_notify_callback(GtkWidget *widget, dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); } } - else if(event->y > height) + else if(y > height) { g->x_move = 0; const int bands = p->curve_num_nodes[g->channel]; @@ -2085,33 +2089,37 @@ static gboolean _area_motion_notify_callback(GtkWidget *widget, } gtk_widget_queue_draw(widget); - return TRUE; + return; } -static gboolean _area_button_press_callback(GtkWidget *widget, - GdkEventButton *event, - dt_iop_module_t *self) +static void _colorzones_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { dt_iop_colorzones_gui_data_t *g = self->gui_data; dt_iop_colorzones_params_t *p = self->params; const dt_iop_colorzones_params_t *const d = self->default_params; - if(darktable.develop->darkroom_skip_mouse_events) return TRUE; + if(darktable.develop->darkroom_skip_mouse_events) return; int ch = g->channel; int nodes = p->curve_num_nodes[ch]; dt_iop_colorzones_node_t *curve = p->curve[ch]; - if(event->button == GDK_BUTTON_PRIMARY) + GtkWidget *widget = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture)); + guint button = gtk_gesture_single_get_current_button(gesture); + if(button == GDK_BUTTON_PRIMARY) { - if(g->edit_by_area && event->type != GDK_2BUTTON_PRESS - && !dt_modifier_is(event->state, GDK_CONTROL_MASK)) + if(g->edit_by_area && n_press != 2 + && !dt_modifier_eq(gesture, GDK_CONTROL_MASK)) { g->dragging = 1; - return TRUE; + return; } - else if(event->type == GDK_BUTTON_PRESS - && dt_modifier_is(event->state, GDK_CONTROL_MASK) + else if(n_press == 1 + && dt_modifier_eq(gesture, GDK_CONTROL_MASK) && nodes < DT_IOP_COLORZONES_MAXNODES && (g->selected == -1 || g->edit_by_area)) { @@ -2123,8 +2131,8 @@ static gboolean _area_button_press_callback(GtkWidget *widget, const int height = allocation.height - 2 * inset; const int width = allocation.width - 2 * inset; - g->mouse_x = CLAMP(event->x - inset, 0, width) / (float)width; - g->mouse_y = 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + g->mouse_x = CLAMP(x - inset, 0, width) / (float)width; + g->mouse_y = 1.0 - CLAMP(y - inset, 0, height) / (float)height; const float mx = _mouse_to_curve(g->mouse_x, g->zoom_factor, g->offset_x); @@ -2146,14 +2154,14 @@ static gboolean _area_button_press_callback(GtkWidget *widget, if(selected == -1) selected = nodes; // evaluate the curve at the current x position - const float y = dt_draw_curve_calc_value(g->minmax_curve[ch], mx); + const float calc_y = dt_draw_curve_calc_value(g->minmax_curve[ch], mx); - if(y >= 0.0f && y <= 1.0f) // never add something outside the - // viewport, you couldn't change it - // afterwards + if(calc_y >= 0.0f && calc_y <= 1.0f) // never add something outside the + // viewport, you couldn't change it + // afterwards { // create a new node - selected = _add_node(curve, &p->curve_num_nodes[ch], mx, y); + selected = _add_node(curve, &p->curve_num_nodes[ch], mx, calc_y); // maybe set the new one as being selected const float min = .04f * .04f; // comparing against square @@ -2161,7 +2169,7 @@ static gboolean _area_button_press_callback(GtkWidget *widget, for(int k = 0; k < nodes; k++) { const float other_y = _curve_to_mouse(curve[k].y, g->zoom_factor, g->offset_y); - const float dist = (y - other_y) * (y - other_y); + const float dist = (calc_y - other_y) * (calc_y - other_y); if(dist < min) g->selected = selected; } @@ -2170,9 +2178,9 @@ static gboolean _area_button_press_callback(GtkWidget *widget, gtk_widget_queue_draw(GTK_WIDGET(g->area)); } - return TRUE; + return; } - else if(event->type == GDK_2BUTTON_PRESS) + else if(n_press == 2) { // reset current curve p->curve_num_nodes[ch] = d->curve_num_nodes[ch]; @@ -2188,11 +2196,12 @@ static gboolean _area_button_press_callback(GtkWidget *widget, dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); gtk_widget_queue_draw(GTK_WIDGET(g->area)); - return TRUE; + return; } } - else if(event->button == GDK_BUTTON_SECONDARY && g->selected >= 0) + else if(button == GDK_BUTTON_SECONDARY && g->selected >= 0) { + dt_gui_claim(gesture); if((g->selected == 0 || g->selected == nodes - 1) && p->splines_version == DT_IOP_COLORZONES_SPLINES_V1) { @@ -2213,48 +2222,43 @@ static gboolean _area_button_press_callback(GtkWidget *widget, dt_iop_color_picker_reset(self, TRUE); gtk_widget_queue_draw(GTK_WIDGET(g->area)); dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); - return TRUE; + return; } // right click deletes the node, ctrl+right click reset the node to y-zero _delete_node(self, curve, &p->curve_num_nodes[ch], - g->selected, dt_modifier_is(event->state, GDK_CONTROL_MASK)); + g->selected, dt_modifier_eq(gesture, GDK_CONTROL_MASK)); g->selected = -2; // avoid re-insertion of that point immediately after this - - return TRUE; } - - return FALSE; } -static gboolean _area_button_release_callback(GtkWidget *widget, - GdkEventButton *event, - dt_iop_module_t *self) +static void _colorzones_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { - if(darktable.develop->darkroom_skip_mouse_events) return TRUE; + if(darktable.develop->darkroom_skip_mouse_events) return; - if(event->button == GDK_BUTTON_PRIMARY) + if(gtk_gesture_single_get_current_button(gesture) == GDK_BUTTON_PRIMARY) { dt_iop_colorzones_gui_data_t *g = self->gui_data; g->dragging = 0; - return TRUE; } - return FALSE; } -static gboolean _area_leave_notify_callback(GtkWidget *widget, - GdkEventCrossing *event, - dt_iop_module_t *self) +static void _colorzones_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { - if(darktable.develop->darkroom_skip_mouse_events) return TRUE; + if(darktable.develop->darkroom_skip_mouse_events) return; dt_iop_colorzones_gui_data_t *g = self->gui_data; // for fluxbox g->mouse_y = -fabs(g->mouse_y); + GdkEventCrossing *event = (GdkEventCrossing *)gtk_get_current_event(); if(!(event->state & GDK_BUTTON1_MASK)) g->selected = -1; - gtk_widget_queue_draw(widget); - return TRUE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } static gboolean _area_key_press_callback(GtkWidget *widget, @@ -2707,14 +2711,8 @@ void gui_init(dt_iop_module_t *self) gtk_widget_set_can_focus(GTK_WIDGET(g->area), TRUE); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(_area_draw_callback), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", - G_CALLBACK(_area_button_press_callback), self); - g_signal_connect(G_OBJECT(g->area), "button-release-event", - G_CALLBACK(_area_button_release_callback), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", - G_CALLBACK(_area_motion_notify_callback), self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", - G_CALLBACK(_area_leave_notify_callback), self); + dt_gui_connect_click(g->area, _colorzones_button_press, _colorzones_button_release, self); + dt_gui_connect_motion(g->area, _colorzones_motion, NULL, _colorzones_leave, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(_area_scrolled_callback), self); g_signal_connect(G_OBJECT(g->area), "key-press-event", diff --git a/src/iop/denoiseprofile.c b/src/iop/denoiseprofile.c index bc57ce5bb737..01f7dd86db57 100644 --- a/src/iop/denoiseprofile.c +++ b/src/iop/denoiseprofile.c @@ -3510,18 +3510,19 @@ static gboolean denoiseprofile_draw(GtkWidget *widget, return FALSE; } -static gboolean denoiseprofile_motion_notify(GtkWidget *widget, - GdkEventMotion *event, - dt_iop_module_t *self) +static void _denoiseprofile_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_denoiseprofile_gui_data_t *g = self->gui_data; dt_iop_denoiseprofile_params_t *p = self->params; const int inset = DT_IOP_DENOISE_PROFILE_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset; - if(!g->dragging) g->mouse_x = CLAMP(event->x - inset, 0, width) / (float)width; - g->mouse_y = 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + if(!g->dragging) g->mouse_x = CLAMP(x - inset, 0, width) / (float)width; + g->mouse_y = 1.0 - CLAMP(y - inset, 0, height) / (float)height; if(g->dragging) { *p = g->drag_params; @@ -3537,17 +3538,18 @@ static gboolean denoiseprofile_motion_notify(GtkWidget *widget, { g->x_move = -1; } - gtk_widget_queue_draw(widget); - return TRUE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } -static gboolean denoiseprofile_button_press(GtkWidget *widget, - GdkEventButton *event, - dt_iop_module_t *self) +static void _denoiseprofile_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { dt_iop_denoiseprofile_gui_data_t *g = self->gui_data; const int ch = g->channel; - if(event->button == 1 && event->type == GDK_2BUTTON_PRESS) + if(n_press == 2) { // reset current curve dt_iop_denoiseprofile_params_t *p = self->params; @@ -3561,44 +3563,37 @@ static gboolean denoiseprofile_button_press(GtkWidget *widget, dt_dev_add_history_item(darktable.develop, self, TRUE); gtk_widget_queue_draw(GTK_WIDGET(g->area)); } - else if(event->button == GDK_BUTTON_PRIMARY) + else { g->drag_params = *(dt_iop_denoiseprofile_params_t *)self->params; const int inset = DT_IOP_DENOISE_PROFILE_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset; g->mouse_pick = dt_draw_curve_calc_value(g->transition_curve, - CLAMP(event->x - inset, 0, width) / (float)width); - g->mouse_pick -= 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + CLAMP(x - inset, 0, width) / (float)width); + g->mouse_pick -= 1.0 - CLAMP(y - inset, 0, height) / (float)height; g->dragging = 1; - return TRUE; } - return FALSE; } -static gboolean denoiseprofile_button_release(GtkWidget *widget, - GdkEventButton *event, - dt_iop_module_t *self) +static void _denoiseprofile_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { - if(event->button == GDK_BUTTON_PRIMARY) - { - dt_iop_denoiseprofile_gui_data_t *g = self->gui_data; - g->dragging = 0; - return TRUE; - } - return FALSE; + dt_iop_denoiseprofile_gui_data_t *g = self->gui_data; + g->dragging = 0; } -static gboolean denoiseprofile_leave_notify(GtkWidget *widget, - GdkEventCrossing *event, - dt_iop_module_t *self) +static void _denoiseprofile_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { dt_iop_denoiseprofile_gui_data_t *g = self->gui_data; if(!g->dragging) g->mouse_y = -1.0; - gtk_widget_queue_draw(widget); - return TRUE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } static gboolean denoiseprofile_scrolled(GtkWidget *widget, @@ -3700,14 +3695,8 @@ void gui_init(dt_iop_module_t *self) dt_action_define_iop(self, NULL, N_("graph"), GTK_WIDGET(g->area), NULL); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(denoiseprofile_draw), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", - G_CALLBACK(denoiseprofile_button_press), self); - g_signal_connect(G_OBJECT(g->area), "button-release-event", - G_CALLBACK(denoiseprofile_button_release), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", - G_CALLBACK(denoiseprofile_motion_notify), self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", - G_CALLBACK(denoiseprofile_leave_notify), self); + dt_gui_connect_click(g->area, _denoiseprofile_button_press, _denoiseprofile_button_release, self); + dt_gui_connect_motion(g->area, _denoiseprofile_motion, NULL, _denoiseprofile_leave, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(denoiseprofile_scrolled), self); diff --git a/src/iop/exposure.c b/src/iop/exposure.c index 59cc6d4d313d..73c60e6cca60 100644 --- a/src/iop/exposure.c +++ b/src/iop/exposure.c @@ -33,6 +33,7 @@ #include "develop/imageop_math.h" #include "develop/imageop_gui.h" #include "develop/pixelpipe.h" +#include "dtgtk/drawingarea.h" #include "dtgtk/paint.h" #include "dtgtk/resetlabel.h" #include "gui/accelerators.h" diff --git a/src/iop/filmicrgb.c b/src/iop/filmicrgb.c index e8d2d75dc2a1..e71238895a13 100644 --- a/src/iop/filmicrgb.c +++ b/src/iop/filmicrgb.c @@ -4183,9 +4183,13 @@ static gboolean dt_iop_tonecurve_draw(GtkWidget *widget, cairo_t *crf, dt_iop_mo return FALSE; } -static gboolean area_button_press(GtkWidget *widget, const GdkEventButton *event, dt_iop_module_t *self) +static void _filmicrgb_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { - if(darktable.gui->reset) return TRUE; + if(darktable.gui->reset) return; dt_iop_filmicrgb_gui_data_t *g = self->gui_data; @@ -4193,8 +4197,8 @@ static gboolean area_button_press(GtkWidget *widget, const GdkEventButton *event if(g->active_button != DT_FILMIC_GUI_BUTTON_LAST) { - - if(event->button == GDK_BUTTON_PRIMARY && event->type == GDK_2BUTTON_PRESS) + guint button = gtk_gesture_single_get_current_button(gesture); + if(button == GDK_BUTTON_PRIMARY && n_press == 2) { // double click resets view if(g->active_button == DT_FILMIC_GUI_BUTTON_TYPE) @@ -4202,14 +4206,9 @@ static gboolean area_button_press(GtkWidget *widget, const GdkEventButton *event g->gui_mode = DT_FILMIC_GUI_LOOK; gtk_widget_queue_draw(GTK_WIDGET(g->area)); dt_conf_set_int("plugins/darkroom/filmicrgb/graph_view", g->gui_mode); - return TRUE; - } - else - { - return FALSE; } } - else if(event->button == GDK_BUTTON_PRIMARY) + else if(button == GDK_BUTTON_PRIMARY) { // simple left click cycles through modes in positive direction if(g->active_button == DT_FILMIC_GUI_BUTTON_TYPE) @@ -4222,24 +4221,17 @@ static gboolean area_button_press(GtkWidget *widget, const GdkEventButton *event gtk_widget_queue_draw(GTK_WIDGET(g->area)); dt_conf_set_int("plugins/darkroom/filmicrgb/graph_view", g->gui_mode); - return TRUE; } else if(g->active_button == DT_FILMIC_GUI_BUTTON_LABELS) { g->gui_show_labels = !g->gui_show_labels; gtk_widget_queue_draw(GTK_WIDGET(g->area)); dt_conf_set_int("plugins/darkroom/filmicrgb/graph_show_labels", g->gui_show_labels); - return TRUE; - } - else - { - // we should never get there since (g->active_button != DT_FILMIC_GUI_BUTTON_LAST) - // and any other case has been processed above. - return FALSE; } } - else if(event->button == GDK_BUTTON_SECONDARY) + else if(button == GDK_BUTTON_SECONDARY) { + dt_gui_claim(gesture); // simple right click cycles through modes in negative direction if(g->active_button == DT_FILMIC_GUI_BUTTON_TYPE) { @@ -4250,44 +4242,44 @@ static gboolean area_button_press(GtkWidget *widget, const GdkEventButton *event gtk_widget_queue_draw(GTK_WIDGET(g->area)); dt_conf_set_int("plugins/darkroom/filmicrgb/graph_view", g->gui_mode); - return TRUE; } else if(g->active_button == DT_FILMIC_GUI_BUTTON_LABELS) { g->gui_show_labels = !g->gui_show_labels; gtk_widget_queue_draw(GTK_WIDGET(g->area)); dt_conf_set_int("plugins/darkroom/filmicrgb/graph_show_labels", g->gui_show_labels); - return TRUE; - } - else - { - return FALSE; } } } - - return FALSE; } -static gboolean area_enter_leave_notify(GtkWidget *widget, const GdkEventCrossing *event, const dt_iop_module_t *self) +static void _filmicrgb_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { dt_iop_filmicrgb_gui_data_t *g = self->gui_data; - g->gui_hover = event->type == GDK_ENTER_NOTIFY; + g->gui_hover = controller == NULL; gtk_widget_queue_draw(GTK_WIDGET(g->area)); - return FALSE; } -static gboolean area_motion_notify(GtkWidget *widget, const GdkEventMotion *event, const dt_iop_module_t *self) +static void _filmicrgb_enter(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) +{ + _filmicrgb_leave(NULL, self); +} + +static void _filmicrgb_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { - if(darktable.gui->reset) return 1; + if(darktable.gui->reset) return; dt_iop_filmicrgb_gui_data_t *g = self->gui_data; - if(!g->gui_sizes_inited) return FALSE; + if(!g->gui_sizes_inited) return; // get in-widget coordinates - const float y = event->y; - const float x = event->x; - if(x > 0. && x < g->allocation.width && y > 0. && y < g->allocation.height) g->gui_hover = TRUE; const gint save_active_button = g->active_button; @@ -4340,13 +4332,11 @@ static gboolean area_motion_notify(GtkWidget *widget, const GdkEventMotion *even } if(save_active_button != g->active_button) gtk_widget_queue_draw(GTK_WIDGET(g->area)); - return TRUE; } else { g->active_button = DT_FILMIC_GUI_BUTTON_LAST; if(save_active_button != g->active_button) (GTK_WIDGET(g->area)); - return FALSE; } } @@ -4368,10 +4358,8 @@ void gui_init(dt_iop_module_t *self) gtk_widget_set_can_focus(GTK_WIDGET(g->area), TRUE); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(dt_iop_tonecurve_draw), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(area_button_press), self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(area_enter_leave_notify), self); - g_signal_connect(G_OBJECT(g->area), "enter-notify-event", G_CALLBACK(area_enter_leave_notify), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(area_motion_notify), self); + dt_gui_connect_click_all(g->area, _filmicrgb_button_press, NULL, self); + dt_gui_connect_motion(g->area, _filmicrgb_motion, _filmicrgb_enter, _filmicrgb_leave, self); // Init GTK notebook static struct dt_action_def_t notebook_def = { }; diff --git a/src/iop/levels.c b/src/iop/levels.c index e13f41cb0599..07d74ffa2bc8 100644 --- a/src/iop/levels.c +++ b/src/iop/levels.c @@ -46,10 +46,22 @@ DT_MODULE_INTROSPECTION(2, dt_iop_levels_params_t) static gboolean dt_iop_levels_area_draw(GtkWidget *widget, cairo_t *crf, dt_iop_module_t *self); -static gboolean dt_iop_levels_motion_notify(GtkWidget *widget, GdkEventMotion *event, dt_iop_module_t *self); -static gboolean dt_iop_levels_button_press(GtkWidget *widget, GdkEventButton *event, dt_iop_module_t *self); -static gboolean dt_iop_levels_button_release(GtkWidget *widget, GdkEventButton *event, dt_iop_module_t *self); -static gboolean dt_iop_levels_leave_notify(GtkWidget *widget, GdkEventCrossing *event, dt_iop_module_t *self); +static void _levels_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self); +static void _levels_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self); +static void _levels_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self); +static void _levels_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self); static gboolean dt_iop_levels_scroll(GtkWidget *widget, GdkEventScroll *event, dt_iop_module_t *self); static void dt_iop_levels_autoadjust_callback(GtkRange *range, dt_iop_module_t *self); //static void dt_iop_levels_mode_callback(GtkWidget *combo, gpointer user_data); @@ -636,10 +648,8 @@ void gui_init(dt_iop_module_t *self) dt_action_define_iop(self, NULL, N_("levels"), GTK_WIDGET(g->area), NULL); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(dt_iop_levels_area_draw), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(dt_iop_levels_button_press), self); - g_signal_connect(G_OBJECT(g->area), "button-release-event", G_CALLBACK(dt_iop_levels_button_release), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(dt_iop_levels_motion_notify), self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(dt_iop_levels_leave_notify), self); + dt_gui_connect_click(g->area, _levels_button_press, _levels_button_release, self); + dt_gui_connect_motion(g->area, _levels_motion, NULL, _levels_leave, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(dt_iop_levels_scroll), self); GtkWidget *autobutton = gtk_button_new_with_label(_("auto")); @@ -696,12 +706,12 @@ void gui_cleanup(dt_iop_module_t *self) g_list_free(g->modes); } -static gboolean dt_iop_levels_leave_notify(GtkWidget *widget, GdkEventCrossing *event, dt_iop_module_t *self) +static void _levels_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { dt_iop_levels_gui_data_t *g = self->gui_data; g->mouse_x = g->mouse_y = -1.0; - gtk_widget_queue_draw(widget); - return TRUE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } static gboolean dt_iop_levels_area_draw(GtkWidget *widget, cairo_t *crf, dt_iop_module_t *self) @@ -862,26 +872,29 @@ static void dt_iop_levels_move_handle(dt_iop_module_t *self, int handle_move, fl g->last_picked_color = -1; } -static gboolean dt_iop_levels_motion_notify(GtkWidget *widget, GdkEventMotion *event, dt_iop_module_t *self) +static void _levels_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_levels_gui_data_t *g = self->gui_data; dt_iop_levels_params_t *p = self->params; const int inset = DT_GUI_CURVE_EDITOR_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); int height = allocation.height - 2 * inset - DT_RESIZE_HANDLE_SIZE, width = allocation.width - 2 * inset; if(!g->dragging) { - g->mouse_x = CLAMP(event->x - inset, 0, width); + g->mouse_x = CLAMP(x - inset, 0, width); g->drag_start_percentage = (p->levels[1] - p->levels[0]) / (p->levels[2] - p->levels[0]); } - g->mouse_y = CLAMP(event->y - inset, 0, height); + g->mouse_y = CLAMP(y - inset, 0, height); if(g->dragging) { if(g->handle_move >= 0 && g->handle_move < 3) { - const float mx = (CLAMP(event->x - inset, 0, width)) / (float)width; + const float mx = (CLAMP(x - inset, 0, width)) / (float)width; dt_iop_levels_move_handle(self, g->handle_move, mx, p->levels, g->drag_start_percentage); } @@ -890,7 +903,7 @@ static gboolean dt_iop_levels_motion_notify(GtkWidget *widget, GdkEventMotion *e else { g->handle_move = 0; - const float mx = CLAMP(event->x - inset, 0, width) / (float)width; + const float mx = CLAMP(x - inset, 0, width) / (float)width; float dist = fabsf(p->levels[0] - mx); for(int k = 1; k < 3; k++) { @@ -902,49 +915,45 @@ static gboolean dt_iop_levels_motion_notify(GtkWidget *widget, GdkEventMotion *e } } } - gtk_widget_queue_draw(widget); - - return TRUE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } -static gboolean dt_iop_levels_button_press(GtkWidget *widget, GdkEventButton *event, dt_iop_module_t *self) +static void _levels_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { // set active point - if(event->button == GDK_BUTTON_PRIMARY) - { - if(darktable.develop->gui_module != self) dt_iop_request_focus(self); + if(darktable.develop->gui_module != self) dt_iop_request_focus(self); - if(event->type == GDK_2BUTTON_PRESS) - { - // Reset - dt_iop_levels_gui_data_t *g = self->gui_data; - memcpy(self->params, self->default_params, self->params_size); + if(n_press == 2) + { + // Reset + dt_iop_levels_gui_data_t *g = self->gui_data; + memcpy(self->params, self->default_params, self->params_size); - // Needed in case the user scrolls or drags immediately after a reset, - // as drag_start_percentage is only updated when the mouse is moved. - g->drag_start_percentage = 0.5; - dt_dev_add_history_item(darktable.develop, self, TRUE); - gtk_widget_queue_draw(GTK_WIDGET(g->area)); - } - else - { - dt_iop_levels_gui_data_t *g = self->gui_data; - g->dragging = 1; - } - return TRUE; + // Needed in case the user scrolls or drags immediately after a reset, + // as drag_start_percentage is only updated when the mouse is moved. + g->drag_start_percentage = 0.5; + dt_dev_add_history_item(darktable.develop, self, TRUE); + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } - return FALSE; -} - -static gboolean dt_iop_levels_button_release(GtkWidget *widget, GdkEventButton *event, dt_iop_module_t *self) -{ - if(event->button == GDK_BUTTON_PRIMARY) + else { dt_iop_levels_gui_data_t *g = self->gui_data; - g->dragging = 0; - return TRUE; + g->dragging = 1; } - return FALSE; +} + +static void _levels_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) +{ + dt_iop_levels_gui_data_t *g = self->gui_data; + g->dragging = 0; } static gboolean dt_iop_levels_scroll(GtkWidget *widget, GdkEventScroll *event, dt_iop_module_t *self) diff --git a/src/iop/lowlight.c b/src/iop/lowlight.c index 83b747858d4d..e38db4a6a05e 100644 --- a/src/iop/lowlight.c +++ b/src/iop/lowlight.c @@ -663,22 +663,25 @@ static gboolean lowlight_draw(GtkWidget *widget, cairo_t *crf, dt_iop_module_t * return FALSE; } -static gboolean lowlight_motion_notify(GtkWidget *widget, GdkEventMotion *event, dt_iop_module_t *self) +static void _lowlight_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_lowlight_gui_data_t *g = self->gui_data; dt_iop_lowlight_params_t *p = self->params; const int inset = DT_IOP_LOWLIGHT_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); int height = allocation.height - 2 * inset - DT_RESIZE_HANDLE_SIZE, width = allocation.width - 2 * inset; - if(!g->dragging) g->mouse_x = CLAMP(event->x - inset, 0, width) / (float)width; - g->mouse_y = 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + if(!g->dragging) g->mouse_x = CLAMP(x - inset, 0, width) / (float)width; + g->mouse_y = 1.0 - CLAMP(y - inset, 0, height) / (float)height; if(g->dragging) { *p = g->drag_params; if(g->x_move >= 0) { - const float mx = CLAMP(event->x - inset, 0, width) / (float)width; + const float mx = CLAMP(x - inset, 0, width) / (float)width; if(g->x_move > 0 && g->x_move < DT_IOP_LOWLIGHT_BANDS - 1) { const float minx = p->transition_x[g->x_move - 1] + 0.001f; @@ -690,10 +693,9 @@ static gboolean lowlight_motion_notify(GtkWidget *widget, GdkEventMotion *event, { dt_iop_lowlight_get_params(p, g->mouse_x, g->mouse_y + g->mouse_pick, g->mouse_radius); } - gtk_widget_queue_draw(widget); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area); } - else if(event->y > height) + else if(y > height) { g->x_move = 0; float dist = fabs(p->transition_x[0] - g->mouse_x); @@ -706,20 +708,22 @@ static gboolean lowlight_motion_notify(GtkWidget *widget, GdkEventMotion *event, dist = d2; } } - gtk_widget_queue_draw(widget); } else { g->x_move = -1; - gtk_widget_queue_draw(widget); } - return TRUE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } -static gboolean lowlight_button_press(GtkWidget *widget, GdkEventButton *event, dt_iop_module_t *self) +static void _lowlight_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { dt_iop_lowlight_gui_data_t *g = self->gui_data; - if(event->button == GDK_BUTTON_PRIMARY && event->type == GDK_2BUTTON_PRESS) + if(n_press == 2) { // reset current curve dt_iop_lowlight_params_t *p = self->params; @@ -729,42 +733,39 @@ static gboolean lowlight_button_press(GtkWidget *widget, GdkEventButton *event, p->transition_x[k] = d->transition_x[k]; p->transition_y[k] = d->transition_y[k]; } - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area); gtk_widget_queue_draw(GTK_WIDGET(g->area)); } - else if(event->button == GDK_BUTTON_PRIMARY) + else { g->drag_params = *(dt_iop_lowlight_params_t *)self->params; const int inset = DT_IOP_LOWLIGHT_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); int height = allocation.height - 2 * inset - DT_RESIZE_HANDLE_SIZE, width = allocation.width - 2 * inset; g->mouse_pick - = dt_draw_curve_calc_value(g->transition_curve, CLAMP(event->x - inset, 0, width) / (float)width); - g->mouse_pick -= 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + = dt_draw_curve_calc_value(g->transition_curve, CLAMP(x - inset, 0, width) / (float)width); + g->mouse_pick -= 1.0 - CLAMP(y - inset, 0, height) / (float)height; g->dragging = 1; - return TRUE; } - return FALSE; } -static gboolean lowlight_button_release(GtkWidget *widget, GdkEventButton *event, dt_iop_module_t *self) +static void _lowlight_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { - if(event->button == GDK_BUTTON_PRIMARY) - { - dt_iop_lowlight_gui_data_t *g = self->gui_data; - g->dragging = 0; - return TRUE; - } - return FALSE; + dt_iop_lowlight_gui_data_t *g = self->gui_data; + g->dragging = 0; } -static gboolean lowlight_leave_notify(GtkWidget *widget, GdkEventCrossing *event, dt_iop_module_t *self) +static void _lowlight_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { dt_iop_lowlight_gui_data_t *g = self->gui_data; if(!g->dragging) g->mouse_y = -1.0; - gtk_widget_queue_draw(widget); - return TRUE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } static gboolean lowlight_scrolled(GtkWidget *widget, GdkEventScroll *event, dt_iop_module_t *self) @@ -808,10 +809,8 @@ void gui_init(dt_iop_module_t *self) self->widget = dt_gui_vbox(g->area); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(lowlight_draw), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(lowlight_button_press), self); - g_signal_connect(G_OBJECT(g->area), "button-release-event", G_CALLBACK(lowlight_button_release), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(lowlight_motion_notify), self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(lowlight_leave_notify), self); + dt_gui_connect_click(g->area, _lowlight_button_press, _lowlight_button_release, self); + dt_gui_connect_motion(g->area, _lowlight_motion, NULL, _lowlight_leave, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(lowlight_scrolled), self); g->scale_blueness = dt_bauhaus_slider_from_params(self, "blueness"); diff --git a/src/iop/monochrome.c b/src/iop/monochrome.c index 4187e14efa91..2508ce72fffc 100644 --- a/src/iop/monochrome.c +++ b/src/iop/monochrome.c @@ -450,7 +450,10 @@ void color_picker_apply(dt_iop_module_t *self, GtkWidget *picker, dt_dev_pixelpi dt_control_queue_redraw_widget(self->widget); } -static gboolean _monochrome_motion_notify(GtkWidget *widget, GdkEventMotion *event, dt_iop_module_t *self) +static void _monochrome_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_monochrome_gui_data_t *g = self->gui_data; dt_iop_monochrome_params_t *p = self->params; @@ -459,73 +462,68 @@ static gboolean _monochrome_motion_notify(GtkWidget *widget, GdkEventMotion *eve const float old_a = p->a, old_b = p->b; const int inset = DT_COLORCORRECTION_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); int width = allocation.width - 2 * inset, height = allocation.height - 2 * inset; - const float mouse_x = CLAMP(event->x - inset, 0, width); - const float mouse_y = CLAMP(height - 1 - event->y + inset, 0, height); + const float mouse_x = CLAMP(x - inset, 0, width); + const float mouse_y = CLAMP(height - 1 - y + inset, 0, height); p->a = PANEL_WIDTH * (mouse_x - width * 0.5f) / (float)width; p->b = PANEL_WIDTH * (mouse_y - height * 0.5f) / (float)height; if(old_a != p->a || old_b != p->b) dt_dev_add_history_item(darktable.develop, self, TRUE); gtk_widget_queue_draw(GTK_WIDGET(g->area)); } - return TRUE; } -static gboolean _monochrome_button_press(GtkWidget *widget, GdkEventButton *event, dt_iop_module_t *self) +static void _monochrome_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { - if(event->button == GDK_BUTTON_PRIMARY) + dt_iop_monochrome_gui_data_t *g = self->gui_data; + dt_iop_monochrome_params_t *p = self->params; + dt_iop_color_picker_reset(self, TRUE); + if(n_press == 2) { - dt_iop_monochrome_gui_data_t *g = self->gui_data; - dt_iop_monochrome_params_t *p = self->params; - dt_iop_color_picker_reset(self, TRUE); - if(event->type == GDK_2BUTTON_PRESS) - { - // reset - const dt_iop_monochrome_params_t *const p0 = self->default_params; - p->a = p0->a; - p->b = p0->b; - p->size = p0->size; - } - else - { - const int inset = DT_COLORCORRECTION_INSET; - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - int width = allocation.width - 2 * inset, height = allocation.height - 2 * inset; - const float mouse_x = CLAMP(event->x - inset, 0, width); - const float mouse_y = CLAMP(height - 1 - event->y + inset, 0, height); - p->a = PANEL_WIDTH * (mouse_x - width * 0.5f) / (float)width; - p->b = PANEL_WIDTH * (mouse_y - height * 0.5f) / (float)height; - g->dragging = 1; - g_object_set(G_OBJECT(widget), "has-tooltip", FALSE, (gchar *)0); - } - gtk_widget_queue_draw(GTK_WIDGET(g->area)); - return TRUE; + // reset + const dt_iop_monochrome_params_t *const p0 = self->default_params; + p->a = p0->a; + p->b = p0->b; + p->size = p0->size; } - return FALSE; + else + { + const int inset = DT_COLORCORRECTION_INSET; + GtkAllocation allocation; + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); + int width = allocation.width - 2 * inset, height = allocation.height - 2 * inset; + const float mouse_x = CLAMP(x - inset, 0, width); + const float mouse_y = CLAMP(height - 1 - y + inset, 0, height); + p->a = PANEL_WIDTH * (mouse_x - width * 0.5f) / (float)width; + p->b = PANEL_WIDTH * (mouse_y - height * 0.5f) / (float)height; + g->dragging = 1; + } + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } -static gboolean _monochrome_button_release(GtkWidget *widget, GdkEventButton *event, dt_iop_module_t *self) +static void _monochrome_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { - if(event->button == GDK_BUTTON_PRIMARY) - { - dt_iop_monochrome_gui_data_t *g = self->gui_data; - dt_iop_color_picker_reset(self, TRUE); - g->dragging = 0; - dt_dev_add_history_item(darktable.develop, self, TRUE); - g_object_set(G_OBJECT(widget), "has-tooltip", TRUE, (gchar *)0); - return TRUE; - } - return FALSE; + dt_iop_monochrome_gui_data_t *g = self->gui_data; + dt_iop_color_picker_reset(self, TRUE); + g->dragging = 0; + dt_dev_add_history_item(darktable.develop, self, TRUE); } -static gboolean _monochrome_leave_notify(GtkWidget *widget, GdkEventCrossing *event, dt_iop_module_t *self) +static void _monochrome_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { dt_iop_monochrome_gui_data_t *g = self->gui_data; g->dragging = 0; gtk_widget_queue_draw(GTK_WIDGET(g->area)); - return TRUE; } static gboolean _monochrome_scrolled(GtkWidget *widget, GdkEventScroll *event, dt_iop_module_t *self) @@ -559,16 +557,10 @@ void gui_init(dt_iop_module_t *self) gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _("drag and scroll mouse wheel to adjust the virtual color filter")); dt_action_define_iop(self, NULL, N_("grid"), GTK_WIDGET(g->area), NULL); - gtk_widget_add_events(GTK_WIDGET(g->area), GDK_POINTER_MOTION_MASK - | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - | GDK_LEAVE_NOTIFY_MASK | darktable.gui->scroll_mask); + gtk_widget_add_events(GTK_WIDGET(g->area), darktable.gui->scroll_mask); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(_monochrome_draw), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(_monochrome_button_press), self); - g_signal_connect(G_OBJECT(g->area), "button-release-event", G_CALLBACK(_monochrome_button_release), - self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(_monochrome_motion_notify), - self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(_monochrome_leave_notify), self); + dt_gui_connect_click(g->area, _monochrome_button_press, _monochrome_button_release, self); + dt_gui_connect_motion(g->area, _monochrome_motion, NULL, _monochrome_leave, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(_monochrome_scrolled), self); g->highlights diff --git a/src/iop/rawdenoise.c b/src/iop/rawdenoise.c index 59779cb76276..0ab711d02f87 100644 --- a/src/iop/rawdenoise.c +++ b/src/iop/rawdenoise.c @@ -763,16 +763,19 @@ static gboolean rawdenoise_draw(GtkWidget *widget, cairo_t *crf, dt_iop_module_t return FALSE; } -static gboolean rawdenoise_motion_notify(GtkWidget *widget, GdkEventMotion *event, dt_iop_module_t *self) +static void _rawdenoise_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_rawdenoise_gui_data_t *g = self->gui_data; dt_iop_rawdenoise_params_t *p = self->params; const int inset = DT_IOP_RAWDENOISE_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset; - if(!g->dragging) g->mouse_x = CLAMP(event->x - inset, 0, width) / (float)width; - g->mouse_y = 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + if(!g->dragging) g->mouse_x = CLAMP(x - inset, 0, width) / (float)width; + g->mouse_y = 1.0 - CLAMP(y - inset, 0, height) / (float)height; if(g->dragging) { *p = g->drag_params; @@ -780,22 +783,24 @@ static gboolean rawdenoise_motion_notify(GtkWidget *widget, GdkEventMotion *even { dt_iop_rawdenoise_get_params(p, g->channel, g->mouse_x, g->mouse_y + g->mouse_pick, g->mouse_radius); } - gtk_widget_queue_draw(widget); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + g->channel); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + g->channel); } else { g->x_move = -1; - gtk_widget_queue_draw(widget); } - return TRUE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } -static gboolean rawdenoise_button_press(GtkWidget *widget, GdkEventButton *event, dt_iop_module_t *self) +static void _rawdenoise_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { dt_iop_rawdenoise_gui_data_t *g = self->gui_data; const int ch = g->channel; - if(event->button == GDK_BUTTON_PRIMARY && event->type == GDK_2BUTTON_PRESS) + if(n_press == 2) { // reset current curve dt_iop_rawdenoise_params_t *p = self->params; @@ -805,42 +810,39 @@ static gboolean rawdenoise_button_press(GtkWidget *widget, GdkEventButton *event p->x[ch][k] = d->x[ch][k]; p->y[ch][k] = d->y[ch][k]; } - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + ch); gtk_widget_queue_draw(GTK_WIDGET(g->area)); } - else if(event->button == GDK_BUTTON_PRIMARY) + else { g->drag_params = *(dt_iop_rawdenoise_params_t *)self->params; const int inset = DT_IOP_RAWDENOISE_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset; g->mouse_pick - = dt_draw_curve_calc_value(g->transition_curve, CLAMP(event->x - inset, 0, width) / (float)width); - g->mouse_pick -= 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + = dt_draw_curve_calc_value(g->transition_curve, CLAMP(x - inset, 0, width) / (float)width); + g->mouse_pick -= 1.0 - CLAMP(y - inset, 0, height) / (float)height; g->dragging = 1; - return TRUE; } - return FALSE; } -static gboolean rawdenoise_button_release(GtkWidget *widget, GdkEventButton *event, dt_iop_module_t *self) +static void _rawdenoise_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { - if(event->button == GDK_BUTTON_PRIMARY) - { - dt_iop_rawdenoise_gui_data_t *g = self->gui_data; - g->dragging = 0; - return TRUE; - } - return FALSE; + dt_iop_rawdenoise_gui_data_t *g = self->gui_data; + g->dragging = 0; } -static gboolean rawdenoise_leave_notify(GtkWidget *widget, GdkEventCrossing *event, dt_iop_module_t *self) +static void _rawdenoise_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { dt_iop_rawdenoise_gui_data_t *g = self->gui_data; if(!g->dragging) g->mouse_y = -1.0; - gtk_widget_queue_draw(widget); - return TRUE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } static gboolean rawdenoise_scrolled(GtkWidget *widget, GdkEventScroll *event, dt_iop_module_t *self) @@ -910,10 +912,8 @@ void gui_init(dt_iop_module_t *self) GtkWidget *box_raw = self->widget = dt_gui_vbox(g->channel_tabs, g->area); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(rawdenoise_draw), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(rawdenoise_button_press), self); - g_signal_connect(G_OBJECT(g->area), "button-release-event", G_CALLBACK(rawdenoise_button_release), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(rawdenoise_motion_notify), self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(rawdenoise_leave_notify), self); + dt_gui_connect_click(g->area, _rawdenoise_button_press, _rawdenoise_button_release, self); + dt_gui_connect_motion(g->area, _rawdenoise_motion, NULL, _rawdenoise_leave, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(rawdenoise_scrolled), self); g->threshold = dt_bauhaus_slider_from_params(self, "threshold"); diff --git a/src/iop/rgbcurve.c b/src/iop/rgbcurve.c index a976f5fec56a..8f1aa24bca93 100644 --- a/src/iop/rgbcurve.c +++ b/src/iop/rgbcurve.c @@ -745,16 +745,15 @@ static gboolean _area_key_press_callback(GtkWidget *widget, #undef RGBCURVE_DEFAULT_STEP -static gboolean _area_leave_notify_callback(GtkWidget *widget, - GdkEventCrossing *event, - dt_iop_module_t *self) +static void _rgbcurve_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { dt_iop_rgbcurve_gui_data_t *g = self->gui_data; + GdkEventCrossing *event = (GdkEventCrossing *)gtk_get_current_event(); if(!(event->state & GDK_BUTTON1_MASK)) g->selected = -1; - gtk_widget_queue_draw(widget); - return FALSE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } static gboolean _area_draw_callback(GtkWidget *widget, @@ -1165,28 +1164,29 @@ static gboolean _area_draw_callback(GtkWidget *widget, return TRUE; } -static gboolean _area_motion_notify_callback(GtkWidget *widget, - GdkEventMotion *event, - dt_iop_module_t *self) +static void _rgbcurve_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_rgbcurve_gui_data_t *g = self->gui_data; dt_iop_rgbcurve_params_t *p = self->params; const int inset = DT_GUI_CURVE_EDITOR_INSET; + GtkAllocation allocation; + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); + const int height = allocation.height - 2 * inset; + const int width = allocation.width - 2 * inset; + GdkEventMotion *event = (GdkEventMotion *)gtk_get_current_event(); // drag the draw area if(darktable.develop->darkroom_skip_mouse_events) { - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - const int height = allocation.height - 2 * inset; - const int width = allocation.width - 2 * inset; - const float mx = g->mouse_x; const float my = g->mouse_y; - g->mouse_x = CLAMP(event->x - inset, 0, width) / (float)width; - g->mouse_y = 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + g->mouse_x = CLAMP(x - inset, 0, width) / (float)width; + g->mouse_y = 1.0 - CLAMP(y - inset, 0, height) / (float)height; if(event->state & GDK_BUTTON1_MASK) { @@ -1198,7 +1198,7 @@ static gboolean _area_motion_notify_callback(GtkWidget *widget, gtk_widget_queue_draw(GTK_WIDGET(g->area)); } - return TRUE; + return; } const int ch = g->channel; @@ -1210,15 +1210,11 @@ static gboolean _area_motion_notify_callback(GtkWidget *widget, && g->channel != DT_IOP_RGBCURVE_R) goto finally; - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - const int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset; - const double old_m_x = g->mouse_x; const double old_m_y = g->mouse_y; - g->mouse_x = CLAMP(event->x - inset, 0, width) / (float)width; - g->mouse_y = 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + g->mouse_x = CLAMP(x - inset, 0, width) / (float)width; + g->mouse_y = 1.0 - CLAMP(y - inset, 0, height) / (float)height; const float mx = g->mouse_x; const float my = g->mouse_y; @@ -1249,14 +1245,15 @@ static gboolean _area_motion_notify_callback(GtkWidget *widget, g->zoom_factor, g->offset_y); dt_iop_color_picker_reset(self, TRUE); - return _move_point_internal(self, widget, dx, dy, event->state); + _move_point_internal(self, GTK_WIDGET(g->area), dx, dy, event->state); + return; } else if(nodes < DT_IOP_RGBCURVE_MAXNODES && g->selected >= -1) { dt_iop_color_picker_reset(self, TRUE); // no vertex was close, create a new one! g->selected = _add_node(curve_nodes, &p->curve_num_nodes[ch], linx, liny); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + ch); } } else @@ -1283,43 +1280,45 @@ static gboolean _area_motion_notify_callback(GtkWidget *widget, g->selected = nearest; } finally: - if(g->selected >= 0) gtk_widget_grab_focus(widget); - gtk_widget_queue_draw(widget); - return TRUE; + if(g->selected >= 0) gtk_widget_grab_focus(GTK_WIDGET(g->area)); + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } -static gboolean _area_button_press_callback(GtkWidget *widget, - GdkEventButton *event, - dt_iop_module_t *self) +static void _rgbcurve_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { dt_iop_rgbcurve_params_t *p = self->params; const dt_iop_rgbcurve_params_t *const d = self->default_params; dt_iop_rgbcurve_gui_data_t *g = self->gui_data; - if(darktable.develop->darkroom_skip_mouse_events) - return TRUE; + if(darktable.develop->darkroom_skip_mouse_events) return; const int ch = g->channel; const int autoscale = p->curve_autoscale; const int nodes = p->curve_num_nodes[ch]; dt_iop_rgbcurve_node_t *curve_nodes = p->curve_nodes[ch]; - if(event->button == GDK_BUTTON_PRIMARY) + guint button = gtk_gesture_single_get_current_button(gesture); + if(button == GDK_BUTTON_PRIMARY) { - if(event->type == GDK_BUTTON_PRESS - && dt_modifier_is(event->state, GDK_CONTROL_MASK) + dt_gui_claim(gesture); + if(n_press == 1 + && dt_modifier_eq(gesture, GDK_CONTROL_MASK) && nodes < DT_IOP_RGBCURVE_MAXNODES && g->selected == -1) { // if we are not on a node -> add a new node at the current x of // the pointer and y of the curve at that x const int inset = DT_GUI_CURVE_EDITOR_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); const int width = allocation.width - 2 * inset; const int height = allocation.height - 2 * inset; - g->mouse_x = CLAMP(event->x - inset, 0, width) / (float)width; - g->mouse_y = 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; + g->mouse_x = CLAMP(x - inset, 0, width) / (float)width; + g->mouse_y = 1.0 - CLAMP(y - inset, 0, height) / (float)height; const float mx = g->mouse_x; const float linx = _mouse_to_curve(mx, g->zoom_factor, g->offset_x); @@ -1342,34 +1341,32 @@ static gboolean _area_button_press_callback(GtkWidget *widget, } if(selected == -1) selected = nodes; - // evaluate the curve at the current x position - const float y = dt_draw_curve_calc_value(g->minmax_curve[ch], linx); + // evaluate the curve at the current x position + const float calc_y = dt_draw_curve_calc_value(g->minmax_curve[ch], linx); - if(y >= 0.0f && y <= 1.0f) // never add something outside the - // viewport, you couldn't change it - // afterwards - { - // create a new node - selected = _add_node(curve_nodes, &p->curve_num_nodes[ch], linx, y); - - // maybe set the new one as being selected - const float min = .04f * .04f; // comparing against square - for(int k = 0; k < nodes; k++) - { - const float other_y = - _curve_to_mouse(curve_nodes[k].y, g->zoom_factor, g->offset_y); - const float dist = (y - other_y) * (y - other_y); - if(dist < min) g->selected = selected; - } + if(calc_y >= 0.0f && calc_y <= 1.0f) // never add something outside the + // viewport, you couldn't change it + // afterwards + { + // create a new node + selected = _add_node(curve_nodes, &p->curve_num_nodes[ch], linx, calc_y); - dt_iop_color_picker_reset(self, TRUE); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); - gtk_widget_queue_draw(GTK_WIDGET(g->area)); + // maybe set the new one as being selected + const float min = .04f * .04f; // comparing against square + for(int k = 0; k < nodes; k++) + { + const float other_y = + _curve_to_mouse(curve_nodes[k].y, g->zoom_factor, g->offset_y); + const float dist = (calc_y - other_y) * (calc_y - other_y); + if(dist < min) g->selected = selected; } - return TRUE; + dt_iop_color_picker_reset(self, TRUE); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + ch); + gtk_widget_queue_draw(GTK_WIDGET(g->area)); + } } - else if(event->type == GDK_2BUTTON_PRESS) + else if(n_press == 2) { // reset current curve // if autoscale is on: allow only reset of L curve @@ -1385,7 +1382,7 @@ static gboolean _area_button_press_callback(GtkWidget *widget, g->selected = -2; // avoid motion notify re-inserting immediately. dt_bauhaus_combobox_set(g->interpolator, p->curve_type[DT_IOP_RGBCURVE_R]); dt_iop_color_picker_reset(self, TRUE); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + ch); gtk_widget_queue_draw(GTK_WIDGET(g->area)); } else @@ -1396,23 +1393,23 @@ static gboolean _area_button_press_callback(GtkWidget *widget, g->selected = -2; // avoid motion notify re-inserting immediately. dt_bauhaus_combobox_set(g->autoscale, 1); dt_iop_color_picker_reset(self, TRUE); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + ch); gtk_widget_queue_draw(GTK_WIDGET(g->area)); } } - return TRUE; } } - else if(event->button == GDK_BUTTON_SECONDARY && g->selected >= 0) + else if(button == GDK_BUTTON_SECONDARY && g->selected >= 0) { + dt_gui_claim(gesture); if(g->selected == 0 || g->selected == nodes - 1) { const float reset_value = g->selected == 0 ? 0.f : 1.f; curve_nodes[g->selected].y = curve_nodes[g->selected].x = reset_value; dt_iop_color_picker_reset(self, TRUE); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + ch); gtk_widget_queue_draw(GTK_WIDGET(g->area)); - return TRUE; + return; } for(int k = g->selected; k < nodes - 1; k++) @@ -1424,11 +1421,9 @@ static gboolean _area_button_press_callback(GtkWidget *widget, g->selected = -2; // avoid re-insertion of that point immediately after this p->curve_num_nodes[ch]--; dt_iop_color_picker_reset(self, TRUE); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + ch); gtk_widget_queue_draw(GTK_WIDGET(g->area)); - return TRUE; } - return FALSE; } void gui_reset(dt_iop_module_t *self) @@ -1527,19 +1522,12 @@ void gui_init(dt_iop_module_t *self) // gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _("double click // to reset curve")); - gtk_widget_add_events(GTK_WIDGET(g->area), - GDK_POINTER_MOTION_MASK | darktable.gui->scroll_mask - | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); + gtk_widget_add_events(GTK_WIDGET(g->area), darktable.gui->scroll_mask); gtk_widget_set_can_focus(GTK_WIDGET(g->area), TRUE); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(_area_draw_callback), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", - G_CALLBACK(_area_button_press_callback), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", - G_CALLBACK(_area_motion_notify_callback), self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", - G_CALLBACK(_area_leave_notify_callback), self); + dt_gui_connect_click_all(g->area, _rgbcurve_button_press, NULL, self); + dt_gui_connect_motion(g->area, _rgbcurve_motion, NULL, _rgbcurve_leave, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(_area_scrolled_callback), self); g_signal_connect(G_OBJECT(g->area), "key-press-event", diff --git a/src/iop/rgblevels.c b/src/iop/rgblevels.c index 9f4f2263a030..a123ff54e92f 100644 --- a/src/iop/rgblevels.c +++ b/src/iop/rgblevels.c @@ -359,14 +359,12 @@ void gui_post_expose(dt_iop_module_t *self, cairo_stroke(cr); } -static gboolean _area_leave_notify_callback(GtkWidget *widget, - GdkEventCrossing *event, - dt_iop_module_t *self) +static void _rgblevels_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { dt_iop_rgblevels_gui_data_t *g = self->gui_data; g->mouse_x = g->mouse_y = -1.0; - gtk_widget_queue_draw(widget); - return TRUE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } static gboolean _area_draw_callback(GtkWidget *widget, @@ -548,28 +546,29 @@ static void _rgblevels_move_handle(dt_iop_module_t *self, gtk_widget_queue_draw(GTK_WIDGET(g->area)); } -static gboolean _area_motion_notify_callback(GtkWidget *widget, - GdkEventMotion *event, - dt_iop_module_t *self) +static void _rgblevels_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_rgblevels_gui_data_t *g = self->gui_data; dt_iop_rgblevels_params_t *p = self->params; const int inset = DT_GUI_CURVE_EDITOR_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); int height = allocation.height - 2 * inset - DT_RESIZE_HANDLE_SIZE, width = allocation.width - 2 * inset; if(!g->dragging) { - g->mouse_x = CLAMP(event->x - inset, 0, width); + g->mouse_x = CLAMP(x - inset, 0, width); g->drag_start_percentage = (p->levels[g->channel][1] - p->levels[g->channel][0]) / (p->levels[g->channel][2] - p->levels[g->channel][0]); } - g->mouse_y = CLAMP(event->y - inset, 0, height); + g->mouse_y = CLAMP(y - inset, 0, height); if(g->dragging) { if(g->handle_move >= 0 && g->handle_move < 3) { - const float mx = (CLAMP(event->x - inset, 0, width)) / (float)width; + const float mx = (CLAMP(x - inset, 0, width)) / (float)width; _rgblevels_move_handle(self, g->handle_move, mx, p->levels[g->channel], g->drag_start_percentage); } @@ -577,7 +576,7 @@ static gboolean _area_motion_notify_callback(GtkWidget *widget, else { g->handle_move = 0; - const float mx = CLAMP(event->x - inset, 0, width) / (float)width; + const float mx = CLAMP(x - inset, 0, width) / (float)width; float dist = fabsf(p->levels[g->channel][0] - mx); for(int k = 1; k < 3; k++) { @@ -591,62 +590,55 @@ static gboolean _area_motion_notify_callback(GtkWidget *widget, darktable.control->element = g->handle_move; - gtk_widget_queue_draw(widget); + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } - - return TRUE; } -static gboolean _area_button_press_callback(GtkWidget *widget, - GdkEventButton *event, - dt_iop_module_t *self) +static void _rgblevels_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { // set active point - if(event->button == GDK_BUTTON_PRIMARY) - { - if(darktable.develop->gui_module != self) dt_iop_request_focus(self); + if(darktable.develop->gui_module != self) dt_iop_request_focus(self); - if(event->type == GDK_2BUTTON_PRESS) - { - _turn_selregion_picker_off(self); + dt_gui_claim(gesture); + if(n_press == 2) + { + _turn_selregion_picker_off(self); - // Reset - dt_iop_rgblevels_gui_data_t *g = self->gui_data; - dt_iop_rgblevels_params_t *p = self->params; - const dt_iop_rgblevels_params_t *const default_params = self->default_params; + // Reset + dt_iop_rgblevels_gui_data_t *g = self->gui_data; + dt_iop_rgblevels_params_t *p = self->params; + const dt_iop_rgblevels_params_t *const default_params = self->default_params; - for(int i = 0; i < 3; i++) - p->levels[g->channel][i] = default_params->levels[g->channel][i]; + for(int i = 0; i < 3; i++) + p->levels[g->channel][i] = default_params->levels[g->channel][i]; - // Needed in case the user scrolls or drags immediately after a reset, - // as drag_start_percentage is only updated when the mouse is moved. - g->drag_start_percentage = 0.5; - dt_dev_add_history_item(darktable.develop, self, TRUE); - gtk_widget_queue_draw(GTK_WIDGET(g->area)); - } - else - { - _turn_selregion_picker_off(self); + // Needed in case the user scrolls or drags immediately after a reset, + // as drag_start_percentage is only updated when the mouse is moved. + g->drag_start_percentage = 0.5; + dt_dev_add_history_item(darktable.develop, self, TRUE); + gtk_widget_queue_draw(GTK_WIDGET(g->area)); + } + else + { + _turn_selregion_picker_off(self); - dt_iop_rgblevels_gui_data_t *g = self->gui_data; - g->dragging = 1; - } - return TRUE; + dt_iop_rgblevels_gui_data_t *g = self->gui_data; + g->dragging = 1; } - return FALSE; } -static gboolean _area_button_release_callback(GtkWidget *widget, - GdkEventButton *event, - dt_iop_module_t *self) +static void _rgblevels_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { - if(event->button == GDK_BUTTON_PRIMARY) - { - dt_iop_rgblevels_gui_data_t *g = self->gui_data; - g->dragging = 0; - return TRUE; - } - return FALSE; + dt_iop_rgblevels_gui_data_t *g = self->gui_data; + g->dragging = 0; } static gboolean _area_scroll_callback(GtkWidget *widget, @@ -1052,14 +1044,8 @@ void gui_init(dt_iop_module_t *self) "operates on L channel.")); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(_area_draw_callback), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", - G_CALLBACK(_area_button_press_callback), self); - g_signal_connect(G_OBJECT(g->area), "button-release-event", - G_CALLBACK(_area_button_release_callback), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", - G_CALLBACK(_area_motion_notify_callback), self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", - G_CALLBACK(_area_leave_notify_callback), self); + dt_gui_connect_click(g->area, _rgblevels_button_press, _rgblevels_button_release, self); + dt_gui_connect_motion(g->area, _rgblevels_motion, NULL, _rgblevels_leave, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(_area_scroll_callback), self); diff --git a/src/iop/tonecurve.c b/src/iop/tonecurve.c index 73b41414caab..3f40418237b0 100644 --- a/src/iop/tonecurve.c +++ b/src/iop/tonecurve.c @@ -50,15 +50,17 @@ DT_MODULE_INTROSPECTION(5, dt_iop_tonecurve_params_t) static gboolean dt_iop_tonecurve_draw(GtkWidget *widget, cairo_t *crf, dt_iop_module_t *self); -static gboolean dt_iop_tonecurve_motion_notify(GtkWidget *widget, - GdkEventMotion *event, - dt_iop_module_t *self); -static gboolean dt_iop_tonecurve_button_press(GtkWidget *widget, - GdkEventButton *event, - dt_iop_module_t *self); -static gboolean dt_iop_tonecurve_leave_notify(GtkWidget *widget, - GdkEventCrossing *event, - dt_iop_module_t *self); +static void _tonecurve_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self); +static void _tonecurve_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self); +static void _tonecurve_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self); static gboolean dt_iop_tonecurve_key_press(GtkWidget *widget, GdkEventKey *event, dt_iop_module_t *self); @@ -1290,17 +1292,11 @@ void gui_init(dt_iop_module_t *self) // FIXME: that tooltip goes in the way of the numbers when you hover a node to get a reading //gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _("double click to reset curve")); - gtk_widget_add_events(GTK_WIDGET(g->area), GDK_POINTER_MOTION_MASK | darktable.gui->scroll_mask - | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); + gtk_widget_add_events(GTK_WIDGET(g->area), darktable.gui->scroll_mask); gtk_widget_set_can_focus(GTK_WIDGET(g->area), TRUE); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(dt_iop_tonecurve_draw), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", - G_CALLBACK(dt_iop_tonecurve_button_press), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", - G_CALLBACK(dt_iop_tonecurve_motion_notify), self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", - G_CALLBACK(dt_iop_tonecurve_leave_notify), self); + dt_gui_connect_click_all(g->area, _tonecurve_button_press, NULL, self); + dt_gui_connect_motion(g->area, _tonecurve_motion, NULL, _tonecurve_leave, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(_scrolled), self); g_signal_connect(G_OBJECT(g->area), "key-press-event", @@ -1343,15 +1339,14 @@ void gui_cleanup(dt_iop_module_t *self) dt_draw_curve_destroy(g->minmax_curve[ch_b]); } -static gboolean dt_iop_tonecurve_leave_notify(GtkWidget *widget, - GdkEventCrossing *event, - dt_iop_module_t *self) +static void _tonecurve_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { dt_iop_tonecurve_gui_data_t *g = self->gui_data; + GdkEventMotion *event = (GdkEventMotion *)gtk_get_current_event(); if(!(event->state & GDK_BUTTON1_MASK)) g->selected = -1; - gtk_widget_queue_draw(widget); - return FALSE; + gtk_widget_queue_draw(GTK_WIDGET(g->area)); } static void picker_scale(const float *in, float *out) @@ -1751,12 +1746,14 @@ static inline int _add_node(dt_iop_tonecurve_node_t *tonecurve, return selected; } -static gboolean dt_iop_tonecurve_motion_notify(GtkWidget *widget, - GdkEventMotion *event, - dt_iop_module_t *self) +static void _tonecurve_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_tonecurve_gui_data_t *g = self->gui_data; dt_iop_tonecurve_params_t *p = self->params; + GtkWidget *widget = GTK_WIDGET(g->area); int ch = g->channel; int nodes = p->tonecurve_nodes[ch]; @@ -1772,14 +1769,15 @@ static gboolean dt_iop_tonecurve_motion_notify(GtkWidget *widget, int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset; double old_m_x = g->mouse_x; double old_m_y = g->mouse_y; - g->mouse_x = event->x - inset; - g->mouse_y = event->y - inset; + g->mouse_x = x - inset; + g->mouse_y = y - inset; const float mx = CLAMP(g->mouse_x, 0, width) / width; const float my = 1.0f - CLAMP(g->mouse_y, 0, height) / height; const float linx = to_lin(mx, g->loglogscale, ch, g->semilog, 0), liny = to_lin(my, g->loglogscale, ch, g->semilog, 1); + GdkEventMotion *event = (GdkEventMotion *)gtk_get_current_event(); if(event->state & GDK_BUTTON1_MASK) { // got a vertex selected: @@ -1794,7 +1792,8 @@ static gboolean dt_iop_tonecurve_motion_notify(GtkWidget *widget, - to_lin(old_m_x / width - translate_mouse_x, g->loglogscale, ch, g->semilog, 0); const float dy = to_lin(1 - g->mouse_y / height - translate_mouse_y, g->loglogscale, ch, g->semilog, 1) - to_lin(1 - old_m_y / height - translate_mouse_y, g->loglogscale, ch, g->semilog, 1); - return _move_point_internal(self, widget, dx, dy, event->state); + _move_point_internal(self, widget, dx, dy, event->state); + return; } else if(nodes < DT_IOP_TONECURVE_MAXNODES && g->selected >= -1) { @@ -1825,12 +1824,13 @@ static gboolean dt_iop_tonecurve_motion_notify(GtkWidget *widget, finally: if(g->selected >= 0) gtk_widget_grab_focus(widget); gtk_widget_queue_draw(widget); - return TRUE; } -static gboolean dt_iop_tonecurve_button_press(GtkWidget *widget, - GdkEventButton *event, - dt_iop_module_t *self) +static void _tonecurve_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { dt_iop_tonecurve_params_t *p = self->params; const dt_iop_tonecurve_params_t *const d = self->default_params; @@ -1841,10 +1841,12 @@ static gboolean dt_iop_tonecurve_button_press(GtkWidget *widget, int nodes = p->tonecurve_nodes[ch]; dt_iop_tonecurve_node_t *tonecurve = p->tonecurve[ch]; - if(event->button == GDK_BUTTON_PRIMARY) + guint button = gtk_gesture_single_get_current_button(gesture); + if(button == GDK_BUTTON_PRIMARY) { - if(event->type == GDK_BUTTON_PRESS - && dt_modifier_is(event->state, GDK_CONTROL_MASK) + dt_gui_claim(gesture); + if(n_press == 1 + && dt_modifier_eq(event->state, GDK_CONTROL_MASK) && nodes < DT_IOP_TONECURVE_MAXNODES && g->selected == -1) { @@ -1852,10 +1854,10 @@ static gboolean dt_iop_tonecurve_button_press(GtkWidget *widget, // the pointer and y of the curve at that x const int inset = DT_GUI_CURVE_EDITOR_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(GTK_WIDGET(g->area), &allocation); int width = allocation.width - 2 * inset; - g->mouse_x = event->x - inset; - g->mouse_y = event->y - inset; + g->mouse_x = x - inset; + g->mouse_y = y - inset; const float mx = CLAMP(g->mouse_x, 0, width) / (float)width; const float linx = to_lin(mx, g->loglogscale, ch, g->semilog, 0); @@ -1882,12 +1884,12 @@ static gboolean dt_iop_tonecurve_button_press(GtkWidget *widget, (selected < nodes && tonecurve[selected].x - linx <= 0.025))) { // evaluate the curve at the current x position - const float y = dt_draw_curve_calc_value(g->minmax_curve[ch], linx); + const float calc_y = dt_draw_curve_calc_value(g->minmax_curve[ch], linx); - if(y >= 0.0 && y <= 1.0) // never add something outside the viewport, you couldn't change it afterwards + if(calc_y >= 0.0 && calc_y <= 1.0) // never add something outside the viewport, you couldn't change it afterwards { // create a new node - selected = _add_node(tonecurve, &p->tonecurve_nodes[ch], linx, y); + selected = _add_node(tonecurve, &p->tonecurve_nodes[ch], linx, calc_y); // maybe set the new one as being selected float min = .04f; @@ -1895,17 +1897,16 @@ static gboolean dt_iop_tonecurve_button_press(GtkWidget *widget, for(int k = 0; k < nodes; k++) { float other_y = to_log(tonecurve[k].y, g->loglogscale, ch, g->semilog, 1); - float dist = (y - other_y) * (y - other_y); + float dist = (calc_y - other_y) * (calc_y - other_y); if(dist < min) g->selected = selected; } - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + ch); gtk_widget_queue_draw(GTK_WIDGET(g->area)); } } - return TRUE; } - else if(event->type == GDK_2BUTTON_PRESS) + else if(n_press == 2) { // reset current curve // if autoscale_ab is on: allow only reset of L curve @@ -1920,7 +1921,7 @@ static gboolean dt_iop_tonecurve_button_press(GtkWidget *widget, } g->selected = -2; // avoid motion notify re-inserting immediately. dt_bauhaus_combobox_set(g->interpolator, p->tonecurve_type[ch_L]); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + ch); gtk_widget_queue_draw(GTK_WIDGET(g->area)); } else @@ -1930,22 +1931,22 @@ static gboolean dt_iop_tonecurve_button_press(GtkWidget *widget, p->tonecurve_autoscale_ab = DT_S_SCALE_MANUAL; g->selected = -2; // avoid motion notify re-inserting immediately. dt_bauhaus_combobox_set(g->autoscale_ab, 1); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + ch); gtk_widget_queue_draw(GTK_WIDGET(g->area)); } } - return TRUE; } } - else if(event->button == GDK_BUTTON_SECONDARY && g->selected >= 0) + else if(button == GDK_BUTTON_SECONDARY && g->selected >= 0) { + dt_gui_claim(gesture); if(g->selected == 0 || g->selected == nodes - 1) { float reset_value = g->selected == 0 ? 0 : 1; tonecurve[g->selected].y = tonecurve[g->selected].x = reset_value; gtk_widget_queue_draw(GTK_WIDGET(g->area)); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); - return TRUE; + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + ch); + return; } for(int k = g->selected; k < nodes - 1; k++) @@ -1957,10 +1958,8 @@ static gboolean dt_iop_tonecurve_button_press(GtkWidget *widget, g->selected = -2; // avoid re-insertion of that point immediately after this p->tonecurve_nodes[ch]--; gtk_widget_queue_draw(GTK_WIDGET(g->area)); - dt_dev_add_history_item_target(darktable.develop, self, TRUE, widget + ch); - return TRUE; + dt_dev_add_history_item_target(darktable.develop, self, TRUE, g->area + ch); } - return FALSE; } // clang-format off diff --git a/src/iop/toneequal.c b/src/iop/toneequal.c index 81a29351fdf8..bc73da0e5570 100644 --- a/src/iop/toneequal.c +++ b/src/iop/toneequal.c @@ -2935,13 +2935,13 @@ static gboolean area_draw(GtkWidget *widget, return TRUE; } - -static gboolean area_enter_leave_notify(GtkWidget *widget, - const GdkEventCrossing *event, - dt_iop_module_t *self) +static void _toneequal_enter(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { - if(darktable.gui->reset) return TRUE; - if(!self->enabled) return FALSE; + if(darktable.gui->reset) return; + if(!self->enabled) return; dt_iop_toneequalizer_gui_data_t *g = self->gui_data; @@ -2955,8 +2955,8 @@ static gboolean area_enter_leave_notify(GtkWidget *widget, dt_dev_add_history_item(darktable.develop, self, FALSE); } dt_iop_gui_enter_critical_section(self); - g->area_x = (event->x - g->inset); - g->area_y = (event->y - g->inset); + g->area_x = (x - g->inset); + g->area_y = (y - g->inset); g->area_dragging = FALSE; g->area_active_node = -1; g->area_cursor_valid = (g->area_x > 0.0f @@ -2966,22 +2966,21 @@ static gboolean area_enter_leave_notify(GtkWidget *widget, dt_iop_gui_leave_critical_section(self); gtk_widget_queue_draw(GTK_WIDGET(g->area)); - return FALSE; } - -static gboolean area_button_press(GtkWidget *widget, - const GdkEventButton *event, - dt_iop_module_t *self) +static void _toneequal_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { - - if(darktable.gui->reset) return TRUE; + if(darktable.gui->reset) return; dt_iop_toneequalizer_gui_data_t *g = self->gui_data; dt_iop_request_focus(self); - if(event->button == GDK_BUTTON_PRIMARY && event->type == GDK_2BUTTON_PRESS) + if(n_press == 2) { dt_iop_toneequalizer_params_t *p = self->params; const dt_iop_toneequalizer_params_t *const d = self->default_params; @@ -3003,9 +3002,8 @@ static gboolean area_button_press(GtkWidget *widget, // Redraw graph gtk_widget_queue_draw(GTK_WIDGET(g->area)); dt_dev_add_history_item(darktable.develop, self, TRUE); - return TRUE; } - else if(event->button == GDK_BUTTON_PRIMARY) + else { if(self->enabled) { @@ -3016,22 +3014,19 @@ static gboolean area_button_press(GtkWidget *widget, { dt_dev_add_history_item(darktable.develop, self, TRUE); } - return TRUE; } // Unlock the colour picker so we can display our own custom cursor dt_iop_color_picker_reset(self, TRUE); - - return FALSE; } - -static gboolean area_motion_notify(GtkWidget *widget, - const GdkEventMotion *event, - dt_iop_module_t *self) +static void _toneequal_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { - if(darktable.gui->reset) return TRUE; - if(!self->enabled) return FALSE; + if(darktable.gui->reset) return; + if(!self->enabled) return; dt_iop_toneequalizer_gui_data_t *g = self->gui_data; dt_iop_toneequalizer_params_t *p = self->params; @@ -3041,7 +3036,7 @@ static gboolean area_motion_notify(GtkWidget *widget, // vertical distance travelled since button_pressed event dt_iop_gui_enter_critical_section(self); // graph spans over 4 EV - const float offset = (-event->y + g->area_y) / g->graph_height * 4.0f; + const float offset = (-y + g->area_y) / g->graph_height * 4.0f; const float cursor_exposure = g->area_x / g->graph_width * 8.0f - 8.0f; // Get the desired correction on exposure channels @@ -3051,8 +3046,8 @@ static gboolean area_motion_notify(GtkWidget *widget, } dt_iop_gui_enter_critical_section(self); - g->area_x = event->x - g->inset; - g->area_y = event->y; + g->area_x = x - g->inset; + g->area_y = y; g->area_cursor_valid = (g->area_x > 0.0f && g->area_x < g->graph_width && g->area_y > 0.0f @@ -3076,23 +3071,25 @@ static gboolean area_motion_notify(GtkWidget *widget, dt_iop_gui_leave_critical_section(self); gtk_widget_queue_draw(GTK_WIDGET(g->area)); - return TRUE; } -static gboolean area_button_release(GtkWidget *widget, - const GdkEventButton *event, - dt_iop_module_t *self) +static void _toneequal_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { - if(darktable.gui->reset) return TRUE; - if(!self->enabled) return FALSE; + if(darktable.gui->reset) return; + if(!self->enabled) return; dt_iop_toneequalizer_gui_data_t *g = self->gui_data; // Give focus to module dt_iop_request_focus(self); - if(event->button == GDK_BUTTON_PRIMARY) + guint button = gtk_gesture_single_get_current_button(gesture); + if(button == GDK_BUTTON_PRIMARY) { const dt_iop_toneequalizer_params_t *p = self->params; @@ -3106,11 +3103,9 @@ static gboolean area_button_release(GtkWidget *widget, dt_iop_gui_enter_critical_section(self); g->area_dragging = FALSE; dt_iop_gui_leave_critical_section(self); - - return TRUE; + return; } } - return FALSE; } static gboolean area_scroll(GtkWidget *widget, @@ -3278,23 +3273,12 @@ void gui_init(dt_iop_module_t *self) g_object_set_data(G_OBJECT(wrapper), "iop-instance", self); gtk_widget_set_name(GTK_WIDGET(wrapper), "toneeqgraph"); dt_action_define_iop(self, NULL, N_("graph"), GTK_WIDGET(wrapper), NULL); - gtk_widget_add_events(GTK_WIDGET(g->area), - GDK_POINTER_MOTION_MASK | darktable.gui->scroll_mask - | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); + gtk_widget_add_events(GTK_WIDGET(g->area), darktable.gui->scroll_mask); gtk_widget_set_vexpand(GTK_WIDGET(g->area), TRUE); gtk_widget_set_can_focus(GTK_WIDGET(g->area), TRUE); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(area_draw), self); - g_signal_connect(G_OBJECT(g->area), "button-press-event", - G_CALLBACK(area_button_press), self); - g_signal_connect(G_OBJECT(g->area), "button-release-event", - G_CALLBACK(area_button_release), self); - g_signal_connect(G_OBJECT(g->area), "leave-notify-event", - G_CALLBACK(area_enter_leave_notify), self); - g_signal_connect(G_OBJECT(g->area), "enter-notify-event", - G_CALLBACK(area_enter_leave_notify), self); - g_signal_connect(G_OBJECT(g->area), "motion-notify-event", - G_CALLBACK(area_motion_notify), self); + dt_gui_connect_click(g->area, _toneequal_button_press, _toneequal_button_release, self); + dt_gui_connect_motion(g->area, _toneequal_motion, _toneequal_enter, NULL, self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(area_scroll), self); gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _("double-click to reset the curve")); diff --git a/src/iop/zonesystem.c b/src/iop/zonesystem.c index 3adb8be831d8..ca22d735c95a 100644 --- a/src/iop/zonesystem.c +++ b/src/iop/zonesystem.c @@ -385,14 +385,22 @@ static gboolean dt_iop_zonesystem_preview_draw(GtkWidget *widget, cairo_t *crf, dt_iop_module_t *self); static gboolean dt_iop_zonesystem_bar_draw(GtkWidget *widget, cairo_t *crf, dt_iop_module_t *self); -static gboolean dt_iop_zonesystem_bar_motion_notify(GtkWidget *widget, GdkEventMotion *event, - dt_iop_module_t *self); -static gboolean dt_iop_zonesystem_bar_leave_notify(GtkWidget *widget, GdkEventCrossing *event, - dt_iop_module_t *self); -static gboolean dt_iop_zonesystem_bar_button_press(GtkWidget *widget, GdkEventButton *event, - dt_iop_module_t *self); -static gboolean dt_iop_zonesystem_bar_button_release(GtkWidget *widget, GdkEventButton *event, - dt_iop_module_t *self); +static void _zonesystem_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self); +static void _zonesystem_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self); +static void _zonesystem_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self); +static void _zonesystem_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self); static gboolean dt_iop_zonesystem_bar_scrolled(GtkWidget *widget, GdkEventScroll *event, dt_iop_module_t *self); @@ -432,9 +440,6 @@ void gui_init(dt_iop_module_t *self) g->preview = dtgtk_drawing_area_new_with_height(0); g_signal_connect(G_OBJECT(g->preview), "size-allocate", G_CALLBACK(size_allocate_callback), self); g_signal_connect(G_OBJECT(g->preview), "draw", G_CALLBACK(dt_iop_zonesystem_preview_draw), self); - gtk_widget_add_events(GTK_WIDGET(g->preview), GDK_POINTER_MOTION_MASK - | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - | GDK_LEAVE_NOTIFY_MASK); /* create the zonesystem bar widget */ g->zones = gtk_drawing_area_new(); @@ -442,18 +447,10 @@ void gui_init(dt_iop_module_t *self) "left-click on a border to create a marker\n" "right-click on a marker to delete it")); g_signal_connect(G_OBJECT(g->zones), "draw", G_CALLBACK(dt_iop_zonesystem_bar_draw), self); - g_signal_connect(G_OBJECT(g->zones), "motion-notify-event", G_CALLBACK(dt_iop_zonesystem_bar_motion_notify), - self); - g_signal_connect(G_OBJECT(g->zones), "leave-notify-event", G_CALLBACK(dt_iop_zonesystem_bar_leave_notify), - self); - g_signal_connect(G_OBJECT(g->zones), "button-press-event", G_CALLBACK(dt_iop_zonesystem_bar_button_press), - self); - g_signal_connect(G_OBJECT(g->zones), "button-release-event", - G_CALLBACK(dt_iop_zonesystem_bar_button_release), self); + dt_gui_connect_click_all(g->zones, _zonesystem_button_press, _zonesystem_button_release, self); + dt_gui_connect_motion(g->zones, _zonesystem_motion, NULL, _zonesystem_leave, self); g_signal_connect(G_OBJECT(g->zones), "scroll-event", G_CALLBACK(dt_iop_zonesystem_bar_scrolled), self); - gtk_widget_add_events(GTK_WIDGET(g->zones), GDK_POINTER_MOTION_MASK - | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - | GDK_LEAVE_NOTIFY_MASK | darktable.gui->scroll_mask); + gtk_widget_add_events(GTK_WIDGET(g->zones), darktable.gui->scroll_mask); gtk_widget_set_size_request(g->zones, -1, DT_PIXEL_APPLY_DPI(40)); self->widget = dt_gui_vbox(g->preview, g->zones); @@ -571,14 +568,17 @@ static gboolean dt_iop_zonesystem_bar_draw(GtkWidget *widget, cairo_t *crf, dt_i return TRUE; } -static gboolean dt_iop_zonesystem_bar_button_press(GtkWidget *widget, GdkEventButton *event, - dt_iop_module_t *self) +static void _zonesystem_button_press(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { dt_iop_zonesystem_params_t *p = self->params; dt_iop_zonesystem_gui_data_t *g = self->gui_data; const int inset = DT_ZONESYSTEM_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(g->zones, &allocation); int width = allocation.width - 2 * inset; /*, height = allocation.height - 2*inset;*/ /* calculate zonemap */ @@ -590,8 +590,8 @@ static gboolean dt_iop_zonesystem_bar_button_press(GtkWidget *widget, GdkEventBu float zw = zonemap[k + 1] - zonemap[k]; if((g->mouse_x / width) > zonemap[k] + (zw / 2)) k++; - - if(event->button == GDK_BUTTON_PRIMARY) + guint button = gtk_gesture_single_get_current_button(gesture); + if(button == GDK_BUTTON_PRIMARY) { if(p->zone[k] == -1) { @@ -601,25 +601,26 @@ static gboolean dt_iop_zonesystem_bar_button_press(GtkWidget *widget, GdkEventBu g->is_dragging = TRUE; g->current_zone = k; } - else if(event->button == GDK_BUTTON_SECONDARY) + else if(button == GDK_BUTTON_SECONDARY) { /* clear the controlpoint */ p->zone[k] = -1; dt_dev_add_history_item(darktable.develop, self, TRUE); } - - return TRUE; } -static gboolean dt_iop_zonesystem_bar_button_release(GtkWidget *widget, GdkEventButton *event, - dt_iop_module_t *self) +static void _zonesystem_button_release(GtkGestureSingle *gesture, + int n_press, + double x, + double y, + dt_iop_module_t *self) { dt_iop_zonesystem_gui_data_t *g = self->gui_data; - if(event->button == GDK_BUTTON_PRIMARY) + guint button = gtk_gesture_single_get_current_button(gesture); + if(button == GDK_BUTTON_PRIMARY) { g->is_dragging = FALSE; } - return TRUE; } static gboolean dt_iop_zonesystem_bar_scrolled(GtkWidget *widget, GdkEventScroll *event, dt_iop_module_t *self) @@ -641,23 +642,24 @@ static gboolean dt_iop_zonesystem_bar_scrolled(GtkWidget *widget, GdkEventScroll return TRUE; } -static gboolean dt_iop_zonesystem_bar_leave_notify(GtkWidget *widget, GdkEventCrossing *event, - dt_iop_module_t *self) +static void _zonesystem_leave(GtkEventControllerMotion *controller, + dt_iop_module_t *self) { dt_iop_zonesystem_gui_data_t *g = self->gui_data; g->hilite_zone = FALSE; gtk_widget_queue_draw(g->preview); - return TRUE; } -static gboolean dt_iop_zonesystem_bar_motion_notify(GtkWidget *widget, GdkEventMotion *event, - dt_iop_module_t *self) +static void _zonesystem_motion(GtkEventControllerMotion *controller, + double x, + double y, + dt_iop_module_t *self) { dt_iop_zonesystem_params_t *p = self->params; dt_iop_zonesystem_gui_data_t *g = self->gui_data; const int inset = DT_ZONESYSTEM_INSET; GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); + gtk_widget_get_allocation(g->zones, &allocation); int width = allocation.width - 2 * inset, height = allocation.height - 2 * inset; /* calculate zonemap */ @@ -665,8 +667,8 @@ static gboolean dt_iop_zonesystem_bar_motion_notify(GtkWidget *widget, GdkEventM _iop_zonesystem_calculate_zonemap(p, zonemap); /* record mouse position within control */ - g->mouse_x = CLAMP(event->x - inset, 0, width); - g->mouse_y = CLAMP(height - 1 - event->y + inset, 0, height); + g->mouse_x = CLAMP(x - inset, 0, width); + g->mouse_y = CLAMP(height - 1 - y + inset, 0, height); if(g->is_dragging) { @@ -703,7 +705,6 @@ static gboolean dt_iop_zonesystem_bar_motion_notify(GtkWidget *widget, GdkEventM gtk_widget_queue_draw(self->widget); gtk_widget_queue_draw(g->preview); - return TRUE; } diff --git a/src/libs/backgroundjobs.c b/src/libs/backgroundjobs.c index b791f704293f..5d8e4da65e2d 100644 --- a/src/libs/backgroundjobs.c +++ b/src/libs/backgroundjobs.c @@ -134,7 +134,7 @@ static gboolean _added_gui_thread(gpointer user_data) gtk_widget_show_all(params->instance_widget); gtk_widget_show(params->self_widget); - GdkCursor *cursor = gdk_cursor_new_for_display(gdk_display_get_default(), GDK_LEFT_PTR); + GdkCursor *cursor = gdk_cursor_new_from_name(gdk_display_get_default(), "default"); gdk_window_set_cursor(gtk_widget_get_window(params->instance_widget), cursor); g_object_unref(cursor); diff --git a/src/libs/colorpicker.c b/src/libs/colorpicker.c index cb3faf4f2c87..09f215032cde 100644 --- a/src/libs/colorpicker.c +++ b/src/libs/colorpicker.c @@ -26,6 +26,7 @@ #include "develop/develop.h" #include "develop/imageop.h" #include "dtgtk/button.h" +#include "dtgtk/drawingarea.h" #include "dtgtk/togglebutton.h" #include "gui/accelerators.h" #include "gui/color_picker_proxy.h" diff --git a/src/libs/lib.c b/src/libs/lib.c index c020f310e012..28dbc2923acc 100644 --- a/src/libs/lib.c +++ b/src/libs/lib.c @@ -24,7 +24,6 @@ #include "control/control.h" #include "dtgtk/button.h" #include "dtgtk/expander.h" -#include "dtgtk/icon.h" #include "gui/accelerators.h" #include "gui/drag_and_drop.h" #include "gui/gtk.h" @@ -1237,8 +1236,10 @@ GtkWidget *dt_lib_gui_get_expander(dt_lib_module_t *module) gtk_drag_source_set(header_evb, GDK_BUTTON1_MASK, target_list, 1, GDK_ACTION_COPY); gtk_drag_dest_set(expander, GTK_DEST_DEFAULT_DROP | GTK_DEST_DEFAULT_HIGHLIGHT, target_list, 1, GDK_ACTION_COPY); +if(0) { // GTK4 g_signal_connect(expander, "drag-motion", G_CALLBACK(_on_drag_motion), module); g_signal_connect(expander, "drag-drop", G_CALLBACK(_on_drag_drop), module); +} } /* setup the header box */ @@ -1319,7 +1320,7 @@ GtkWidget *dt_lib_gui_get_expander(dt_lib_module_t *module) if(module->widget) { dt_gui_add_class(module->widget, "dt_plugin_ui_main"); - gtk_widget_set_hexpand(module->widget, FALSE); + // gtk_widget_set_hexpand(module->widget, FALSE); // GTK4 gtk_widget_set_vexpand(module->widget, FALSE); } dt_gui_add_class(pluginui_frame, "dt_plugin_ui"); diff --git a/src/libs/location.c b/src/libs/location.c index 5be0ce9f8af0..651548a02a24 100644 --- a/src/libs/location.c +++ b/src/libs/location.c @@ -22,7 +22,6 @@ #include "control/conf.h" #include "control/control.h" #include "control/jobs.h" -#include "dtgtk/icon.h" #include "gui/gtk.h" #include "libs/lib.h" #include "libs/lib_api.h" diff --git a/src/libs/modulegroups.c b/src/libs/modulegroups.c index 264e69341768..18b7819ba4f9 100644 --- a/src/libs/modulegroups.c +++ b/src/libs/modulegroups.c @@ -25,7 +25,6 @@ #include "control/control.h" #include "develop/develop.h" #include "dtgtk/button.h" -#include "dtgtk/icon.h" #include "gui/accelerators.h" #include "gui/gtk.h" #include "gui/presets.h" @@ -842,6 +841,7 @@ static void _lib_modulegroups_update_iop_visibility(dt_lib_module_t *self) */ dt_iop_module_t *module = modules->data; GtkWidget *w = module->expander; +gtk_widget_show(w); continue; // GTK4 show all modules for testing purposes if(module->enabled) dt_print(DT_DEBUG_IOPORDER, "%20s %d%s", diff --git a/src/libs/tools/global_toolbox.c b/src/libs/tools/global_toolbox.c index 5ab5b172282c..5345a860a49a 100644 --- a/src/libs/tools/global_toolbox.c +++ b/src/libs/tools/global_toolbox.c @@ -412,7 +412,7 @@ void gui_init(dt_lib_module_t *self) gtk_container_add(GTK_CONTAINER(d->over_popup), vbox); #define NEW_RADIO(widget, box, callback, label) \ - rb = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rb), _(label)); \ + rb = gtk_check_button_new_with_label(_(label)); /* GTK4 */\ dt_action_define(ac, NULL, label, rb, &dt_action_def_button); \ g_signal_connect(G_OBJECT(rb), "clicked", G_CALLBACK(callback), self); \ gtk_box_pack_start(GTK_BOX(box), rb, TRUE, TRUE, 0); \ diff --git a/src/libs/tools/ratings.c b/src/libs/tools/ratings.c index e5fe913bbd4f..ebcba8fa3925 100644 --- a/src/libs/tools/ratings.c +++ b/src/libs/tools/ratings.c @@ -21,6 +21,7 @@ #include "common/debug.h" #include "control/control.h" #include "dtgtk/button.h" +#include "dtgtk/drawingarea.h" #include "gui/draw.h" #include "gui/gtk.h" #include "gui/accelerators.h" diff --git a/src/views/view.c b/src/views/view.c index bebc33493f90..ac733b1d5e22 100644 --- a/src/views/view.c +++ b/src/views/view.c @@ -340,7 +340,7 @@ gboolean dt_view_manager_switch_by_view(dt_view_manager_t *vm, if(plugin->widget) gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(plugin->widget)), plugin->widget); if(plugin->expander) - gtk_widget_destroy(plugin->expander); + gtk_box_remove(GTK_BOX(gtk_widget_get_parent(plugin->expander)), plugin->expander); } plugin->expander = NULL; }