[gtk+/wip/baedert/gtkimageview: 21/31] GtkImageView: Add scale arguments to load functions
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baedert/gtkimageview: 21/31] GtkImageView: Add scale arguments to load functions
- Date: Mon, 10 Aug 2015 04:37:52 +0000 (UTC)
commit ed7f1de9d1883f59899aa6197abe8536d615e5ed
Author: Timm Bäder <mail baedert org>
Date: Mon Jul 13 12:27:31 2015 +0200
GtkImageView: Add scale arguments to load functions
demos/gtk-demo/image_view.c | 4 +-
demos/gtk-demo/image_view.ui | 27 ++++++--
gtk/gtkimageview.c | 150 ++++++++++++++++++++++++++++++++---------
gtk/gtkimageview.h | 7 ++-
4 files changed, 145 insertions(+), 43 deletions(-)
---
diff --git a/demos/gtk-demo/image_view.c b/demos/gtk-demo/image_view.c
index 815d473..332e13e 100644
--- a/demos/gtk-demo/image_view.c
+++ b/demos/gtk-demo/image_view.c
@@ -19,6 +19,7 @@ file_set_cb (GtkFileChooserButton *widget,
GFile *file = g_file_new_for_path (filename);
gtk_image_view_load_from_file_async (GTK_IMAGE_VIEW (image_view),
file,
+ 1,
NULL,
generic_cb,
NULL);
@@ -31,6 +32,7 @@ load_button_cb ()
GFile *file = g_file_new_for_uri (uri);
gtk_image_view_load_from_file_async (GTK_IMAGE_VIEW (image_view),
file,
+ 1,
NULL,
generic_cb,
NULL);
@@ -125,7 +127,7 @@ load_pixbuf_button_clicked_cb ()
NULL);
g_assert (pixbuf != NULL);
- gtk_image_view_set_pixbuf (GTK_IMAGE_VIEW (image_view), pixbuf);
+ gtk_image_view_set_pixbuf (GTK_IMAGE_VIEW (image_view), pixbuf, 1);
}
diff --git a/demos/gtk-demo/image_view.ui b/demos/gtk-demo/image_view.ui
index 640d8e4..8945697 100644
--- a/demos/gtk-demo/image_view.ui
+++ b/demos/gtk-demo/image_view.ui
@@ -107,6 +107,20 @@
+
+ <child>
+ <object class="GtkCheckButton">
+ <property name="visible">true</property>
+ <property name="label" translatable="yes">Draw on Surface</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+
+
<child>
<object class="GtkLabel">
<property name="visible">true</property>
@@ -116,7 +130,7 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">5</property>
+ <property name="top_attach">6</property>
<property name="width">2</property>
</packing>
</child>
@@ -129,12 +143,11 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">6</property>
+ <property name="top_attach">7</property>
<property name="width">2</property>
</packing>
</child>
-
<child>
<object class="GtkScale" id="angle_scale">
<property name="visible">true</property>
@@ -144,7 +157,7 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">7</property>
+ <property name="top_attach">8</property>
<property name="width">2</property>
</packing>
</child>
@@ -187,7 +200,7 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">8</property>
+ <property name="top_attach">9</property>
<property name="width">2</property>
</packing>
</child>
@@ -202,7 +215,7 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">9</property>
+ <property name="top_attach">10</property>
<property name="width">2</property>
</packing>
</child>
@@ -216,7 +229,7 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">10</property>
+ <property name="top_attach">11</property>
<property name="width">2</property>
</packing>
</child>
diff --git a/gtk/gtkimageview.c b/gtk/gtkimageview.c
index 4fbcfc6..de78db4 100644
--- a/gtk/gtkimageview.c
+++ b/gtk/gtkimageview.c
@@ -29,6 +29,7 @@ struct _GtkImageViewPrivate
gboolean snap_angle;
gboolean fit_allocation;
gboolean scale_set;
+ int scale_factor;
gboolean rotate_gesture_enabled;
gboolean zoom_gesture_enabled;
@@ -95,6 +96,22 @@ G_DEFINE_TYPE_WITH_CODE (GtkImageView, gtk_image_view, GTK_TYPE_WIDGET,
G_ADD_PRIVATE (GtkImageView)
G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
+typedef struct _LoadTaskData LoadTaskData;
+
+
+// @ask How to solve this more elegantly?
+struct _LoadTaskData
+{
+ int scale_factor;
+ gpointer source;
+};
+
+static void
+free_load_task_data (LoadTaskData *data)
+{
+ g_clear_object ((&data->source));
+}
+
static void
gtk_image_view_init (GtkImageView *image_view)
@@ -119,7 +136,8 @@ gtk_image_view_init (GtkImageView *image_view)
/* Prototypes {{{ */
static void gtk_image_view_update_surface (GtkImageView *image_view,
- const GdkPixbuf *frame);
+ const GdkPixbuf *frame,
+ int scale_factor);
static void adjustment_value_changed_cb (GtkAdjustment *adjustment,
gpointer user_data);
@@ -150,7 +168,8 @@ gtk_image_view_update_animation (gpointer user_data)
gdk_pixbuf_animation_iter_advance (priv->source_animation_iter, NULL);
gtk_image_view_update_surface (image_view,
- gtk_image_view_get_current_frame (image_view));
+ gtk_image_view_get_current_frame (image_view),
+ priv->scale_factor);
return priv->is_animation;
}
@@ -278,8 +297,8 @@ gtk_image_view_compute_bounding_box (GtkImageView *image_view,
}
gtk_widget_get_allocation ((GtkWidget *)image_view, &alloc);
- image_width = cairo_image_surface_get_width (priv->image_surface);
- image_height = cairo_image_surface_get_height (priv->image_surface);
+ image_width = priv->surface_width;
+ image_height = priv->surface_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);
@@ -305,7 +324,9 @@ gtk_image_view_compute_bounding_box (GtkImageView *image_view,
scale = MIN (MIN (scale_x, scale_y), 1.0);
}
else
- scale = priv->scale;
+ {
+ scale = priv->scale;
+ }
if (scale_out)
*scale_out = scale;
@@ -406,23 +427,55 @@ gtk_image_view_draw (GtkWidget *widget, cairo_t *ct)
draw_x = (alloc.width - draw_width) / 2;
draw_y = (alloc.height - draw_height) / 2;
+
+#if 1
+ {
+ cairo_save (ct);
+ cairo_set_source_rgba (ct, 0.7, 0.7, 0.7, 1);
+ cairo_rectangle (ct, (alloc.width - draw_width) / 2, (alloc.height - draw_height) / 2, draw_width,
draw_height);
+ cairo_fill (ct);
+ cairo_set_source_rgba (ct, 0, 0, 0, 1);
+ cairo_rectangle (ct, (alloc.width - draw_width) / 2, (alloc.height - draw_height) / 2, draw_width,
draw_height);
+ cairo_stroke (ct);
+ cairo_restore (ct);
+ }
+
+ {
+ /*cairo_save (ct);*/
+ /*cairo_set_source_rgba (ct, 1, 0, 0, 1);*/
+ /*cairo_rectangle (ct, ((alloc.width - image_width) / 2) / scale,*/
+ /*((alloc.height - image_height) / 2) / scale,*/
+ /*cairo_image_surface_get_width (priv->image_surface),*/
+ /*cairo_image_surface_get_height (priv->image_surface));*/
+ /*cairo_stroke (ct);*/
+ /*cairo_restore (ct);*/
+ }
+#endif
+
+
+
+
cairo_save (ct);
cairo_rectangle (ct, draw_x, draw_y, draw_width, draw_height);
/* Handle the h/vadjustments, but keep the image centered in all cases */
- if (priv->hadjustment &&
- gtk_adjustment_get_page_size (priv->hadjustment) < draw_width)
- draw_x = -gtk_adjustment_get_value (priv->hadjustment);
- else
+
+ /*if (priv->hadjustment &&*/
+ /*gtk_adjustment_get_page_size (priv->hadjustment) < draw_width)*/
+ /*draw_x = -gtk_adjustment_get_value (priv->hadjustment);*/
+ /*else*/
draw_x = (alloc.width - image_width) / 2;
- if (priv->vadjustment &&
- gtk_widget_get_allocated_height (widget) < draw_height)
- draw_y = -gtk_adjustment_get_value (priv->vadjustment);
- else
+ /*if (priv->vadjustment &&*/
+ /*gtk_widget_get_allocated_height (widget) < draw_height)*/
+ /*draw_y = -gtk_adjustment_get_value (priv->vadjustment);*/
+ /*else*/
draw_y = (alloc.height - image_height) / 2;
+ if (priv->vadjustment)
+ draw_y -= gtk_adjustment_get_value (priv->vadjustment);
+
/* Rotate around the center */
@@ -1039,26 +1092,36 @@ gtk_image_view_new ()
static void
gtk_image_view_update_surface (GtkImageView *image_view,
- const GdkPixbuf *frame)
+ const GdkPixbuf *frame,
+ int scale_factor)
{
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
- int new_width = gdk_pixbuf_get_width (frame);
- int new_height = gdk_pixbuf_get_height (frame);
- gboolean resize = TRUE;
+ int new_width = gdk_pixbuf_get_width (frame);
+ int new_height = gdk_pixbuf_get_height (frame);
+ int widget_scale = gtk_widget_get_scale_factor ((GtkWidget *)image_view);
+ gboolean resize = TRUE;
+ int real_width = (new_width * scale_factor) / widget_scale;
+ int real_height = (new_height * scale_factor) / widget_scale;
if (!priv->image_surface ||
- priv->surface_width != new_width ||
- priv->surface_height != new_height)
+ priv->surface_width != real_width ||
+ priv->surface_height != real_height)
{
+ GdkWindow *window = gtk_widget_get_window ((GtkWidget *)image_view);
+ int surface_scale = gtk_widget_get_scale_factor ((GtkWidget *)image_view);
+
if (priv->image_surface)
cairo_surface_destroy (priv->image_surface);
+ priv->scale_factor = scale_factor;
priv->image_surface = gdk_cairo_surface_create_from_pixbuf (frame,
- 1,
- gtk_widget_get_window ((GtkWidget
*)image_view));
+ surface_scale,
+ window);
+
+
cairo_surface_reference (priv->image_surface);
- priv->surface_width = new_width;
- priv->surface_height = new_height;
+ priv->surface_width = real_width;
+ priv->surface_height = real_height;
}
else
{
@@ -1072,13 +1135,14 @@ gtk_image_view_update_surface (GtkImageView *image_view,
if (resize)
gtk_widget_queue_resize ((GtkWidget *)image_view);
else
- gtk_widget_queue_resize ((GtkWidget *)image_view);
+ gtk_widget_queue_draw ((GtkWidget *)image_view);
}
static void
gtk_image_view_load_image_from_stream (GtkImageView *image_view,
GInputStream *input_stream,
+ int scale_factor,
GCancellable *cancellable,
GError *error)
{
@@ -1114,14 +1178,16 @@ gtk_image_view_load_image_from_stream (GtkImageView *image_view,
priv->source_animation_iter = gdk_pixbuf_animation_get_iter (priv->source_animation,
NULL);
gtk_image_view_update_surface (image_view,
- gtk_image_view_get_current_frame (image_view));
+ gtk_image_view_get_current_frame (image_view),
+ scale_factor);
gtk_image_view_start_animation (image_view);
}
else
{
gtk_image_view_update_surface (image_view,
- gdk_pixbuf_animation_get_static_image (result));
+ gdk_pixbuf_animation_get_static_image (result),
+ scale_factor);
}
}
}
@@ -1133,7 +1199,8 @@ gtk_image_view_load_image_contents (GTask *task,
GCancellable *cancellable)
{
GtkImageView *image_view = source_object;
- GFile *file = task_data;
+ LoadTaskData *data = task_data;
+ GFile *file = (GFile *)data->source;
GError *error = NULL;
GFileInputStream *in_stream;
@@ -1142,13 +1209,13 @@ gtk_image_view_load_image_contents (GTask *task,
if (error)
{
g_task_return_error (task, error);
- g_message ("g_file_read error: %s", error->message);
return;
}
gtk_image_view_load_image_from_stream (image_view,
G_INPUT_STREAM (in_stream),
+ data->scale_factor,
cancellable,
error);
@@ -1163,11 +1230,13 @@ gtk_image_view_load_from_input_stream (GTask *task,
GCancellable *cancellable)
{
GtkImageView *image_view = source_object;
- GInputStream *in_stream = task_data;
+ LoadTaskData *data = task_data;
+ GInputStream *in_stream = (GInputStream *)data->source;
GError *error = NULL;
gtk_image_view_load_image_from_stream (image_view,
in_stream,
+ data->scale_factor,
cancellable,
error);
@@ -1180,16 +1249,23 @@ gtk_image_view_load_from_input_stream (GTask *task,
void
gtk_image_view_load_from_file_async (GtkImageView *image_view,
GFile *file,
+ int scale_factor,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
+ LoadTaskData *task_data;
g_return_if_fail (GTK_IS_IMAGE_VIEW (image_view));
g_return_if_fail (G_IS_FILE (file));
+ g_return_if_fail (scale_factor > 0);
+
+ task_data = g_slice_new (LoadTaskData);
+ task_data->scale_factor = scale_factor;
+ task_data->source = file;
task = g_task_new (image_view, cancellable, callback, user_data);
- g_task_set_task_data (task, file, (GDestroyNotify)g_object_unref);
+ g_task_set_task_data (task, task_data, (GDestroyNotify)free_load_task_data);
g_task_run_in_thread (task, gtk_image_view_load_image_contents);
g_object_unref (task);
@@ -1208,16 +1284,23 @@ gtk_image_view_load_from_file_finish (GtkImageView *image_view,
void
gtk_image_view_load_from_stream_async (GtkImageView *image_view,
GInputStream *input_stream,
+ int scale_factor,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
+ LoadTaskData *task_data;
g_return_if_fail (GTK_IS_IMAGE_VIEW (image_view));
g_return_if_fail (G_IS_INPUT_STREAM (input_stream));
+ g_return_if_fail (scale_factor > 0);
+
+ task_data = g_slice_new (LoadTaskData);
+ task_data->scale_factor = scale_factor;
+ task_data->source = input_stream;
task = g_task_new (image_view, cancellable, callback, user_data);
- g_task_set_task_data (task, input_stream, (GDestroyNotify)g_object_unref);
+ g_task_set_task_data (task, task_data, (GDestroyNotify)free_load_task_data);
g_task_run_in_thread (task, gtk_image_view_load_from_input_stream);
g_object_unref (task);
@@ -1234,11 +1317,12 @@ gtk_image_view_load_from_stream_finish (GtkImageView *image_view,
void
gtk_image_view_set_pixbuf (GtkImageView *image_view,
- const GdkPixbuf *pixbuf)
+ const GdkPixbuf *pixbuf,
+ int scale_factor)
{
g_return_if_fail (GTK_IS_IMAGE_VIEW (image_view));
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
- gtk_image_view_update_surface (image_view, pixbuf);
+ gtk_image_view_update_surface (image_view, pixbuf, scale_factor);
}
diff --git a/gtk/gtkimageview.h b/gtk/gtkimageview.h
index cacf8c7..9d8888e 100644
--- a/gtk/gtkimageview.h
+++ b/gtk/gtkimageview.h
@@ -45,7 +45,8 @@ GtkWidget * gtk_image_view_new ();
GDK_AVAILABLE_IN_3_18
void gtk_image_view_set_pixbuf (GtkImageView *image_view,
- const GdkPixbuf *pixbuf);
+ const GdkPixbuf *pixbuf,
+ int scale_factor);
/* Loading {{{ */
@@ -53,6 +54,7 @@ void gtk_image_view_set_pixbuf (GtkImageView *image_view,
GDK_AVAILABLE_IN_3_18
void gtk_image_view_load_from_file_async (GtkImageView *image_view,
GFile *file,
+ int scale_factor,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -63,6 +65,7 @@ void gtk_image_view_load_from_file_finish (GtkImageView *image_view,
GDK_AVAILABLE_IN_3_18
void gtk_image_view_load_from_stream_async (GtkImageView *image_view,
GInputStream *input_stream,
+ int scale_factor,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -95,7 +98,7 @@ double gtk_image_view_get_angle (GtkImageView *image_view);
GDK_AVAILABLE_IN_3_18
void gtk_image_view_set_snap_angle (GtkImageView *image_view,
- gboolean snap_rotation);
+ gboolean snap_angle);
GDK_AVAILABLE_IN_3_18
gboolean gtk_image_get_view_snap_angle (GtkImageView *image_view);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]