[gtk+/wip/baedert/gtkimageview: 99/103] GtkImageView: Add _set_pixbuf
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baedert/gtkimageview: 99/103] GtkImageView: Add _set_pixbuf
- Date: Sat, 18 Jul 2015 16:58:26 +0000 (UTC)
commit 733d3e56885dcd6db3b21a8f8c47a52c9fc62e03
Author: Timm Bäder <mail baedert org>
Date: Fri Jul 10 11:13:06 2015 +0200
GtkImageView: Add _set_pixbuf
... and user another cairo pattern filter, etc.
demos/gtk-demo/image_view.c | 13 +++++
demos/gtk-demo/image_view.ui | 32 ++++++++----
gtk/gtkimageview.c | 111 ++++++++++++++++++++++++++++-------------
gtk/gtkimageview.h | 11 +++-
4 files changed, 119 insertions(+), 48 deletions(-)
---
diff --git a/demos/gtk-demo/image_view.c b/demos/gtk-demo/image_view.c
index 7fd3af4..815d473 100644
--- a/demos/gtk-demo/image_view.c
+++ b/demos/gtk-demo/image_view.c
@@ -115,6 +115,19 @@ scale_scale_format_value_cb (GtkScale *scale,
}
+void
+load_pixbuf_button_clicked_cb ()
+{
+ GdkPixbuf *pixbuf;
+
+ /* I really hope you have this. */
+ pixbuf = gdk_pixbuf_new_from_file ("/usr/share/backgrounds/gnome/adwaita-day.jpg",
+ NULL);
+
+ g_assert (pixbuf != NULL);
+ gtk_image_view_set_pixbuf (GTK_IMAGE_VIEW (image_view), pixbuf);
+}
+
GtkWidget *
diff --git a/demos/gtk-demo/image_view.ui b/demos/gtk-demo/image_view.ui
index 28df6df..640d8e4 100644
--- a/demos/gtk-demo/image_view.ui
+++ b/demos/gtk-demo/image_view.ui
@@ -64,6 +64,19 @@
</child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">true</property>
+ <property name="label" translatable="yes">Load Pixbuf</property>
+ <signal name="clicked" handler="load_pixbuf_button_clicked_cb" />
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+
<child>
@@ -73,7 +86,7 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">2</property>
+ <property name="top_attach">3</property>
<property name="width">2</property>
</packing>
</child>
@@ -87,7 +100,7 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">3</property>
+ <property name="top_attach">4</property>
<property name="width">2</property>
</packing>
</child>
@@ -103,7 +116,7 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">4</property>
+ <property name="top_attach">5</property>
<property name="width">2</property>
</packing>
</child>
@@ -116,7 +129,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>
@@ -131,7 +144,7 @@
</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>
@@ -174,7 +187,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>
@@ -189,7 +202,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>
@@ -203,7 +216,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>
@@ -213,9 +226,6 @@
</child>
-
-
-
<child>
<object class="GtkImageView" id="image_view">
<property name="visible">true</property>
diff --git a/gtk/gtkimageview.c b/gtk/gtkimageview.c
index 55e2569..1b75d92 100644
--- a/gtk/gtkimageview.c
+++ b/gtk/gtkimageview.c
@@ -45,6 +45,8 @@ struct _GtkImageViewPrivate
GdkPixbufAnimation *source_animation;
GdkPixbufAnimationIter *source_animation_iter;
cairo_surface_t *image_surface;
+ int surface_width;
+ int surface_height;
int animation_timeout;
/* Transitions */
@@ -55,6 +57,10 @@ struct _GtkImageViewPrivate
// XXX animate image size changes!
// XXX Double-press gesture to zoom in/out
+//
+// XXX Keep track of the inital width/height and use a non-image cairo surface
+// XXX Pass a scaling factor to the loading functions
+// Means: "The supplied image was designed for this scaling factor"
enum
{
@@ -98,6 +104,8 @@ gtk_image_view_init (GtkImageView *image_view)
priv->scale = 1.0;
priv->angle = 0.0;
+ priv->surface_width = -1;
+ priv->surface_height = -1;
priv->snap_angle = FALSE;
priv->fit_allocation = FALSE;
priv->scale_set = FALSE;
@@ -110,7 +118,8 @@ gtk_image_view_init (GtkImageView *image_view)
}
/* Prototypes {{{ */
-static void gtk_image_view_update_surface (GtkImageView *image_view);
+static void gtk_image_view_update_surface (GtkImageView *image_view,
+ const GdkPixbuf *frame);
static void adjustment_value_changed_cb (GtkAdjustment *adjustment,
gpointer user_data);
@@ -119,6 +128,20 @@ static void adjustment_value_changed_cb (GtkAdjustment *adjustment,
/* }}} */
+static GdkPixbuf *
+gtk_image_view_get_current_frame (GtkImageView *image_view)
+{
+ GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
+
+ g_assert (priv->source_animation);
+
+ if (priv->is_animation)
+ return gdk_pixbuf_animation_iter_get_pixbuf (priv->source_animation_iter);
+ else
+ return gdk_pixbuf_animation_get_static_image (priv->source_animation);
+}
+
+
static gboolean
gtk_image_view_update_animation (gpointer user_data)
{
@@ -126,7 +149,8 @@ gtk_image_view_update_animation (gpointer user_data)
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
gdk_pixbuf_animation_iter_advance (priv->source_animation_iter, NULL);
- gtk_image_view_update_surface (image_view);
+ gtk_image_view_update_surface (image_view,
+ gtk_image_view_get_current_frame (image_view));
return priv->is_animation;
}
@@ -138,8 +162,7 @@ gtk_image_view_start_animation (GtkImageView *image_view)
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
int delay_ms;
- if (!priv->is_animation)
- g_error ("NOPE");
+ g_assert (priv->is_animation);
delay_ms = gdk_pixbuf_animation_iter_get_delay_time (priv->source_animation_iter);
@@ -173,8 +196,11 @@ frameclock_cb (GtkWidget *widget,
double new_angle = (priv->transition_end_angle - priv->transition_start_angle) * t;
priv->angle = priv->transition_start_angle + new_angle;
- /*gtk_widget_queue_resize (widget);*/
- gtk_widget_queue_draw (widget);
+
+ if (priv->fit_allocation)
+ gtk_widget_queue_draw (widget);
+ else
+ gtk_widget_queue_resize (widget);
if (t >= 1.0)
{
@@ -378,12 +404,16 @@ gtk_image_view_draw (GtkWidget *widget, cairo_t *ct)
gtk_render_frame (sc, ct, 0, 0, alloc.width, alloc.height);
if (!priv->image_surface)
- return FALSE;
+ return GDK_EVENT_PROPAGATE;
gtk_image_view_compute_bounding_box (image_view, &draw_width, &draw_height, &scale);
- image_width = cairo_image_surface_get_width (priv->image_surface) * scale;
- image_height = cairo_image_surface_get_height (priv->image_surface) * scale;
+ image_width = priv->surface_width * scale;
+ image_height = priv->surface_height * scale;
+
+ if (image_width == 0 || image_height == 0)
+ return GDK_EVENT_PROPAGATE;
+
draw_x = (alloc.width - draw_width) / 2;
draw_y = (alloc.height - draw_height) / 2;
@@ -428,6 +458,7 @@ gtk_image_view_draw (GtkWidget *widget, cairo_t *ct)
cairo_scale (ct, scale, scale);
cairo_set_source_surface (ct, priv->image_surface, draw_x/scale, draw_y/scale);
+ cairo_pattern_set_filter (cairo_get_source (ct), CAIRO_FILTER_FAST);
cairo_fill (ct);
cairo_restore (ct);
@@ -555,7 +586,10 @@ gtk_image_view_set_angle (GtkImageView *image_view,
g_object_notify_by_pspec ((GObject *)image_view,
widget_props[PROP_ANGLE]);
- gtk_widget_queue_resize ((GtkWidget *)image_view);
+ if (priv->fit_allocation)
+ gtk_widget_queue_draw ((GtkWidget *)image_view);
+ else
+ gtk_widget_queue_resize ((GtkWidget *)image_view);
}
double
@@ -922,13 +956,12 @@ gtk_image_view_finalize (GObject *object)
g_clear_object (&priv->zoom_gesture);
g_clear_object (&priv->hadjustment);
- g_clear_object (&priv->hadjustment);
+ g_clear_object (&priv->vadjustment);
if (priv->image_surface)
cairo_surface_destroy (priv->image_surface);
-
G_OBJECT_CLASS (gtk_image_view_parent_class)->finalize (object);
}
@@ -1022,31 +1055,18 @@ gtk_image_view_new ()
}
-static GdkPixbuf *
-gtk_image_view_get_current_frame (GtkImageView *image_view)
-{
- GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
-
- g_assert (priv->source_animation);
-
- if (priv->is_animation)
- return gdk_pixbuf_animation_iter_get_pixbuf (priv->source_animation_iter);
- else
- return gdk_pixbuf_animation_get_static_image (priv->source_animation);
-}
-
-
static void
-gtk_image_view_update_surface (GtkImageView *image_view)
+gtk_image_view_update_surface (GtkImageView *image_view,
+ const GdkPixbuf *frame)
{
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
- int cur_width = gdk_pixbuf_animation_get_width (priv->source_animation);
- int cur_height = gdk_pixbuf_animation_get_height (priv->source_animation);
- GdkPixbuf *frame = gtk_image_view_get_current_frame (image_view);
+ int new_width = gdk_pixbuf_get_width (frame);
+ int new_height = gdk_pixbuf_get_height (frame);
+ gboolean resize = TRUE;
if (!priv->image_surface ||
- cairo_image_surface_get_width (priv->image_surface) != cur_width ||
- cairo_image_surface_get_height (priv->image_surface) != cur_height)
+ priv->surface_width != new_width ||
+ priv->surface_height != new_height)
{
if (priv->image_surface)
cairo_surface_destroy (priv->image_surface);
@@ -1055,16 +1075,22 @@ gtk_image_view_update_surface (GtkImageView *image_view)
1,
gtk_widget_get_window ((GtkWidget
*)image_view));
cairo_surface_reference (priv->image_surface);
+ priv->surface_width = new_width;
+ priv->surface_height = new_height;
}
else
{
gdk_cairo_surface_paint_pixbuf (priv->image_surface, frame);
+ resize = FALSE;
}
g_assert (priv->image_surface != NULL);
g_signal_emit (image_view, widget_signals[PREPARE_IMAGE], 0, priv->image_surface);
- gtk_widget_queue_resize ((GtkWidget *)image_view);
+ if (resize)
+ gtk_widget_queue_resize ((GtkWidget *)image_view);
+ else
+ gtk_widget_queue_resize ((GtkWidget *)image_view);
}
@@ -1083,6 +1109,7 @@ gtk_image_view_load_image_from_stream (GtkImageView *image_view,
g_object_unref (input_stream);
if (error)
{
+ // XXX
g_error ("error!");
}
else
@@ -1097,6 +1124,7 @@ gtk_image_view_load_image_from_stream (GtkImageView *image_view,
}
/*g_task_return_pointer (task, result, g_object_unref);*/
+
priv->source_animation = result;
priv->is_animation = !gdk_pixbuf_animation_is_static_image (result);
if (priv->is_animation)
@@ -1105,9 +1133,9 @@ gtk_image_view_load_image_from_stream (GtkImageView *image_view,
NULL);
gtk_image_view_start_animation (image_view);
}
- gtk_image_view_update_surface (image_view);
+ gtk_image_view_update_surface (image_view,
+ gtk_image_view_get_current_frame (image_view));
}
-
}
static void
@@ -1213,3 +1241,16 @@ gtk_image_view_load_from_stream_finish (GtkImageView *image_view,
{
g_return_if_fail (g_task_is_valid (result, image_view));
}
+
+
+
+void
+gtk_image_view_set_pixbuf (GtkImageView *image_view,
+ const GdkPixbuf *pixbuf)
+{
+ 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);
+}
+
diff --git a/gtk/gtkimageview.h b/gtk/gtkimageview.h
index 8cf3bc5..cacf8c7 100644
--- a/gtk/gtkimageview.h
+++ b/gtk/gtkimageview.h
@@ -43,6 +43,11 @@ GDK_AVAILABLE_IN_3_18
GtkWidget * gtk_image_view_new ();
+GDK_AVAILABLE_IN_3_18
+void gtk_image_view_set_pixbuf (GtkImageView *image_view,
+ const GdkPixbuf *pixbuf);
+
+
/* Loading {{{ */
GDK_AVAILABLE_IN_3_18
@@ -71,7 +76,8 @@ void gtk_image_view_load_from_stream_finish (GtkImageView *image_view,
/* Setters/Getters {{{ */
GDK_AVAILABLE_IN_3_18
-void gtk_image_view_set_scale (GtkImageView *image_view, double scale);
+void gtk_image_view_set_scale (GtkImageView *image_view,
+ double scale);
GDK_AVAILABLE_IN_3_18
double gtk_image_view_get_scale (GtkImageView *image_view);
@@ -79,7 +85,8 @@ double gtk_image_view_get_scale (GtkImageView *image_view);
GDK_AVAILABLE_IN_3_18
-void gtk_image_view_set_angle (GtkImageView *image_view, double angle);
+void gtk_image_view_set_angle (GtkImageView *image_view,
+ double angle);
GDK_AVAILABLE_IN_3_18
double gtk_image_view_get_angle (GtkImageView *image_view);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]