Skip to content

Commit ac46abd

Browse files
committed
add touchpad pinch zoom and smooth pan gestures
1 parent e6690f3 commit ac46abd

5 files changed

Lines changed: 138 additions & 1 deletion

File tree

src/gui/gtk.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,10 +730,41 @@ static gboolean _draw(GtkWidget *da,
730730
return TRUE;
731731
}
732732

733+
static gboolean _input_event(GtkWidget *widget,
734+
GdkEvent *event,
735+
gpointer user_data)
736+
{
737+
(void)user_data;
738+
739+
if(event->type == GDK_TOUCHPAD_PINCH)
740+
{
741+
const GdkEventTouchpadPinch *pinch = &event->touchpad_pinch;
742+
if(dt_view_manager_gesture_pinch(darktable.view_manager, pinch->x, pinch->y,
743+
pinch->phase, pinch->scale, pinch->state & 0xf))
744+
{
745+
gtk_widget_queue_draw(widget);
746+
return TRUE;
747+
}
748+
}
749+
750+
return FALSE;
751+
}
752+
733753
static gboolean _scrolled(GtkWidget *widget,
734754
const GdkEventScroll *event,
735755
gpointer user_data)
736756
{
757+
(void)user_data;
758+
759+
if(event->direction == GDK_SCROLL_SMOOTH && !event->is_stop
760+
&& (event->delta_x != 0.0 || event->delta_y != 0.0)
761+
&& dt_view_manager_gesture_pan(darktable.view_manager, event->x, event->y,
762+
event->delta_x, event->delta_y, event->state & 0xf))
763+
{
764+
gtk_widget_queue_draw(widget);
765+
return TRUE;
766+
}
767+
737768
int delta_y;
738769
if(dt_gui_get_scroll_unit_delta(event, &delta_y))
739770
{
@@ -1481,10 +1512,13 @@ int dt_gui_gtk_init(dt_gui_gtk_t *gui)
14811512
gtk_widget_add_events(widget,
14821513
GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK
14831514
| GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK
1484-
| GDK_LEAVE_NOTIFY_MASK | darktable.gui->scroll_mask);
1515+
| GDK_LEAVE_NOTIFY_MASK | GDK_TOUCHPAD_GESTURE_MASK
1516+
| darktable.gui->scroll_mask);
14851517

14861518
g_signal_connect(G_OBJECT(widget), "draw",
14871519
G_CALLBACK(_draw), NULL);
1520+
g_signal_connect(G_OBJECT(widget), "event",
1521+
G_CALLBACK(_input_event), NULL);
14881522
g_signal_connect(G_OBJECT(widget), "motion-notify-event",
14891523
G_CALLBACK(_mouse_moved), gui);
14901524
g_signal_connect(G_OBJECT(widget), "leave-notify-event",

src/views/darkroom.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3722,6 +3722,67 @@ void scrolled(dt_view_t *self,
37223722
dt_dev_zoom_move(&dev->full, DT_ZOOM_SCROLL, 0.0f, up, x, y, constrained);
37233723
}
37243724

3725+
gboolean gesture_pan(dt_view_t *self,
3726+
const double x,
3727+
const double y,
3728+
const double dx,
3729+
const double dy,
3730+
const int state)
3731+
{
3732+
dt_develop_t *dev = self->data;
3733+
(void)x;
3734+
(void)y;
3735+
(void)state;
3736+
if(!dev) return FALSE;
3737+
if(dx == 0.0 && dy == 0.0) return FALSE;
3738+
3739+
dt_dev_zoom_move(&dev->full, DT_ZOOM_MOVE, 1.0f, 0, dx, dy, TRUE);
3740+
return TRUE;
3741+
}
3742+
3743+
gboolean gesture_pinch(dt_view_t *self,
3744+
const double x,
3745+
const double y,
3746+
const int phase,
3747+
const double scale,
3748+
const int state)
3749+
{
3750+
dt_develop_t *dev = self->data;
3751+
if(!dev) return FALSE;
3752+
const gboolean constrained = !dt_modifier_is(state, GDK_CONTROL_MASK);
3753+
3754+
static double pinch_last_scale = 0.0;
3755+
3756+
if(phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN)
3757+
{
3758+
pinch_last_scale = scale > 0.0 ? scale : 1.0;
3759+
return TRUE;
3760+
}
3761+
3762+
if(phase == GDK_TOUCHPAD_GESTURE_PHASE_END
3763+
|| phase == GDK_TOUCHPAD_GESTURE_PHASE_CANCEL)
3764+
{
3765+
pinch_last_scale = 0.0;
3766+
return TRUE;
3767+
}
3768+
3769+
if(phase != GDK_TOUCHPAD_GESTURE_PHASE_UPDATE) return FALSE;
3770+
if(pinch_last_scale <= 0.0 || scale <= 0.0) return FALSE;
3771+
3772+
if(scale > pinch_last_scale)
3773+
{
3774+
dt_dev_zoom_move(&dev->full, DT_ZOOM_SCROLL, 0.0f, 1, x, y, constrained);
3775+
pinch_last_scale = scale;
3776+
}
3777+
else if(scale < pinch_last_scale)
3778+
{
3779+
dt_dev_zoom_move(&dev->full, DT_ZOOM_SCROLL, 0.0f, 0, x, y, constrained);
3780+
pinch_last_scale = scale;
3781+
}
3782+
3783+
return TRUE;
3784+
}
3785+
37253786
static void _change_slider_accel_precision(dt_action_t *action)
37263787
{
37273788
const int curr_precision = dt_conf_get_int("accel/slider_precision");

src/views/view.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,34 @@ void dt_view_manager_scrolled(dt_view_manager_t *vm,
669669
vm->current_view->scrolled(vm->current_view, x, y, up, state);
670670
}
671671

672+
gboolean dt_view_manager_gesture_pan(dt_view_manager_t *vm,
673+
const double x,
674+
const double y,
675+
const double dx,
676+
const double dy,
677+
const int state)
678+
{
679+
if(!vm->current_view)
680+
return FALSE;
681+
if(vm->current_view->gesture_pan)
682+
return vm->current_view->gesture_pan(vm->current_view, x, y, dx, dy, state);
683+
return FALSE;
684+
}
685+
686+
gboolean dt_view_manager_gesture_pinch(dt_view_manager_t *vm,
687+
const double x,
688+
const double y,
689+
const int phase,
690+
const double scale,
691+
const int state)
692+
{
693+
if(!vm->current_view)
694+
return FALSE;
695+
if(vm->current_view->gesture_pinch)
696+
return vm->current_view->gesture_pinch(vm->current_view, x, y, phase, scale, state);
697+
return FALSE;
698+
}
699+
672700
void dt_view_manager_scrollbar_changed(dt_view_manager_t *vm,
673701
const double x,
674702
const double y)

src/views/view.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,18 @@ void dt_view_manager_scrolled(dt_view_manager_t *vm,
453453
const double y,
454454
const int up,
455455
const int state);
456+
gboolean dt_view_manager_gesture_pan(dt_view_manager_t *vm,
457+
const double x,
458+
const double y,
459+
const double dx,
460+
const double dy,
461+
const int state);
462+
gboolean dt_view_manager_gesture_pinch(dt_view_manager_t *vm,
463+
const double x,
464+
const double y,
465+
const int phase,
466+
const double scale,
467+
const int state);
456468
void dt_view_manager_scrollbar_changed(dt_view_manager_t *vm,
457469
const double x,
458470
const double y);

src/views/view_api.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ OPTIONAL(int, button_pressed, struct dt_view_t *self, double x, double y, double
5858
OPTIONAL(void, configure, struct dt_view_t *self, int width, int height);
5959
OPTIONAL(void, scrolled, struct dt_view_t *self, double x, double y, int up, int state); // mouse scrolled in view
6060
OPTIONAL(void, scrollbar_changed, struct dt_view_t *self, double x, double y); // scrollbars changed in view
61+
OPTIONAL(gboolean, gesture_pan, struct dt_view_t *self, double x, double y, double dx, double dy, int state);
62+
OPTIONAL(gboolean, gesture_pinch, struct dt_view_t *self, double x, double y, int phase, double scale, int state);
6163

6264
// list of mouse actions
6365
OPTIONAL(GSList *, mouse_actions, const struct dt_view_t *self);

0 commit comments

Comments
 (0)