Author: rpmcruz
Date: Thu Dec 6 05:28:35 2007
New Revision: 42749
URL: http://svn.opensuse.org/viewcvs/yast?rev=42749&view=rev
Log:
Forgot to commit these two.
Added:
trunk/gtk/unstable/src/ygtkimage.c
trunk/gtk/unstable/src/ygtkimage.h
Added: trunk/gtk/unstable/src/ygtkimage.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkimage.c?rev=42749&view=auto
==============================================================================
--- trunk/gtk/unstable/src/ygtkimage.c (added)
+++ trunk/gtk/unstable/src/ygtkimage.c Thu Dec 6 05:28:35 2007
@@ -0,0 +1,285 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* YGtkImage widget */
+// check the header file for information about this widget
+
+#include
+#include "ygdkmngloader.h"
+#include "ygtkimage.h"
+#include
+
+G_DEFINE_TYPE (YGtkImage, ygtk_image, GTK_TYPE_DRAWING_AREA)
+
+static void ygtk_image_init (YGtkImage *image)
+{
+}
+
+static void ygtk_image_free_pixbuf (YGtkImage *image)
+{
+ if (image->animated) {
+ if (image->animation) {
+ g_object_unref (G_OBJECT (image->animation->pixbuf));
+ if (image->animation->timeout_id)
+ g_source_remove (image->animation->timeout_id);
+ g_free (image->animation);
+ image->animation = NULL;
+ }
+ }
+ else {
+ if (image->pixbuf) {
+ g_object_unref (G_OBJECT (image->pixbuf));
+ image->pixbuf = NULL;
+ }
+ }
+}
+
+static void ygtk_image_destroy (GtkObject *object)
+{
+ YGtkImage *image = YGTK_IMAGE (object);
+ if (image->alt_text)
+ g_free (image->alt_text);
+ image->alt_text = NULL;
+ ygtk_image_free_pixbuf (image);
+ GTK_OBJECT_CLASS (ygtk_image_parent_class)->destroy (object);
+}
+
+static void ygtk_image_set_pixbuf (YGtkImage *image, GdkPixbuf *pixbuf, const char *error_msg)
+{
+ ygtk_image_free_pixbuf (image);
+ gtk_widget_queue_resize (GTK_WIDGET (image));
+
+ if (pixbuf) {
+ image->animated = FALSE;
+ image->pixbuf = pixbuf;
+ image->loaded = TRUE;
+ }
+/* else
+ g_warning ("Couldn't load image - %s", error_msg);*/
+}
+
+static gboolean ygtk_image_advance_frame_cb (gpointer data)
+{
+ YGtkImage *image = (YGtkImage *) data;
+ struct _YGtkImageAnimation *animation = image->animation;
+
+ if (!animation->frame) // no frame yet loaded
+ animation->frame = gdk_pixbuf_animation_get_iter (animation->pixbuf, NULL);
+ else
+ if (gdk_pixbuf_animation_iter_advance (animation->frame, NULL))
+ gtk_widget_queue_draw (GTK_WIDGET (image));
+
+ // shedule next frame
+ int delay = gdk_pixbuf_animation_iter_get_delay_time (animation->frame);
+ if (delay != -1)
+ animation->timeout_id = g_timeout_add (delay, ygtk_image_advance_frame_cb, data);
+ return FALSE;
+}
+
+static void ygtk_image_set_animation (YGtkImage *image, GdkPixbufAnimation *pixbuf,
+ const char *error_msg)
+{
+ ygtk_image_free_pixbuf (image);
+ gtk_widget_queue_resize (GTK_WIDGET (image));
+
+ if (pixbuf) {
+ image->animated = TRUE;
+ image->animation = g_new0 (struct _YGtkImageAnimation, 1);
+ image->animation->pixbuf = pixbuf;
+ image->loaded = TRUE;
+ ygtk_image_advance_frame_cb (image);
+ }
+/* else
+ g_warning ("Couldn't load image - %s", error_msg);*/
+}
+
+void ygtk_image_set_from_file (YGtkImage *image, const char *filename, gboolean anim)
+{
+ GError *error = 0;
+ if (anim) {
+ GdkPixbufAnimation *pixbuf;
+ if (ygdk_mng_pixbuf_is_file_mng (filename))
+ pixbuf = ygdk_mng_pixbuf_new_from_file (filename, &error);
+ else
+ pixbuf = gdk_pixbuf_animation_new_from_file (filename, &error);
+ ygtk_image_set_animation (image, pixbuf, error ? error->message : "(undefined)");
+ }
+ else {
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (filename, &error);
+ ygtk_image_set_pixbuf (image, pixbuf, error ? error->message : "(undefined)");
+ }
+}
+
+static void ygtk_image_loaded_cb (GdkPixbufLoader *loader, YGtkImage *image)
+{
+ if (image->animated) {
+ if (image->animation) {
+ // a new frame loaded -- just redraw the widget
+ if (gdk_pixbuf_animation_iter_on_currently_loading_frame
+ (image->animation->frame))
+ gtk_widget_queue_draw (GTK_WIDGET (image));
+ }
+ else {
+ GdkPixbufAnimation *pixbuf = gdk_pixbuf_loader_get_animation (loader);
+ g_object_ref (G_OBJECT (pixbuf));
+ ygtk_image_set_animation (image, pixbuf, "on block data reading callback");
+ }
+ }
+ else {
+ GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+ g_object_ref (G_OBJECT (pixbuf));
+ ygtk_image_set_pixbuf (image, pixbuf, "on block data reading callback");
+ }
+}
+
+void ygtk_image_set_from_data (YGtkImage *image, const guint8 *data, long data_size, gboolean anim)
+{
+ GError *error = 0;
+ if (anim && ygdk_mng_pixbuf_is_data_mng (data, data_size)) {
+ GdkPixbufAnimation *pixbuf;
+ pixbuf = ygdk_mng_pixbuf_new_from_data (data, data_size, &error);
+ ygtk_image_set_animation (image, pixbuf, error ? error->message : "(undefined)");
+ }
+ else {
+ image->animated = anim;
+ GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
+ g_signal_connect (G_OBJECT (loader), "area-prepared",
+ G_CALLBACK (ygtk_image_loaded_cb), image);
+ if (!gdk_pixbuf_loader_write (loader, data, data_size, &error))
+ g_warning ("Could not load image from data blocks: %s", error->message);
+ gdk_pixbuf_loader_close (loader, &error);
+ }
+}
+
+void ygtk_image_set_props (YGtkImage *image, YGtkImageAlign align, const gchar *alt_text)
+{
+ image->align = align;
+ if (image->alt_text)
+ g_free (image->alt_text);
+ image->alt_text = g_strdup (alt_text);
+ gtk_widget_queue_draw (GTK_WIDGET (image));
+}
+
+static void ygtk_image_size_request (GtkWidget *widget, GtkRequisition *requisition)
+{
+ YGtkImage *image = YGTK_IMAGE (widget);
+ int width = 0, height = 0;
+ if (image->loaded) {
+ if (image->animated) {
+ width = gdk_pixbuf_animation_get_width (image->animation->pixbuf);
+ height = gdk_pixbuf_animation_get_height (image->animation->pixbuf);
+ }
+ else {
+ width = gdk_pixbuf_get_width (image->pixbuf);
+ height = gdk_pixbuf_get_height (image->pixbuf);
+ }
+ }
+ else if (image->alt_text) {
+ PangoLayout *layout;
+ layout = gtk_widget_create_pango_layout (widget, image->alt_text);
+ pango_layout_get_pixel_size (layout, &width, &height);
+ }
+ requisition->width = width;
+ requisition->height = height;
+}
+
+static GdkPixbuf *ygtk_image_render_state (GtkWidget *widget, GdkPixbuf *pixbuf)
+{
+ // as in GtkImage
+ GtkIconSource *source = gtk_icon_source_new();
+ GdkPixbuf *rendered;
+ gtk_icon_source_set_pixbuf (source, pixbuf);
+ gtk_icon_source_set_size (source, GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_icon_source_set_size_wildcarded (source, FALSE);
+ rendered = gtk_style_render_icon (widget->style, source,
+ gtk_widget_get_direction (widget), GTK_WIDGET_STATE (widget),
+ /* arbitrary */ (GtkIconSize)-1, widget, "gtk-image");
+ gtk_icon_source_free (source);
+ return rendered;
+}
+
+static gboolean ygtk_image_expose_event (GtkWidget *widget, GdkEventExpose *event)
+{
+ YGtkImage *image = YGTK_IMAGE (widget);
+ int width, height;
+ width = widget->allocation.width;
+ height = widget->allocation.height;
+
+ cairo_t *cr = gdk_cairo_create (widget->window);
+
+ if (!image->loaded && image->alt_text) {
+ // show alt text if no image was loaded
+ PangoLayout *layout;
+ layout = gtk_widget_create_pango_layout (widget, image->alt_text);
+
+ int x, y;
+ x = (width - widget->requisition.width) / 2;
+ y = (height - widget->requisition.height) / 2;
+
+ cairo_move_to (cr, x, y);
+ pango_cairo_show_layout (cr, layout);
+
+ g_object_unref (layout);
+ cairo_destroy (cr);
+ return TRUE;
+ }
+
+ GdkPixbuf *pixbuf;
+ if (image->animated)
+ pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (image->animation->frame);
+ else
+ pixbuf = image->pixbuf;
+
+ gboolean needs_transform = GTK_WIDGET_STATE (widget) != GTK_STATE_NORMAL;
+ if (needs_transform)
+ pixbuf = ygtk_image_render_state (widget, pixbuf);
+ int x = 0, y = 0;
+ if (image->align == CENTER_IMAGE_ALIGN) {
+ x = (width - widget->requisition.width) / 2;
+ y = (height - widget->requisition.height) / 2;
+ }
+
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y);
+
+ switch (image->align) {
+ case CENTER_IMAGE_ALIGN:
+ break;
+ case SCALE_IMAGE_ALIGN:
+ {
+ double scale_x = (double) gdk_pixbuf_get_width (pixbuf) / width;
+ double scale_y = (double) gdk_pixbuf_get_height (pixbuf) / height;
+ cairo_matrix_t matrix;
+ cairo_matrix_init_scale (&matrix, scale_x, scale_y);
+ cairo_pattern_set_matrix (cairo_get_source (cr), &matrix);
+ break;
+ }
+ case TILE_IMAGE_ALIGN:
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ break;
+ }
+
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_fill (cr);
+
+ cairo_destroy (cr);
+ if (needs_transform)
+ g_object_unref (G_OBJECT (pixbuf));
+ return FALSE;
+}
+
+GtkWidget* ygtk_image_new (void)
+{
+ return g_object_new (YGTK_TYPE_IMAGE, NULL);
+}
+
+static void ygtk_image_class_init (YGtkImageClass *klass)
+{
+ GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass);
+ widget_class->expose_event = ygtk_image_expose_event;
+ widget_class->size_request = ygtk_image_size_request;
+
+ GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
+ gtkobject_class->destroy = ygtk_image_destroy;
+}
+
Added: trunk/gtk/unstable/src/ygtkimage.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkimage.h?rev=42749&view=auto
==============================================================================
--- trunk/gtk/unstable/src/ygtkimage.h (added)
+++ trunk/gtk/unstable/src/ygtkimage.h Thu Dec 6 05:28:35 2007
@@ -0,0 +1,75 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* GtkImage doesn't provide all the functionality asked by libyui,
+ such as scaling and tiling. Thus, YGtkImage is a more powerful
+ GtkImage.
+*/
+
+#ifndef YGTK_IMAGE_H
+#define YGTK_IMAGE_H
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define YGTK_TYPE_IMAGE (ygtk_image_get_type ())
+#define YGTK_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ YGTK_TYPE_IMAGE, YGtkImage))
+#define YGTK_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ YGTK_TYPE_IMAGE, YGtkImageClass))
+#define YGTK_IS_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ YGTK_TYPE_IMAGE))
+#define YGTK_IS_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ YGTK_TYPE_IMAGE))
+#define YGTK_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ YGTK_TYPE_IMAGE, YGtkImageClass))
+
+typedef enum {
+ CENTER_IMAGE_ALIGN, SCALE_IMAGE_ALIGN, TILE_IMAGE_ALIGN
+} YGtkImageAlign;
+
+struct _YGtkImageAnimation {
+ GdkPixbufAnimation *pixbuf;
+ GdkPixbufAnimationIter *frame;
+ guint timeout_id;
+};
+
+typedef struct _YGtkImage
+{
+ GtkDrawingArea parent;
+
+ // properties:
+ YGtkImageAlign align;
+
+ gboolean animated;
+ union {
+ GdkPixbuf *pixbuf;
+ struct _YGtkImageAnimation *animation;
+ };
+
+ gboolean loaded;
+ gchar *alt_text;
+
+} YGtkImage;
+
+typedef struct _YGtkImageClass
+{
+ GtkDrawingAreaClass parent_class;
+} YGtkImageClass;
+
+GtkWidget* ygtk_image_new (void);
+GType ygtk_image_get_type (void) G_GNUC_CONST;
+
+void ygtk_image_set_from_file (YGtkImage *image, const char *filename, gboolean anim);
+void ygtk_image_set_from_data (YGtkImage *image, const guint8 *data, long size, gboolean anim);
+void ygtk_image_set_props (YGtkImage *image, YGtkImageAlign align, const gchar *alt_text);
+
+// as we don't have a window,
+
+G_END_DECLS
+
+#endif /* YGTK_IMAGE_H */
+
--
To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org
For additional commands, e-mail: yast-commit+help@opensuse.org