[gtk+/wip/baedert/gtkimageview] GtkImageView: Don't use internal scale/angle values for gestures
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baedert/gtkimageview] GtkImageView: Don't use internal scale/angle values for gestures
- Date: Sun, 24 Jan 2016 20:05:07 +0000 (UTC)
commit 6c15ba694bf58dec80398620034f08c2dd24f839
Author: Timm Bäder <mail baedert org>
Date: Sun Jan 24 21:01:08 2016 +0100
GtkImageView: Don't use internal scale/angle values for gestures
Instead, use separate values so they are independent from the internal
values, and so we can properly reset them in the gestures' ::cancel.
gtk/gtkimageview.c | 152 +++++++++++++++++++++++++++++++---------------------
1 files changed, 90 insertions(+), 62 deletions(-)
---
diff --git a/gtk/gtkimageview.c b/gtk/gtkimageview.c
index 4b1c9cb..9b4e544 100644
--- a/gtk/gtkimageview.c
+++ b/gtk/gtkimageview.c
@@ -33,6 +33,7 @@ typedef struct
// XXX Add gtk_image_reset_view that transitions back to scale = 1 and angle = 0.
+// TODO: Set scale-set to FALSE every time we manipulate it from inside gtkimageview
struct _GtkImageViewPrivate
{
@@ -51,9 +52,11 @@ struct _GtkImageViewPrivate
GtkGesture *rotate_gesture;
double gesture_start_angle;
+ double gesture_scale;
GtkGesture *zoom_gesture;
double gesture_start_scale;
+ double gesture_angle;
/* Current anchor point, or -1/-1.
* In widget coordinates. */
@@ -141,6 +144,44 @@ static inline void gtk_image_view_restrict_adjustment (GtkAdjustment *adjustment
/* }}} */
+static inline double
+gtk_image_view_get_real_scale (GtkImageView *image_view)
+{
+ GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
+
+ if (priv->in_zoom)
+ return priv->gesture_scale;
+ else
+ return priv->scale;
+}
+
+
+static inline double
+gtk_image_view_get_real_angle (GtkImageView *image_view)
+{
+ GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
+
+ if (priv->in_rotate)
+ return priv->gesture_angle;
+ else
+ return priv->angle;
+}
+
+static inline double
+gtk_image_view_clamp_angle (double angle)
+{
+ double new_angle = angle;
+
+ if (angle > 360.0)
+ new_angle -= (int)(angle / 360.0) * 360;
+ else if (angle < 0.0)
+ new_angle = 360.0 + (int)(angle / 360.0);
+
+ g_assert (new_angle >= 0.0);
+ g_assert (new_angle <= 360.0);
+
+ return new_angle;
+}
static void
@@ -156,8 +197,8 @@ gtk_image_view_get_current_state (GtkImageView *image_view,
state->hupper = gtk_adjustment_get_upper (priv->hadjustment);
state->vupper = gtk_adjustment_get_upper (priv->vadjustment);
}
- state->angle = priv->angle;
- state->scale = priv->scale;
+ state->angle = gtk_image_view_get_real_angle (image_view);
+ state->scale = gtk_image_view_get_real_scale (image_view);
}
@@ -196,6 +237,7 @@ gtk_image_view_fix_anchor (GtkImageView *image_view,
- old_state->vupper;
double hupper_delta_scale, vupper_delta_scale;
double hupper_delta_angle, vupper_delta_angle;
+ double cur_scale = gtk_image_view_get_real_scale (image_view);
g_assert (priv->hadjustment);
@@ -207,9 +249,9 @@ gtk_image_view_fix_anchor (GtkImageView *image_view,
g_assert (anchor_y < gtk_widget_get_allocated_height (GTK_WIDGET (image_view)));
/* Amount of upper change caused by scale */
- hupper_delta_scale = ((old_state->hupper / old_state->scale) * priv->scale)
+ hupper_delta_scale = ((old_state->hupper / old_state->scale) * cur_scale)
- old_state->hupper;
- vupper_delta_scale = ((old_state->vupper / old_state->scale) * priv->scale)
+ vupper_delta_scale = ((old_state->vupper / old_state->scale) * cur_scale)
- old_state->vupper;
/* Amount of upper change caused by angle */
@@ -229,8 +271,8 @@ gtk_image_view_fix_anchor (GtkImageView *image_view,
double px = anchor_x + hvalue;
double py = anchor_y + vvalue;
- double px_after = (px / old_state->scale) * priv->scale;
- double py_after = (py / old_state->scale) * priv->scale;
+ double px_after = (px / old_state->scale) * cur_scale;
+ double py_after = (py / old_state->scale) * cur_scale;
gtk_adjustment_set_value (priv->hadjustment,
hvalue + px_after - px);
@@ -267,7 +309,8 @@ gtk_image_view_fix_anchor (GtkImageView *image_view,
/* The angle of the anchor point NOW is the old angle plus
* the difference between old surface angle and new surface angle */
- anchor_angle += DEG_TO_RAD (priv->angle - old_state->angle);
+ anchor_angle += DEG_TO_RAD (gtk_image_view_get_real_angle (image_view)
+ - old_state->angle);
/* Calculate the position of the new anchor point, relative
* to the bounding box center */
@@ -308,6 +351,8 @@ gtk_image_view_compute_bounding_box (GtkImageView *image_view,
double upper_right_x, upper_right_y;
double upper_left_x, upper_left_y;
double scale;
+ double angle;
+
if (priv->size_valid)
{
*width = priv->cached_width;
@@ -326,12 +371,13 @@ gtk_image_view_compute_bounding_box (GtkImageView *image_view,
}
gtk_widget_get_allocation (GTK_WIDGET (image_view), &alloc);
+ angle = gtk_image_view_get_real_angle (image_view);
image_width = cairo_image_surface_get_width (priv->image_surface);
image_height = cairo_image_surface_get_height (priv->image_surface);
- upper_right_degrees = DEG_TO_RAD (priv->angle) + atan (image_height / image_width);
- upper_left_degrees = DEG_TO_RAD (priv->angle) + atan (image_height / -image_width);
+ upper_right_degrees = DEG_TO_RAD (angle) + atan (image_height / image_width);
+ upper_left_degrees = DEG_TO_RAD (angle) + atan (image_height / -image_width);
r = sqrt ((image_width / 2.0) * (image_width / 2.0) + (image_height / 2.0) * (image_height / 2.0));
upper_right_x = r * cos (upper_right_degrees);
@@ -343,23 +389,17 @@ gtk_image_view_compute_bounding_box (GtkImageView *image_view,
bb_width = round (MAX (fabs (upper_right_x), fabs (upper_left_x)) * 2.0);
bb_height = round (MAX (fabs (upper_right_y), fabs (upper_left_y)) * 2.0);
- if (priv->scale_set)
+
+ if (priv->fit_allocation)
{
- scale = priv->scale;
+ double scale_x = (double)alloc.width / (double)bb_width;
+ double scale_y = (double)alloc.height / (double)bb_height;
+
+ scale = MIN (MIN (scale_x, scale_y), 1.0);
}
else
{
- if (priv->fit_allocation)
- {
- double scale_x = (double)alloc.width / (double)bb_width;
- double scale_y = (double)alloc.height / (double)bb_height;
-
- scale = MIN (MIN (scale_x, scale_y), 1.0);
- }
- else
- {
- scale = 1.0;
- }
+ scale = gtk_image_view_get_real_scale (image_view);
}
priv->cached_scale = scale;
@@ -528,13 +568,15 @@ gesture_zoom_end_cb (GtkGesture *gesture,
{
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (user_data);
- /* XXX Is this correct? */
- if (priv->zoom_gesture_enabled)
- gtk_image_view_set_scale (user_data, priv->scale);
+ priv->scale = priv->gesture_scale;
+ priv->size_valid = FALSE;
+ g_object_notify_by_pspec (G_OBJECT (user_data),
+ widget_props[PROP_SCALE]);
- priv->gesture_start_scale = 0.0;
- priv->in_zoom = FALSE;
+ gtk_image_view_update_adjustments (user_data);
+ gtk_widget_queue_resize (user_data);
+ priv->in_zoom = FALSE;
priv->anchor_x = -1;
priv->anchor_y = -1;
}
@@ -549,7 +591,6 @@ gesture_zoom_cancel_cb (GtkGesture *gesture,
if (priv->in_zoom)
gtk_image_view_set_scale (user_data, priv->gesture_start_scale);
- priv->gesture_start_scale = 0.0;
priv->in_zoom = FALSE;
priv->anchor_x = -1;
priv->anchor_y = -1;
@@ -574,10 +615,10 @@ gesture_zoom_changed_cb (GtkGestureZoom *gesture,
new_scale = priv->gesture_start_scale * delta;
gtk_image_view_get_current_state (image_view, &state);
- /* Don't emit */
- priv->scale = new_scale;
+ priv->gesture_scale = new_scale;
+ priv->size_valid = FALSE;
- gtk_image_view_set_scale_internal (image_view, new_scale);
+ gtk_image_view_update_adjustments (image_view);
if (priv->hadjustment != NULL && priv->vadjustment != NULL)
{
@@ -586,6 +627,8 @@ gesture_zoom_changed_cb (GtkGestureZoom *gesture,
priv->anchor_y,
&state);
}
+
+ gtk_widget_queue_resize (GTK_WIDGET (image_view));
}
/* }}} */
@@ -617,13 +660,16 @@ gesture_rotate_begin_cb (GtkGesture *gesture,
static void
gesture_rotate_end_cb (GtkGesture *gesture,
GdkEventSequence *sequence,
- gpointer user_data)
+ gpointer image_view)
{
- GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (user_data);
+ GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
- priv->gesture_start_angle = 0.0;
- priv->in_rotate = FALSE;
+ priv->angle = gtk_image_view_clamp_angle (priv->gesture_angle);
+ g_object_notify_by_pspec (image_view,
+ widget_props[PROP_ANGLE]);
+
+ priv->in_rotate = FALSE;
priv->anchor_x = -1;
priv->anchor_y = -1;
}
@@ -631,16 +677,14 @@ gesture_rotate_end_cb (GtkGesture *gesture,
static void
gesture_rotate_cancel_cb (GtkGesture *gesture,
GdkEventSequence *sequence,
- gpointer user_data)
+ gpointer image_view)
{
- GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (user_data);
+ GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
- if (priv->in_rotate)
- gtk_image_view_set_angle (user_data, priv->gesture_start_angle);
+ priv->size_valid = FALSE;
+ gtk_image_view_update_adjustments (image_view);
priv->in_rotate = FALSE;
- priv->gesture_start_angle = 0.0;
-
priv->anchor_x = -1;
priv->anchor_y = -1;
}
@@ -664,15 +708,9 @@ gesture_rotate_changed_cb (GtkGestureRotate *gesture,
new_angle = priv->gesture_start_angle + RAD_TO_DEG (delta);
-
- if (new_angle == priv->angle)
- return;
-
-
gtk_image_view_get_current_state (image_view, &old_state);
- /* Don't notify */
- priv->angle = new_angle;
+ priv->gesture_angle = new_angle;
priv->size_valid = FALSE;
gtk_image_view_update_adjustments (image_view);
@@ -747,6 +785,8 @@ gtk_image_view_init (GtkImageView *image_view)
priv->scale = 1.0;
priv->angle = 0.0;
+ priv->gesture_scale = 1.0;
+ priv->gesture_angle = 0.0;
priv->snap_angle = FALSE;
priv->fit_allocation = FALSE;
priv->scale_set = FALSE;
@@ -966,7 +1006,7 @@ gtk_image_view_draw (GtkWidget *widget, cairo_t *ct)
cairo_translate (ct,
draw_x + (image_width / 2.0),
draw_y + (image_height / 2.0));
- cairo_rotate (ct, DEG_TO_RAD (priv->angle));
+ cairo_rotate (ct, DEG_TO_RAD (gtk_image_view_get_real_angle (image_view)));
cairo_translate (ct,
- draw_x - (image_width / 2.0),
- draw_y - (image_height / 2.0));
@@ -1160,20 +1200,8 @@ gtk_image_view_set_angle (GtkImageView *image_view,
g_return_if_fail (GTK_IS_IMAGE_VIEW (image_view));
-
-
- if (angle > 360.0)
- angle -= (int)(angle / 360.0) * 360;
- else if (angle < 0.0)
- angle = 360.0 + (int)(angle / 360.0);
-
- g_assert (angle >= 0.0);
- g_assert (angle <= 360.0);
-
-
gtk_image_view_get_current_state (image_view, &state);
-
- priv->angle = angle;
+ priv->angle = gtk_image_view_clamp_angle (angle);
/* Setting the angle while fit-allocation is TRUE
* does not invalidate the bounding box size. */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]