[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