[gimp/gtk3-port: 412/454] Enable and fix smooth scrolling and zooming
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gtk3-port: 412/454] Enable and fix smooth scrolling and zooming
- Date: Wed, 16 May 2018 21:55:21 +0000 (UTC)
commit ca8f7fef375e175c127f87976b3137f413adb7c6
Author: Michael Natterer <mitch gimp org>
Date: Fri May 11 02:08:51 2018 +0200
Enable and fix smooth scrolling and zooming
- Fix gimp_scroll_adjustment_values() for smooth scroll events
- Set GDK_SMOOTH_SCROLL_MASK on all widgets where we set GDK_SCROLL_MASK
- Add GIMP_ZOOM_SMOOTH to enum GimpZoomType
- Add "gdouble delta" to gimp_zoom_model_step()
- Change the meaning of the "scale" parameter to "scale or delta" in
all functions that take GimpZoomType and a scale factor.
app/core/gimpmarshal.list | 1 +
app/display/gimpcanvas.h | 1 +
app/display/gimpdisplayshell-scale.c | 10 ++++++--
app/display/gimpdisplayshell-tool-events.c | 10 ++++++++
app/display/gimpdisplayshell.c | 3 +-
app/display/gimpnavigationeditor.c | 4 ++-
app/widgets/gimpgradienteditor.c | 4 ++-
app/widgets/gimpnavigationview.c | 19 +++++++++++----
app/widgets/gimpnavigationview.h | 3 +-
app/widgets/gimpsearchpopup.c | 3 +-
app/widgets/gimptagpopup.c | 3 +-
libgimp/gimpzoompreview.c | 6 +++++
libgimpwidgets/gimppreview.c | 1 +
libgimpwidgets/gimpscrolledpreview.c | 18 ++++++++------
libgimpwidgets/gimpwidgetsenums.h | 4 ++-
libgimpwidgets/gimpzoommodel.c | 33 +++++++++++++++++++++------
libgimpwidgets/gimpzoommodel.h | 3 +-
17 files changed, 94 insertions(+), 32 deletions(-)
---
diff --git a/app/core/gimpmarshal.list b/app/core/gimpmarshal.list
index a79ef9b..4232c47 100644
--- a/app/core/gimpmarshal.list
+++ b/app/core/gimpmarshal.list
@@ -42,6 +42,7 @@ VOID: DOUBLE
VOID: DOUBLE, DOUBLE
VOID: DOUBLE, DOUBLE, DOUBLE, DOUBLE
VOID: ENUM
+VOID: ENUM, DOUBLE
VOID: ENUM, INT
VOID: ENUM, INT, BOOLEAN
VOID: ENUM, OBJECT
diff --git a/app/display/gimpcanvas.h b/app/display/gimpcanvas.h
index a4f02e8..e49bdfc 100644
--- a/app/display/gimpcanvas.h
+++ b/app/display/gimpcanvas.h
@@ -27,6 +27,7 @@
GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_SCROLL_MASK | \
+ GDK_SMOOTH_SCROLL_MASK | \
GDK_STRUCTURE_MASK | \
GDK_ENTER_NOTIFY_MASK | \
GDK_LEAVE_NOTIFY_MASK | \
diff --git a/app/display/gimpdisplayshell-scale.c b/app/display/gimpdisplayshell-scale.c
index e23a262..d89af5c 100644
--- a/app/display/gimpdisplayshell-scale.c
+++ b/app/display/gimpdisplayshell-scale.c
@@ -352,14 +352,18 @@ gimp_display_shell_scale (GimpDisplayShell *shell,
GimpZoomFocus zoom_focus)
{
gdouble current_scale;
+ gdouble delta;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_if_fail (shell->canvas != NULL);
current_scale = gimp_zoom_model_get_factor (shell->zoom);
+ if (zoom_type == GIMP_ZOOM_SMOOTH)
+ delta = new_scale;
+
if (zoom_type != GIMP_ZOOM_TO)
- new_scale = gimp_zoom_model_zoom_step (zoom_type, current_scale);
+ new_scale = gimp_zoom_model_zoom_step (zoom_type, current_scale, delta);
if (! SCALE_EQUALS (new_scale, current_scale))
{
@@ -755,14 +759,14 @@ gimp_display_shell_set_initial_scale (GimpDisplayShell *shell,
new_scale = current * MIN (((gdouble) monitor_height) / shell_height,
((gdouble) monitor_width) / shell_width);
- new_scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, new_scale);
+ new_scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, new_scale, 0.0);
/* Since zooming out might skip a zoom step we zoom in
* again and test if we are small enough.
*/
gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO,
gimp_zoom_model_zoom_step (GIMP_ZOOM_IN,
- new_scale));
+ new_scale, 0.0));
if (SCALEX (shell, image_width) > monitor_width ||
SCALEY (shell, image_height) > monitor_height)
diff --git a/app/display/gimpdisplayshell-tool-events.c b/app/display/gimpdisplayshell-tool-events.c
index 7c41dfd..8bc98c9 100644
--- a/app/display/gimpdisplayshell-tool-events.c
+++ b/app/display/gimpdisplayshell-tool-events.c
@@ -732,6 +732,8 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
{
if (state & gimp_get_toggle_behavior_mask ())
{
+ gdouble delta;
+
switch (sevent->direction)
{
case GDK_SCROLL_UP:
@@ -748,6 +750,14 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
GIMP_ZOOM_FOCUS_BEST_GUESS);
break;
+ case GDK_SCROLL_SMOOTH:
+ gdk_event_get_scroll_deltas (event, NULL, &delta);
+ gimp_display_shell_scale (shell,
+ GIMP_ZOOM_SMOOTH,
+ delta,
+ GIMP_ZOOM_FOCUS_BEST_GUESS);
+ break;
+
default:
break;
}
diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c
index 64f7cd6..ce6d39a 100644
--- a/app/display/gimpdisplayshell.c
+++ b/app/display/gimpdisplayshell.c
@@ -334,7 +334,8 @@ gimp_display_shell_init (GimpDisplayShell *shell)
GDK_KEY_RELEASE_MASK |
GDK_FOCUS_CHANGE_MASK |
GDK_VISIBILITY_NOTIFY_MASK |
- GDK_SCROLL_MASK));
+ GDK_SCROLL_MASK |
+ GDK_SMOOTH_SCROLL_MASK));
/* zoom model callback */
g_signal_connect_swapped (shell->zoom, "zoomed",
diff --git a/app/display/gimpnavigationeditor.c b/app/display/gimpnavigationeditor.c
index 31e8b7d..479a6e5 100644
--- a/app/display/gimpnavigationeditor.c
+++ b/app/display/gimpnavigationeditor.c
@@ -80,6 +80,7 @@ static void gimp_navigation_editor_marker_changed (GimpNavigationView
GimpNavigationEditor *editor);
static void gimp_navigation_editor_zoom (GimpNavigationView *view,
GimpZoomType direction,
+ gdouble delta,
GimpNavigationEditor *editor);
static void gimp_navigation_editor_scroll (GimpNavigationView *view,
GdkEventScroll *sevent,
@@ -553,6 +554,7 @@ gimp_navigation_editor_marker_changed (GimpNavigationView *view,
static void
gimp_navigation_editor_zoom (GimpNavigationView *view,
GimpZoomType direction,
+ gdouble delta,
GimpNavigationEditor *editor)
{
g_return_if_fail (direction != GIMP_ZOOM_TO);
@@ -562,7 +564,7 @@ gimp_navigation_editor_zoom (GimpNavigationView *view,
if (gimp_display_get_image (editor->shell->display))
gimp_display_shell_scale (editor->shell,
direction,
- 0.0,
+ delta,
GIMP_ZOOM_FOCUS_BEST_GUESS);
}
}
diff --git a/app/widgets/gimpgradienteditor.c b/app/widgets/gimpgradienteditor.c
index d85f6fd..14e93e0 100644
--- a/app/widgets/gimpgradienteditor.c
+++ b/app/widgets/gimpgradienteditor.c
@@ -92,7 +92,8 @@
GDK_POINTER_MOTION_HINT_MASK | \
GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
- GDK_SCROLL_MASK)
+ GDK_SCROLL_MASK | \
+ GDK_SMOOTH_SCROLL_MASK)
#define GRAD_CONTROL_EVENT_MASK (GDK_EXPOSURE_MASK | \
GDK_LEAVE_NOTIFY_MASK | \
@@ -101,6 +102,7 @@
GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_SCROLL_MASK | \
+ GDK_SMOOTH_SCROLL_MASK | \
GDK_BUTTON1_MOTION_MASK)
diff --git a/app/widgets/gimpnavigationview.c b/app/widgets/gimpnavigationview.c
index 627f647..982479a 100644
--- a/app/widgets/gimpnavigationview.c
+++ b/app/widgets/gimpnavigationview.c
@@ -138,9 +138,10 @@ gimp_navigation_view_class_init (GimpNavigationViewClass *klass)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpNavigationViewClass, zoom),
NULL, NULL,
- gimp_marshal_VOID__ENUM,
- G_TYPE_NONE, 1,
- GIMP_TYPE_ZOOM_TYPE);
+ gimp_marshal_VOID__ENUM_DOUBLE,
+ G_TYPE_NONE, 2,
+ GIMP_TYPE_ZOOM_TYPE,
+ G_TYPE_DOUBLE);
view_signals[SCROLL] =
g_signal_new ("scroll",
@@ -167,6 +168,7 @@ gimp_navigation_view_init (GimpNavigationView *view)
gtk_widget_set_can_focus (GTK_WIDGET (view), TRUE);
gtk_widget_add_events (GTK_WIDGET (view),
GDK_SCROLL_MASK |
+ GDK_SMOOTH_SCROLL_MASK |
GDK_POINTER_MOTION_MASK |
GDK_KEY_PRESS_MASK);
@@ -297,14 +299,21 @@ gimp_navigation_view_scroll (GtkWidget *widget,
{
if (sevent->state & gimp_get_toggle_behavior_mask ())
{
+ gdouble delta;
+
switch (sevent->direction)
{
case GDK_SCROLL_UP:
- g_signal_emit (widget, view_signals[ZOOM], 0, GIMP_ZOOM_IN);
+ g_signal_emit (widget, view_signals[ZOOM], 0, GIMP_ZOOM_IN, 0.0);
break;
case GDK_SCROLL_DOWN:
- g_signal_emit (widget, view_signals[ZOOM], 0, GIMP_ZOOM_OUT);
+ g_signal_emit (widget, view_signals[ZOOM], 0, GIMP_ZOOM_OUT, 0.0);
+ break;
+
+ case GDK_SCROLL_SMOOTH:
+ gdk_event_get_scroll_deltas ((GdkEvent *) sevent, NULL, &delta);
+ g_signal_emit (widget, view_signals[ZOOM], 0, GIMP_ZOOM_SMOOTH, delta);
break;
default:
diff --git a/app/widgets/gimpnavigationview.h b/app/widgets/gimpnavigationview.h
index 22d7113..2a0545d 100644
--- a/app/widgets/gimpnavigationview.h
+++ b/app/widgets/gimpnavigationview.h
@@ -47,7 +47,8 @@ struct _GimpNavigationViewClass
gdouble width,
gdouble height);
void (* zoom) (GimpNavigationView *view,
- GimpZoomType direction);
+ GimpZoomType direction,
+ gdouble delta);
void (* scroll) (GimpNavigationView *view,
GdkEventScroll *sevent);
};
diff --git a/app/widgets/gimpsearchpopup.c b/app/widgets/gimpsearchpopup.c
index 490afe7..e94f0dc 100644
--- a/app/widgets/gimpsearchpopup.c
+++ b/app/widgets/gimpsearchpopup.c
@@ -370,7 +370,8 @@ gimp_search_popup_constructed (GObject *object)
GDK_KEY_RELEASE_MASK |
GDK_KEY_PRESS_MASK |
GDK_BUTTON_PRESS_MASK |
- GDK_SCROLL_MASK);
+ GDK_SCROLL_MASK |
+ GDK_SMOOTH_SCROLL_MASK);
g_signal_connect (popup->priv->keyword_entry, "key-press-event",
G_CALLBACK (keyword_entry_key_press_event),
diff --git a/app/widgets/gimptagpopup.c b/app/widgets/gimptagpopup.c
index 38e89f9..be9d49b 100644
--- a/app/widgets/gimptagpopup.c
+++ b/app/widgets/gimptagpopup.c
@@ -162,7 +162,8 @@ gimp_tag_popup_init (GimpTagPopup *popup)
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK |
GDK_KEY_RELEASE_MASK |
- GDK_SCROLL_MASK);
+ GDK_SCROLL_MASK |
+ GDK_SMOOTH_SCROLL_MASK);
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (popup)),
GTK_STYLE_CLASS_MENU);
diff --git a/libgimp/gimpzoompreview.c b/libgimp/gimpzoompreview.c
index 7c02ec6..8190339 100644
--- a/libgimp/gimpzoompreview.c
+++ b/libgimp/gimpzoompreview.c
@@ -435,6 +435,7 @@ gimp_zoom_preview_scroll_event (GtkWidget *widget,
if (event->state & GDK_CONTROL_MASK)
{
GimpZoomPreviewPrivate *priv = GET_PRIVATE (preview);
+ gdouble delta;
gimp_scrolled_preview_freeze (GIMP_SCROLLED_PREVIEW (preview));
@@ -448,6 +449,11 @@ gimp_zoom_preview_scroll_event (GtkWidget *widget,
gimp_zoom_model_zoom (priv->model, GIMP_ZOOM_OUT, 0.0);
break;
+ case GDK_SCROLL_SMOOTH:
+ gdk_event_get_scroll_deltas ((GdkEvent *) event, NULL, &delta);
+ gimp_zoom_model_zoom (priv->model, GIMP_ZOOM_SMOOTH, delta);
+ break;
+
default:
break;
}
diff --git a/libgimpwidgets/gimppreview.c b/libgimpwidgets/gimppreview.c
index d76a875..c066c1b 100644
--- a/libgimpwidgets/gimppreview.c
+++ b/libgimpwidgets/gimppreview.c
@@ -281,6 +281,7 @@ gimp_preview_init (GimpPreview *preview)
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_SCROLL_MASK |
+ GDK_SMOOTH_SCROLL_MASK |
GDK_POINTER_MOTION_HINT_MASK |
GDK_BUTTON_MOTION_MASK);
diff --git a/libgimpwidgets/gimpscrolledpreview.c b/libgimpwidgets/gimpscrolledpreview.c
index a7c73b3..ae375db 100644
--- a/libgimpwidgets/gimpscrolledpreview.c
+++ b/libgimpwidgets/gimpscrolledpreview.c
@@ -963,8 +963,8 @@ gimp_scroll_adjustment_values (GdkEventScroll *sevent,
{
GtkAdjustment *adj_x;
GtkAdjustment *adj_y;
- gdouble page_size_x;
- gdouble page_size_y;
+ gdouble scroll_unit_x;
+ gdouble scroll_unit_y;
gdouble value_x = 0.0;
gdouble value_y = 0.0;
@@ -983,29 +983,31 @@ gimp_scroll_adjustment_values (GdkEventScroll *sevent,
adj_y = vadj;
}
- page_size_x = gtk_adjustment_get_page_size (adj_x);
- page_size_y = gtk_adjustment_get_page_size (adj_y);
+ scroll_unit_x = pow (gtk_adjustment_get_page_size (adj_x), 2.0 / 3.0);
+ scroll_unit_y = pow (gtk_adjustment_get_page_size (adj_y), 2.0 / 3.0);
switch (sevent->direction)
{
case GDK_SCROLL_LEFT:
- value_x = -pow (page_size_x, 2.0 / 3.0);
+ value_x = -scroll_unit_x;
break;
case GDK_SCROLL_RIGHT:
- value_x = pow (page_size_x, 2.0 / 3.0);
+ value_x = scroll_unit_x;
break;
case GDK_SCROLL_UP:
- value_y = -pow (page_size_y, 2.0 / 3.0);
+ value_y = -scroll_unit_y;
break;
case GDK_SCROLL_DOWN:
- value_y = pow (page_size_y, 2.0 / 3.0);
+ value_y = scroll_unit_y;
break;
case GDK_SCROLL_SMOOTH:
gdk_event_get_scroll_deltas ((GdkEvent *) sevent, &value_x, &value_y);
+ value_x *= scroll_unit_x;
+ value_y *= scroll_unit_y;
}
value_x = CLAMP (value_x +
diff --git a/libgimpwidgets/gimpwidgetsenums.h b/libgimpwidgets/gimpwidgetsenums.h
index 4876e18..a2f9333 100644
--- a/libgimpwidgets/gimpwidgetsenums.h
+++ b/libgimpwidgets/gimpwidgetsenums.h
@@ -190,6 +190,7 @@ typedef enum
* @GIMP_ZOOM_IN_MAX: zoom in as far as possible
* @GIMP_ZOOM_OUT_MAX: zoom out as far as possible
* @GIMP_ZOOM_TO: zoom to a specific zoom factor
+ * @GIMP_ZOOM_SMOOTH: zoom smoothly from a smooth scroll event
*
* the zoom types for #GimpZoomModel.
**/
@@ -205,7 +206,8 @@ typedef enum
GIMP_ZOOM_OUT_MORE, /*< skip >*/
GIMP_ZOOM_IN_MAX, /*< skip >*/
GIMP_ZOOM_OUT_MAX, /*< skip >*/
- GIMP_ZOOM_TO /*< skip >*/
+ GIMP_ZOOM_TO, /*< skip >*/
+ GIMP_ZOOM_SMOOTH /*< skip >*/
} GimpZoomType;
diff --git a/libgimpwidgets/gimpzoommodel.c b/libgimpwidgets/gimpzoommodel.c
index 805a039..2fe834f 100644
--- a/libgimpwidgets/gimpzoommodel.c
+++ b/libgimpwidgets/gimpzoommodel.c
@@ -371,13 +371,18 @@ gimp_zoom_model_zoom (GimpZoomModel *model,
GimpZoomType zoom_type,
gdouble scale)
{
+ gdouble delta = 0.0;
+
g_return_if_fail (GIMP_IS_ZOOM_MODEL (model));
+ if (zoom_type == GIMP_ZOOM_SMOOTH)
+ delta = scale;
+
if (zoom_type != GIMP_ZOOM_TO)
scale = gimp_zoom_model_get_factor (model);
g_object_set (model,
- "value", gimp_zoom_model_zoom_step (zoom_type, scale),
+ "value", gimp_zoom_model_zoom_step (zoom_type, scale, delta),
NULL);
}
@@ -605,6 +610,7 @@ gimp_zoom_button_new (GimpZoomModel *model,
* gimp_zoom_model_zoom_step:
* @zoom_type: the zoom type
* @scale: ignored unless @zoom_type == %GIMP_ZOOM_TO
+ * @delta: the delta from a smooth zoom event
*
* Utility function to calculate a new scale factor.
*
@@ -614,7 +620,8 @@ gimp_zoom_button_new (GimpZoomModel *model,
**/
gdouble
gimp_zoom_model_zoom_step (GimpZoomType zoom_type,
- gdouble scale)
+ gdouble scale,
+ gdouble delta)
{
gint i, n_presets;
gdouble new_scale = 1.0;
@@ -669,16 +676,16 @@ gimp_zoom_model_zoom_step (GimpZoomType zoom_type,
break;
case GIMP_ZOOM_IN_MORE:
- scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_IN, scale);
- scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_IN, scale);
- scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_IN, scale);
+ scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_IN, scale, 0.0);
+ scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_IN, scale, 0.0);
+ scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_IN, scale, 0.0);
new_scale = scale;
break;
case GIMP_ZOOM_OUT_MORE:
- scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, scale);
- scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, scale);
- scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, scale);
+ scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, scale, 0.0);
+ scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, scale, 0.0);
+ scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, scale, 0.0);
new_scale = scale;
break;
@@ -693,6 +700,16 @@ gimp_zoom_model_zoom_step (GimpZoomType zoom_type,
case GIMP_ZOOM_TO:
new_scale = scale;
break;
+
+ case GIMP_ZOOM_SMOOTH:
+ if (delta > 0.0)
+ new_scale = scale * (1.0 + 0.1 * delta);
+ else if (delta < 0.0)
+ new_scale = scale / (1.0 + 0.1 * -delta);
+ else
+ new_scale = scale;
+ break;
+
}
return CLAMP (new_scale, ZOOM_MIN, ZOOM_MAX);
diff --git a/libgimpwidgets/gimpzoommodel.h b/libgimpwidgets/gimpzoommodel.h
index 50f6052..e36724e 100644
--- a/libgimpwidgets/gimpzoommodel.h
+++ b/libgimpwidgets/gimpzoommodel.h
@@ -86,7 +86,8 @@ GtkWidget * gimp_zoom_button_new (GimpZoomModel *model,
GtkIconSize icon_size);
gdouble gimp_zoom_model_zoom_step (GimpZoomType zoom_type,
- gdouble scale);
+ gdouble scale,
+ gdouble delta);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]