[gtk+/wip/baedert/gtkimageview: 17/31] GtkImageView: Replace zoom-mode with fit-allocation
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baedert/gtkimageview: 17/31] GtkImageView: Replace zoom-mode with fit-allocation
- Date: Mon, 10 Aug 2015 04:37:32 +0000 (UTC)
commit 9aff130faa5839249e621ede41693dfc8dc33377
Author: Timm Bäder <mail baedert org>
Date: Tue Jul 7 19:54:19 2015 +0200
GtkImageView: Replace zoom-mode with fit-allocation
demos/gtk-demo/image_view.c | 27 +-----
demos/gtk-demo/image_view.ui | 10 +--
gtk/gtkimageview.c | 228 ++++++++++++++++++++++++------------------
gtk/gtkimageview.h | 20 +---
4 files changed, 141 insertions(+), 144 deletions(-)
---
diff --git a/demos/gtk-demo/image_view.c b/demos/gtk-demo/image_view.c
index 0d6f95c..7fd3af4 100644
--- a/demos/gtk-demo/image_view.c
+++ b/demos/gtk-demo/image_view.c
@@ -37,23 +37,6 @@ load_button_cb ()
}
void
-zoom_mode_changed_cb (GtkComboBox *widget,
- gpointer user_data)
-{
- const gchar *new_id = gtk_combo_box_get_active_id (widget);
-
- if (g_strcmp0 (new_id, "fit") == 0)
- gtk_image_view_set_zoom_mode (GTK_IMAGE_VIEW (image_view),
- GTK_IMAGE_VIEW_ZOOM_MODE_FIT);
- else if (g_strcmp0 (new_id, "original") == 0)
- gtk_image_view_set_zoom_mode (GTK_IMAGE_VIEW (image_view),
- GTK_IMAGE_VIEW_ZOOM_MODE_ORIGINAL);
- else
- g_error (new_id);
-
-}
-
-void
angle_changed_cb (GtkRange *range,
gpointer user_data)
{
@@ -142,8 +125,8 @@ do_image_view (GtkWidget *do_widget)
image_view = GTK_WIDGET (gtk_builder_get_object (builder, "image_view"));
uri_entry = GTK_WIDGET (gtk_builder_get_object (builder, "uri_entry"));
GtkWidget *box = GTK_WIDGET (gtk_builder_get_object (builder, "box"));
- GtkWidget *zoom_mode_combo = GTK_WIDGET (gtk_builder_get_object (builder, "zoom_mode_combo"));
GtkWidget *snap_angle_button = GTK_WIDGET (gtk_builder_get_object (builder, "snap_angle_check_button"));
+ GtkWidget *fit_allocation_button = GTK_WIDGET (gtk_builder_get_object (builder,
"fit_allocation_check_button"));
GtkWidget *header_bar = gtk_header_bar_new ();
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (header_bar), TRUE);
gtk_window_set_titlebar (GTK_WINDOW (window), header_bar);
@@ -157,14 +140,10 @@ do_image_view (GtkWidget *do_widget)
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
g_object_bind_property (image_view, "snap-angle", snap_angle_button, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+ g_object_bind_property (image_view, "fit-allocation", fit_allocation_button, "active",
+ G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-
- if (gtk_image_view_get_zoom_mode (GTK_IMAGE_VIEW (image_view)) == GTK_IMAGE_VIEW_ZOOM_MODE_FIT)
- gtk_combo_box_set_active_id (GTK_COMBO_BOX (zoom_mode_combo), "fit");
- else if (gtk_image_view_get_zoom_mode (GTK_IMAGE_VIEW (image_view)) == GTK_IMAGE_VIEW_ZOOM_MODE_ORIGINAL)
- gtk_combo_box_set_active_id (GTK_COMBO_BOX (zoom_mode_combo), "original");
-
gtk_container_add (GTK_CONTAINER (window), box);
gtk_builder_connect_signals (builder, NULL);
diff --git a/demos/gtk-demo/image_view.ui b/demos/gtk-demo/image_view.ui
index 99233c7..28df6df 100644
--- a/demos/gtk-demo/image_view.ui
+++ b/demos/gtk-demo/image_view.ui
@@ -67,15 +67,9 @@
<child>
- <object class="GtkComboBoxText" id="zoom_mode_combo">
+ <object class="GtkCheckButton" id="fit_allocation_check_button">
<property name="visible">true</property>
- <signal name="changed" handler="zoom_mode_changed_cb" />
-
- <items>
- <item id="fit">ZOOM_MODE_FIT</item>
- <item id="original">ZOOM_MODE_ORIGINAL</item>
- </items>
-
+ <property name="label" translatable="yes">Fit Allocation</property>
</object>
<packing>
<property name="left_attach">0</property>
diff --git a/gtk/gtkimageview.c b/gtk/gtkimageview.c
index 5c4865c..849b687 100644
--- a/gtk/gtkimageview.c
+++ b/gtk/gtkimageview.c
@@ -22,14 +22,13 @@
#define TRANSITION_DURATION (200.0 * 1000.0)
-
-
struct _GtkImageViewPrivate
{
double scale;
double angle;
- int zoom_mode;
gboolean snap_angle;
+ gboolean fit_allocation;
+ gboolean scale_set;
GtkGesture *rotate_gesture;
GtkGesture *zoom_gesture;
@@ -58,11 +57,12 @@ struct _GtkImageViewPrivate
enum
{
PROP_SCALE = 1,
+ PROP_SCALE_SET,
PROP_ANGLE,
- PROP_ZOOM_MODE,
PROP_ROTATE_ENABLED,
PROP_ZOOM_ENABLED,
PROP_SNAP_ANGLE,
+ PROP_FIT_ALLOCATION,
LAST_WIDGET_PROPERTY,
PROP_HADJUSTMENT,
PROP_VADJUSTMENT,
@@ -97,7 +97,8 @@ gtk_image_view_init (GtkImageView *image_view)
priv->scale = 1.0;
priv->angle = 0.0;
priv->snap_angle = FALSE;
- priv->zoom_mode = GTK_IMAGE_VIEW_ZOOM_MODE_FIT;
+ priv->fit_allocation = FALSE;
+ priv->scale_set = FALSE;
priv->rotate_gesture = gtk_gesture_rotate_new ((GtkWidget *)image_view);
priv->zoom_gesture = gtk_gesture_zoom_new ((GtkWidget *)image_view);
@@ -223,15 +224,20 @@ static void
gtk_image_view_compute_bounding_box (GtkImageView *image_view,
int *width,
int *height,
- double *scale)
+ double *scale_out)
{
- // XXX Rework this to have less code duplication
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
GtkAllocation alloc;
int image_width;
int image_height;
int bb_width = 0;
int bb_height = 0;
+ double upper_right_degrees;
+ double upper_left_degrees;
+ double r;
+ int upper_right_x, upper_right_y;
+ int upper_left_x, upper_left_y;
+ double scale;
if (!priv->image_surface)
@@ -245,59 +251,61 @@ gtk_image_view_compute_bounding_box (GtkImageView *image_view,
image_width = cairo_image_surface_get_width (priv->image_surface);
image_height = cairo_image_surface_get_height (priv->image_surface);
- if (priv->zoom_mode == GTK_IMAGE_VIEW_ZOOM_MODE_FIT ||
- priv->zoom_mode == GTK_IMAGE_VIEW_ZOOM_MODE_ORIGINAL)
- {
- int final_width = image_width;
- int final_height = image_height;
+ upper_right_degrees = DEG_TO_RAD (priv->angle) + atan ((double)image_height / (double)image_width);
+ upper_left_degrees = DEG_TO_RAD (priv->angle) + atan ((double)image_height / -(double)image_width);
+ r = sqrtf ((image_width / 2) * (image_width / 2) + (image_height / 2) * (image_height / 2));
- double upper_right_degrees = DEG_TO_RAD (priv->angle) + atan ((double)final_height /
(double)final_width);
- double upper_left_degrees = DEG_TO_RAD (priv->angle) + atan ((double)final_height /
-(double)final_width);
- double r = sqrtf ((final_width / 2) * (final_width / 2) + (final_height / 2) * (final_height / 2));
+ upper_right_x = r * cos (upper_right_degrees);
+ upper_right_y = r * sin (upper_right_degrees);
- int upper_right_x = r * cos (upper_right_degrees);
- int upper_right_y = r * sin (upper_right_degrees);
+ upper_left_x = r * cos (upper_left_degrees);
+ upper_left_y = r * sin (upper_left_degrees);
- int upper_left_x = r * cos (upper_left_degrees);
- int upper_left_y = r * sin (upper_left_degrees);
+ //
+ bb_width = MAX (fabs (upper_right_x), fabs (upper_left_x)) * 2;
+ bb_height = MAX (fabs (upper_right_y), fabs (upper_left_y)) * 2;
- //
- bb_width = MAX (fabs (upper_right_x), fabs (upper_left_x)) * 2;
- bb_height = MAX (fabs (upper_right_y), fabs (upper_left_y)) * 2;
+ if (!priv->scale_set)
+ {
double scale_x = (double)alloc.width / (double)bb_width;
double scale_y = (double)alloc.height / (double)bb_height;
- if (scale)
- *scale = MIN (MIN (scale_x, scale_y), 1.0);
+ scale = MIN (MIN (scale_x, scale_y), 1.0);
+ }
+ else
+ scale = priv->scale;
+
+
+ if (scale_out)
+ {
+ // XXX Care about scale_set
+ *scale_out = scale;
+ }
- priv->scale = *scale;
+ if (priv->fit_allocation)
+ {
+ priv->scale = scale;
g_object_notify_by_pspec ((GObject *)image_view,
widget_props[PROP_SCALE]);
- if (priv->zoom_mode == GTK_IMAGE_VIEW_ZOOM_MODE_FIT)
+ *width = bb_width * scale;
+ *height = bb_height * scale;
+ }
+ else
+ {
+ if (priv->scale_set)
{
- *width = bb_width * *scale;
- *height = bb_height * *scale;
+ *width = bb_width * scale;
+ *height = bb_height * scale;
}
- else if (priv->zoom_mode == GTK_IMAGE_VIEW_ZOOM_MODE_ORIGINAL)
+ else
{
- *width = bb_width * *scale;
- *height = bb_height * *scale;
+ *width = bb_width;
+ *height = bb_height;
}
-
- return;
}
- else
- {
- }
-
- *width = image_width;
- *height = image_height;
-
- if (scale)
- *scale = 1.0;
}
static void
@@ -317,8 +325,12 @@ gtk_image_view_update_adjustments (GtkImageView *image_view)
-
- if (priv->zoom_mode == GTK_IMAGE_VIEW_ZOOM_MODE_ORIGINAL)
+ if (priv->fit_allocation)
+ {
+ gtk_adjustment_set_upper (priv->vadjustment, 0);
+ gtk_adjustment_set_upper (priv->hadjustment, 0);
+ }
+ else
{
int width, height;
gtk_image_view_compute_bounding_box (image_view,
@@ -327,16 +339,10 @@ gtk_image_view_update_adjustments (GtkImageView *image_view)
NULL);
gtk_adjustment_set_upper (priv->hadjustment, width);
gtk_adjustment_set_upper (priv->vadjustment, height);
- }
- else if (priv->zoom_mode == GTK_IMAGE_VIEW_ZOOM_MODE_FIT)
- {
- gtk_adjustment_set_upper (priv->vadjustment,
- gtk_widget_get_allocated_width ((GtkWidget *)image_view));
- gtk_adjustment_set_upper (priv->hadjustment,
- gtk_widget_get_allocated_height((GtkWidget *)image_view));
}
+
gtk_adjustment_set_page_size (priv->hadjustment,
gtk_widget_get_allocated_width ((GtkWidget *)image_view));
gtk_adjustment_set_page_size (priv->vadjustment,
@@ -407,8 +413,6 @@ gtk_image_view_draw (GtkWidget *widget, cairo_t *ct)
draw_y = (alloc.height - image_height) / 2;
- /*cairo_rectangle (ct, draw_x, draw_y, draw_width, draw_height);*/
-
/* Rotate around the center */
cairo_translate (ct, draw_x + (image_width / 2.0), draw_y + (image_height / 2.0));
cairo_rotate (ct, DEG_TO_RAD (priv->angle));
@@ -489,12 +493,20 @@ gtk_image_view_set_scale (GtkImageView *image_view,
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
g_return_if_fail (GTK_IS_IMAGE_VIEW (image_view));
- /*g_message ("Want to set new scale: %f", scale);*/
-
priv->scale = scale;
- /*gtk_image_view_set_zoom_mode (image_view, GTK_IMAGE_VIEW_ZOOM_MODE_NONE);*/
g_object_notify_by_pspec ((GObject *)image_view,
widget_props[PROP_SCALE]);
+ priv->scale_set = TRUE;
+ g_object_notify_by_pspec ((GObject *)image_view,
+ widget_props[PROP_SCALE_SET]);
+
+ if (priv->fit_allocation)
+ {
+ priv->fit_allocation = FALSE;
+ g_object_notify_by_pspec ((GObject *)image_view,
+ widget_props[PROP_SCALE_SET]);
+ }
+
gtk_widget_queue_resize ((GtkWidget *)image_view);
}
@@ -524,6 +536,7 @@ gtk_image_view_set_angle (GtkImageView *image_view,
g_object_notify_by_pspec ((GObject *)image_view,
widget_props[PROP_ANGLE]);
+ gtk_widget_queue_draw ((GtkWidget *)image_view);
gtk_widget_queue_resize ((GtkWidget *)image_view);
}
@@ -539,63 +552,74 @@ gtk_image_view_get_angle (GtkImageView *image_view)
void
-gtk_image_view_set_zoom_mode (GtkImageView *image_view,
- GtkImageViewZoomMode zoom_mode)
+gtk_image_view_set_snap_angle (GtkImageView *image_view,
+ gboolean snap_angle)
{
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
g_return_if_fail (GTK_IS_IMAGE_VIEW (image_view));
- if (priv->zoom_mode == zoom_mode)
+ snap_angle = !!snap_angle;
+
+ if (snap_angle == priv->snap_angle)
return;
- priv->zoom_mode = zoom_mode;
+ priv->snap_angle = snap_angle;
g_object_notify_by_pspec ((GObject *)image_view,
- widget_props[PROP_ANGLE]);
+ widget_props[PROP_SNAP_ANGLE]);
- gtk_widget_queue_resize ((GtkWidget *)image_view);
+ if (priv->snap_angle)
+ gtk_image_view_do_snapping (image_view, priv->angle);
}
-GtkImageViewZoomMode
-gtk_image_view_get_zoom_mode (GtkImageView *image_view)
+gboolean
+gtk_image_view_get_snap_angle (GtkImageView *image_view)
{
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
g_return_if_fail (GTK_IS_IMAGE_VIEW (image_view));
- return priv->zoom_mode;
+ return priv->snap_angle;
}
void
-gtk_image_view_set_snap_angle (GtkImageView *image_view,
- gboolean snap_angle)
+gtk_image_view_set_fit_allocation (GtkImageView *image_view,
+ gboolean fit_allocation)
{
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
g_return_if_fail (GTK_IS_IMAGE_VIEW (image_view));
- snap_angle = !!snap_angle;
+ fit_allocation = !!fit_allocation;
- if (snap_angle == priv->snap_angle)
+ if (fit_allocation == priv->fit_allocation)
return;
- priv->snap_angle = snap_angle;
+ priv->fit_allocation = fit_allocation;
g_object_notify_by_pspec ((GObject *)image_view,
- widget_props[PROP_SNAP_ANGLE]);
+ widget_props[PROP_FIT_ALLOCATION]);
- if (priv->snap_angle)
- gtk_image_view_do_snapping (image_view, priv->angle);
+ priv->scale_set = FALSE;
+ g_object_notify_by_pspec ((GObject *)image_view,
+ widget_props[PROP_SCALE_SET]);
+
+ if (!priv->fit_allocation && !priv->scale_set)
+ {
+ priv->scale = 1.0;
+ g_object_notify_by_pspec ((GObject *)image_view,
+ widget_props[PROP_SCALE]);
+ }
+
+ gtk_widget_queue_resize ((GtkWidget *)image_view);
}
gboolean
-gtk_image_view_get_snap_angle (GtkImageView *image_view)
+gtk_image_view_get_fit_allocation (GtkImageView *image_view)
{
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
g_return_if_fail (GTK_IS_IMAGE_VIEW (image_view));
- return priv->snap_angle;
+ return priv->fit_allocation;
}
-
-
/* }}} */
@@ -617,8 +641,11 @@ gtk_image_view_realize (GtkWidget *widget)
attributes.height = allocation.height;
attributes.window_type = GDK_WINDOW_CHILD;
attributes.event_mask = gtk_widget_get_events (widget) |
- GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK |
- GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_SMOOTH_SCROLL_MASK |
+ GDK_SCROLL_MASK;
attributes.wclass = GDK_INPUT_OUTPUT;
window = gdk_window_new (gtk_widget_get_parent_window (widget),
@@ -663,14 +690,13 @@ gtk_image_view_get_preferred_height (GtkWidget *widget,
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
int width, height;
- double scale;
gtk_image_view_compute_bounding_box (image_view,
&width,
&height,
- &scale);
+ NULL);
- if (priv->zoom_mode == GTK_IMAGE_VIEW_ZOOM_MODE_FIT)
+ if (priv->fit_allocation)
{
*minimal = 0;
*natural = height;
@@ -690,13 +716,12 @@ gtk_image_view_get_preferred_width (GtkWidget *widget,
GtkImageView *image_view = (GtkImageView *)widget;
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
int width, height;
- double scale;
gtk_image_view_compute_bounding_box (image_view,
&width,
&height,
- &scale);
+ NULL);
- if (priv->zoom_mode == GTK_IMAGE_VIEW_ZOOM_MODE_FIT)
+ if (priv->fit_allocation)
{
*minimal = 0;
*natural = width;
@@ -729,12 +754,12 @@ gtk_image_view_set_property (GObject *object,
case PROP_ANGLE:
gtk_image_view_set_angle (image_view, g_value_get_double (value));
break;
- case PROP_ZOOM_MODE:
- gtk_image_view_set_zoom_mode (image_view, g_value_get_enum (value));
- break;
case PROP_SNAP_ANGLE:
gtk_image_view_set_snap_angle (image_view, g_value_get_boolean (value));
break;
+ case PROP_FIT_ALLOCATION:
+ gtk_image_view_set_fit_allocation (image_view, g_value_get_boolean (value));
+ break;
case PROP_HADJUSTMENT:
gtk_image_view_set_hadjustment (image_view, g_value_get_object (value));
break;
@@ -769,12 +794,12 @@ gtk_image_view_get_property (GObject *object,
case PROP_ANGLE:
g_value_set_double (value, priv->angle);
break;
- case PROP_ZOOM_MODE:
- g_value_set_enum (value, priv->zoom_mode);
- break;
case PROP_SNAP_ANGLE:
g_value_set_boolean (value, priv->snap_angle);
break;
+ case PROP_FIT_ALLOCATION:
+ g_value_set_boolean (value, priv->fit_allocation);
+ break;
case PROP_HADJUSTMENT:
g_value_set_object (value, priv->hadjustment);
break;
@@ -840,6 +865,12 @@ gtk_image_view_class_init (GtkImageViewClass *view_class)
0.0,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+ widget_props[PROP_SCALE_SET] = g_param_spec_boolean ("scale-set",
+ P_("Foo"),
+ P_("fooar"),
+ TRUE,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+
widget_props[PROP_ANGLE] = g_param_spec_double ("angle",
P_("angle"),
P_("angle"),
@@ -848,13 +879,6 @@ gtk_image_view_class_init (GtkImageViewClass *view_class)
0.0,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
- widget_props[PROP_ZOOM_MODE] = g_param_spec_enum("zoom-mode",
- P_("zoom mode"),
- P_("zoommode"),
- GTK_TYPE_IMAGE_VIEW_ZOOM_MODE,
- GTK_IMAGE_VIEW_ZOOM_MODE_NONE,
- GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
-
widget_props[PROP_ROTATE_ENABLED] = g_param_spec_boolean ("rotate-gesture-enabled",
P_("Foo"),
P_("fooar"),
@@ -873,6 +897,14 @@ gtk_image_view_class_init (GtkImageViewClass *view_class)
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+ widget_props[PROP_FIT_ALLOCATION] = g_param_spec_boolean ("fit-allocation",
+ P_("Foo"),
+ P_("fooar"),
+ FALSE,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+
+
+
widget_signals[PREPARE_IMAGE] = g_signal_new (I_("prepare-image"),
G_TYPE_FROM_CLASS (object_class),
diff --git a/gtk/gtkimageview.h b/gtk/gtkimageview.h
index bcc3109..f3caf13 100644
--- a/gtk/gtkimageview.h
+++ b/gtk/gtkimageview.h
@@ -35,13 +35,6 @@ struct _GtkImageViewClass
void (* prepare_image) (cairo_surface_t *image);
};
-typedef enum
-{
- GTK_IMAGE_VIEW_ZOOM_MODE_ORIGINAL,
- GTK_IMAGE_VIEW_ZOOM_MODE_FIT,
- GTK_IMAGE_VIEW_ZOOM_MODE_NONE
-} GtkImageViewZoomMode;
-
GDK_AVAILABLE_IN_3_18
GType gtk_image_view_get_type (void) G_GNUC_CONST;
@@ -90,21 +83,20 @@ double gtk_image_view_get_angle (GtkImageView *image_view);
GDK_AVAILABLE_IN_3_18
-void gtk_image_view_set_zoom_mode (GtkImageView *image_view,
- GtkImageViewZoomMode zoom_mode);
+gboolean gtk_image_get_view_snap_angle (GtkImageView *image_view);
GDK_AVAILABLE_IN_3_18
-GtkImageViewZoomMode gtk_image_view_get_zoom_mode (GtkImageView *image_view);
+void gtk_image_view_set_snap_angle (GtkImageView *image_view,
+ gboolean snap_rotation);
GDK_AVAILABLE_IN_3_18
-gboolean gtk_image_view_snap_angle (GtkImageView *image_view);
+gboolean gtk_image_view_get_fit_allocation (GtkImageView *image_view);
GDK_AVAILABLE_IN_3_18
-void gtk_image_view_set_snap_angle (GtkImageView *image_view,
- gboolean snap_rotation);
-
+void gtk_image_view_set_fit_allocation (GtkImageView *image_view,
+ gboolean fit_allocation);
// XXX Adding a gtk_image_view_set_pixbuf would work, but we are working with animations internally...
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]