[Xfce4-commits] <xfce4-panel:devel> * Add the XfceScaledImage widget. Only used in panel implementations (so far), so therefore it's not suitable for libxfce4ui.

Nick Schermer nick at xfce.org
Tue Aug 11 20:24:15 CEST 2009


Updating branch refs/heads/devel
         to b69f4a2f4e72e59dc0944aef958f0538c75ee95c (commit)
       from da1b170dad3dfd79be0a1e85047295acacb8c926 (commit)

commit b69f4a2f4e72e59dc0944aef958f0538c75ee95c
Author: Nick Schermer <nick at xfce.org>
Date:   Sat Oct 4 20:00:26 2008 +0200

    * Add the XfceScaledImage widget. Only used in panel implementations (so far),
      so therefore it's not suitable for libxfce4ui.

 libxfce4panel/Makefile.am         |    6 +-
 libxfce4panel/libxfce4panel.h     |    1 +
 libxfce4panel/xfce-scaled-image.c |  423 +++++++++++++++++++++++++++++++++++++
 libxfce4panel/xfce-scaled-image.h |   61 ++++++
 4 files changed, 489 insertions(+), 2 deletions(-)

diff --git a/libxfce4panel/Makefile.am b/libxfce4panel/Makefile.am
index ca6235f..92397f2 100644
--- a/libxfce4panel/Makefile.am
+++ b/libxfce4panel/Makefile.am
@@ -20,7 +20,8 @@ libxfce4panel_headers =							\
 	xfce-hvbox.h							\
 	xfce-panel-convenience.h					\
 	xfce-panel-macros.h						\
-	xfce-panel-plugin.h
+	xfce-panel-plugin.h						\
+	xfce-scaled-image.h
 
 libxfce4panel_includedir =						\
 	$(includedir)/xfce4/libxfce4panel
@@ -36,7 +37,8 @@ libxfce4panel_la_SOURCES =						\
 	xfce-panel-convenience.c					\
 	xfce-panel-plugin.c						\
 	xfce-panel-plugin-provider.c					\
-	xfce-panel-plugin-provider.h
+	xfce-panel-plugin-provider.h					\
+	xfce-scaled-image.c
 
 libxfce4panel_la_CFLAGS =						\
 	$(GTK_CFLAGS)							\
diff --git a/libxfce4panel/libxfce4panel.h b/libxfce4panel/libxfce4panel.h
index ebf60b3..0a01b70 100644
--- a/libxfce4panel/libxfce4panel.h
+++ b/libxfce4panel/libxfce4panel.h
@@ -30,6 +30,7 @@ G_BEGIN_DECLS
 #include <libxfce4panel/xfce-panel-convenience.h>
 #include <libxfce4panel/xfce-panel-enums.h>
 #include <libxfce4panel/xfce-panel-plugin.h>
+#include <libxfce4panel/xfce-scaled-image.h>
 
 #undef LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H
 
diff --git a/libxfce4panel/xfce-scaled-image.c b/libxfce4panel/xfce-scaled-image.c
new file mode 100644
index 0000000..43ea9fa
--- /dev/null
+++ b/libxfce4panel/xfce-scaled-image.c
@@ -0,0 +1,423 @@
+/* $Id$ */
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include <libxfce4panel/libxfce4panel.h>
+
+
+
+struct _XfceScaledImageClass
+{
+  GtkWidgetClass __parent__;
+};
+
+struct _XfceScaledImage
+{
+  GtkWidget __parent__;
+
+  /* pixbuf set by the user */
+  GdkPixbuf *pixbuf;
+
+  /* icon name */
+  gchar     *icon_name;
+
+  /* internal cached pixbuf (resized) */
+  GdkPixbuf *cache;
+
+  /* cached width and height */
+  gint       width;
+  gint       height;
+};
+
+
+
+static void     xfce_scaled_image_class_init    (XfceScaledImageClass *klass);
+static void     xfce_scaled_image_init          (XfceScaledImage      *tasklist);
+static void     xfce_scaled_image_finalize      (GObject              *object);
+static void     xfce_scaled_image_size_request  (GtkWidget            *widget,
+                                                 GtkRequisition       *requisition);
+static gboolean xfce_scaled_image_expose_event  (GtkWidget            *widget,
+                                                 GdkEventExpose       *event);
+static void     xfce_scaled_image_size_allocate (GtkWidget            *widget,
+                                                 GtkAllocation        *allocation);
+static void     xfce_scaled_image_update_cache  (XfceScaledImage      *image);
+static void     xfce_scaled_image_cleanup       (XfceScaledImage      *image);
+
+
+
+G_DEFINE_TYPE (XfceScaledImage, xfce_scaled_image, GTK_TYPE_WIDGET);
+
+
+
+static void
+xfce_scaled_image_class_init (XfceScaledImageClass *klass)
+{
+  GObjectClass   *gobject_class;
+  GtkWidgetClass *gtkwidget_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = xfce_scaled_image_finalize;
+
+  gtkwidget_class = GTK_WIDGET_CLASS (klass);
+  gtkwidget_class->expose_event = xfce_scaled_image_expose_event;
+  gtkwidget_class->size_request = xfce_scaled_image_size_request;
+  gtkwidget_class->size_allocate = xfce_scaled_image_size_allocate;
+}
+
+
+
+static void
+xfce_scaled_image_init (XfceScaledImage *image)
+{
+  GTK_WIDGET_SET_FLAGS (GTK_WIDGET (image), GTK_NO_WINDOW);
+
+  image->pixbuf = NULL;
+  image->icon_name = NULL;
+  image->cache = NULL;
+  image->width = -1;
+  image->height = -1;
+}
+
+
+
+static void
+xfce_scaled_image_finalize (GObject *object)
+{
+  XfceScaledImage *image = XFCE_SCALED_IMAGE (object);
+
+  /* cleanup */
+  xfce_scaled_image_cleanup (image);
+
+  (*G_OBJECT_CLASS (xfce_scaled_image_parent_class)->finalize) (object);
+}
+
+
+
+static gboolean
+xfce_scaled_image_expose_event (GtkWidget      *widget,
+                                GdkEventExpose *event)
+{
+  XfceScaledImage *image = XFCE_SCALED_IMAGE (widget);
+  gint             source_width, source_height;
+  gint             dest_x, dest_y;
+
+  if (image->cache)
+    {
+      /* get the size of the cache pixbuf */
+      source_width = gdk_pixbuf_get_width (image->cache);
+      source_height = gdk_pixbuf_get_height (image->cache);
+
+      /* position */
+      dest_x = widget->allocation.x + (image->width - source_width) / 2;
+      dest_y = widget->allocation.y + (image->height - source_height) / 2;
+
+      /* draw the pixbuf */
+      gdk_draw_pixbuf (widget->window,
+                       widget->style->black_gc,
+                       image->cache,
+                       0, 0,
+                       dest_x, dest_y,
+                       source_width, source_height,
+                       GDK_RGB_DITHER_NORMAL, 0, 0);
+    }
+
+  return FALSE;
+}
+
+
+
+static void
+xfce_scaled_image_size_request (GtkWidget      *widget,
+                                GtkRequisition *requisition)
+{
+  XfceScaledImage *image = XFCE_SCALED_IMAGE (widget);
+
+  if (image->pixbuf)
+    {
+      widget->requisition.width = gdk_pixbuf_get_width (image->pixbuf);
+      widget->requisition.height = gdk_pixbuf_get_height (image->pixbuf);
+    }
+
+  GTK_WIDGET_CLASS (xfce_scaled_image_parent_class)->size_request (widget, requisition);
+}
+
+
+
+static void
+xfce_scaled_image_size_allocate (GtkWidget     *widget,
+                                 GtkAllocation *allocation)
+{
+  XfceScaledImage *image = XFCE_SCALED_IMAGE (widget);
+
+  /* set the widget allocation */
+  widget->allocation = *allocation;
+
+  /* check if the available size changed */
+  if ((image->pixbuf || image->icon_name)
+      && allocation->width > 0
+      && allocation->height > 0
+      && (allocation->width != image->width
+      || allocation->height != image->height))
+    {
+      /* store the new size */
+      image->width = allocation->width;
+      image->height = allocation->height;
+
+      if (image->cache)
+        {
+          g_object_unref (G_OBJECT (image->cache));
+          image->cache = NULL;
+        }
+
+      xfce_scaled_image_update_cache (image);
+    }
+
+  GTK_WIDGET_CLASS (xfce_scaled_image_parent_class)->size_allocate (widget, allocation);
+}
+
+
+
+static void
+xfce_scaled_image_update_cache (XfceScaledImage *image)
+{
+  gint       source_width, source_height;
+  gint       dest_width, dest_height;
+  gdouble    wratio, hratio;
+  GdkPixbuf *pixbuf;
+  GdkScreen *screen;
+
+  panel_return_if_fail (image->cache == NULL);
+  panel_return_if_fail (image->pixbuf != NULL || image->icon_name != NULL);
+
+  /* target size */
+  dest_width = image->width;
+  dest_height = image->height;
+
+  if (image->pixbuf)
+    {
+      /* use the pixbuf set by the user */
+      pixbuf = image->pixbuf;
+    }
+  else if (image->icon_name)
+    {
+      /* get the screen */
+      screen = gtk_widget_get_screen (GTK_WIDGET (image));
+
+      /* get a pixbuf from the icon name */
+      pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_for_screen (screen),
+                                         image->icon_name,
+                                         MIN (dest_width, dest_height),
+                                         0, NULL);
+    }
+
+  /* get the pixbuf size */
+  source_width = gdk_pixbuf_get_width (pixbuf);
+  source_height = gdk_pixbuf_get_height (pixbuf);
+
+  if (dest_width >= source_width && dest_height >= source_height)
+    {
+      /* use the origional pixmap */
+      image->cache = g_object_ref (G_OBJECT (pixbuf));
+    }
+  else
+    {
+      /* calculate the new dimensions */
+      wratio = (gdouble) source_width  / (gdouble) dest_width;
+      hratio = (gdouble) source_height / (gdouble) dest_height;
+
+      if (hratio > wratio)
+        dest_width  = rint (source_width / hratio);
+      else
+        dest_height = rint (source_height / wratio);
+
+      /* scale the pixbuf */
+      if (dest_width > 1 && dest_height > 1)
+        image->cache = gdk_pixbuf_scale_simple (pixbuf, dest_width, dest_height, GDK_INTERP_BILINEAR);
+    }
+}
+
+
+
+static void
+xfce_scaled_image_cleanup (XfceScaledImage *image)
+{
+  /* release the pixbuf reference */
+  if (G_LIKELY (image->pixbuf))
+    {
+      g_object_unref (G_OBJECT (image->pixbuf));
+      image->pixbuf = NULL;
+    }
+
+  /* release the cached pixbuf */
+  if (G_LIKELY (image->cache))
+    {
+      g_object_unref (G_OBJECT (image->cache));
+      image->cache = NULL;
+    }
+
+  /* free the icon name */
+  g_free (image->icon_name);
+  image->icon_name = NULL;
+
+  /* reset the cached width and height */
+  image->width = -1;
+  image->height = -1;
+}
+
+
+
+PANEL_SYMBOL_EXPORT GtkWidget *
+xfce_scaled_image_new (void)
+{
+  return g_object_new (XFCE_TYPE_SCALED_IMAGE, NULL);
+}
+
+
+
+PANEL_SYMBOL_EXPORT GtkWidget *
+xfce_scaled_image_new_from_pixbuf (GdkPixbuf *pixbuf)
+{
+  GtkWidget *image;
+
+  g_return_val_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf), NULL);
+
+  /* create a scaled image */
+  image = xfce_scaled_image_new ();
+
+  /* set the pixbuf */
+  xfce_scaled_image_set_from_pixbuf (XFCE_SCALED_IMAGE (image), pixbuf);
+
+  return image;
+}
+
+
+
+PANEL_SYMBOL_EXPORT GtkWidget *
+xfce_scaled_image_new_from_icon_name (const gchar *icon_name)
+{
+  GtkWidget *image;
+
+  /* create a scaled image */
+  image = xfce_scaled_image_new ();
+
+  /* set the icon name */
+  xfce_scaled_image_set_from_icon_name (XFCE_SCALED_IMAGE (image), icon_name);
+
+  return image;
+}
+
+
+
+PANEL_SYMBOL_EXPORT GtkWidget *
+xfce_scaled_image_new_from_file (const gchar *filename)
+{
+  GtkWidget *image;
+
+  /* create a scaled image */
+  image = xfce_scaled_image_new ();
+
+  /* set the filename */
+  xfce_scaled_image_set_from_file (XFCE_SCALED_IMAGE (image), filename);
+
+  return image;
+}
+
+
+
+PANEL_SYMBOL_EXPORT void
+xfce_scaled_image_set_from_pixbuf (XfceScaledImage *image,
+                                   GdkPixbuf       *pixbuf)
+{
+  g_return_if_fail (XFCE_IS_SCALED_IMAGE (image));
+  g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
+
+  /* cleanup */
+  xfce_scaled_image_cleanup (image);
+
+  if (G_LIKELY (pixbuf))
+    {
+      /* set the new pixbuf */
+      image->pixbuf = g_object_ref (G_OBJECT (pixbuf));
+
+      /* queue a resize */
+      gtk_widget_queue_resize (GTK_WIDGET (image));
+    }
+}
+
+
+
+PANEL_SYMBOL_EXPORT void
+xfce_scaled_image_set_from_icon_name (XfceScaledImage *image,
+                                      const gchar     *icon_name)
+{
+  g_return_if_fail (XFCE_IS_SCALED_IMAGE (image));
+
+  /* cleanup */
+  xfce_scaled_image_cleanup (image);
+
+  if (G_LIKELY (icon_name && *icon_name != '\0'))
+    {
+      /* set the new icon name */
+      image->icon_name = g_strdup (icon_name);
+
+      /* queue a resize */
+      gtk_widget_queue_resize (GTK_WIDGET (image));
+    }
+}
+
+
+
+PANEL_SYMBOL_EXPORT void
+xfce_scaled_image_set_from_file (XfceScaledImage *image,
+                                 const gchar     *filename)
+{
+  GdkPixbuf *pixbuf = NULL;
+  GError    *error = NULL;
+
+  g_return_if_fail (XFCE_IS_SCALED_IMAGE (image));
+
+  if (G_LIKELY (filename && *filename != '\0'))
+    {
+      /* try to load the image from the file */
+      pixbuf = gdk_pixbuf_new_from_file (filename, &error);
+
+      if (G_UNLIKELY (error != NULL))
+        {
+          /* print a warning what went wrong */
+          g_critical ("Failed to loading image from filesname: %s", error->message);
+
+          /* cleanup */
+          g_error_free (error);
+        }
+    }
+
+  /* set the pixbuf */
+  xfce_scaled_image_set_from_pixbuf (image, pixbuf);
+
+  /* release the pixbuf */
+  if (G_LIKELY (pixbuf))
+    g_object_unref (G_OBJECT (pixbuf));
+}
diff --git a/libxfce4panel/xfce-scaled-image.h b/libxfce4panel/xfce-scaled-image.h
new file mode 100644
index 0000000..33d0281
--- /dev/null
+++ b/libxfce4panel/xfce-scaled-image.h
@@ -0,0 +1,61 @@
+/* $Id$ */
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#if !defined(LIBXFCE4PANEL_INSIDE_LIBXFCE4PANEL_H) && !defined(LIBXFCE4PANEL_COMPILATION)
+#error "Only <libxfce4panel/libxfce4panel.h> can be included directly, this file may disappear or change contents"
+#endif
+
+#ifndef __XFCE_SCALED_IMAGE_H__
+#define __XFCE_SCALED_IMAGE_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _XfceScaledImageClass XfceScaledImageClass;
+typedef struct _XfceScaledImage      XfceScaledImage;
+
+#define XFCE_TYPE_SCALED_IMAGE            (xfce_scaled_image_get_type ())
+#define XFCE_SCALED_IMAGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_SCALED_IMAGE, XfceScaledImage))
+#define XFCE_SCALED_IMAGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_SCALED_IMAGE, XfceScaledImageClass))
+#define XFCE_IS_SCALED_IMAGE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_SCALED_IMAGE))
+#define XFCE_IS_SCALED_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_SCALED_IMAGE))
+#define XFCE_SCALED_IMAGE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_SCALED_IMAGE, XfceScaledImageClass))
+
+PANEL_SYMBOL_EXPORT
+GType      xfce_scaled_image_get_type           (void) G_GNUC_CONST;
+
+GtkWidget *xfce_scaled_image_new                (void) G_GNUC_MALLOC;
+
+GtkWidget *xfce_scaled_image_new_from_pixbuf    (GdkPixbuf       *pixbuf) G_GNUC_MALLOC;
+
+GtkWidget *xfce_scaled_image_new_from_icon_name (const gchar     *icon_name) G_GNUC_MALLOC;
+
+GtkWidget *xfce_scaled_image_new_from_file      (const gchar     *filename) G_GNUC_MALLOC;
+
+void       xfce_scaled_image_set_from_pixbuf    (XfceScaledImage *image,
+                                                 GdkPixbuf       *pixbuf);
+
+void       xfce_scaled_image_set_from_icon_name (XfceScaledImage *image,
+                                                 const gchar     *icon_name);
+
+void       xfce_scaled_image_set_from_file      (XfceScaledImage *image,
+                                                 const gchar     *filename);
+
+G_END_DECLS
+
+#endif /* !__XFCE_SCALED_IMAGE_H__ */



More information about the Xfce4-commits mailing list