midori/katze/katze-throbber.c

881 lines
26 KiB
C
Raw Normal View History

/*
Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
See the file COPYING for the full license text.
*/
#include "katze-throbber.h"
#include <gtk/gtk.h>
G_DEFINE_TYPE (KatzeThrobber, katze_throbber, GTK_TYPE_MISC)
struct _KatzeThrobberPrivate
{
GtkIconSize icon_size;
gchar* icon_name;
GdkPixbuf* pixbuf;
gchar* stock_id;
gboolean animated;
gchar* static_icon_name;
GdkPixbuf* static_pixbuf;
gchar* static_stock_id;
gint index;
gint timer_id;
gint width;
gint height;
};
#define KATZE_THROBBER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), KATZE_TYPE_THROBBER, KatzeThrobberPrivate))
enum
{
PROP_0,
PROP_ICON_SIZE,
PROP_ICON_NAME,
PROP_PIXBUF,
PROP_ANIMATED,
PROP_STATIC_ICON_NAME,
PROP_STATIC_PIXBUF,
PROP_STATIC_STOCK_ID
};
static void
katze_throbber_dispose(GObject* object);
static void
katze_throbber_set_property (GObject* object,
guint prop_id,
const GValue* value,
GParamSpec* pspec);
static void
katze_throbber_get_property (GObject* object,
guint prop_id,
GValue* value,
GParamSpec* pspec);
static void
katze_throbber_destroy (GtkObject* object);
static void
katze_throbber_realize (GtkWidget* widget);
static void
katze_throbber_unrealize (GtkWidget* widget);
static void
katze_throbber_map (GtkWidget* widget);
static void
katze_throbber_unmap (GtkWidget* widget);
static void
katze_throbber_style_set (GtkWidget* widget,
GtkStyle* style);
static void
katze_throbber_screen_changed (GtkWidget* widget,
GdkScreen* screen_prev);
static void
katze_throbber_size_request (GtkWidget* widget,
GtkRequisition* requisition);
static gboolean
katze_throbber_expose_event (GtkWidget* widget,
GdkEventExpose* event);
static void
icon_theme_changed (KatzeThrobber* throbber);
static gboolean
katze_throbber_timeout (KatzeThrobber* throbber);
static void
katze_throbber_timeout_destroy (KatzeThrobber* throbber);
static void
katze_throbber_class_init (KatzeThrobberClass* class)
{
GObjectClass* gobject_class = G_OBJECT_CLASS (class);
gobject_class->dispose = katze_throbber_dispose;
gobject_class->set_property = katze_throbber_set_property;
gobject_class->get_property = katze_throbber_get_property;
GtkObjectClass* object_class = GTK_OBJECT_CLASS (class);
object_class->destroy = katze_throbber_destroy;
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (class);
widget_class->realize = katze_throbber_realize;
widget_class->unrealize = katze_throbber_unrealize;
widget_class->map = katze_throbber_map;
widget_class->unmap = katze_throbber_unmap;
widget_class->style_set = katze_throbber_style_set;
widget_class->screen_changed = katze_throbber_screen_changed;
widget_class->size_request = katze_throbber_size_request;
widget_class->expose_event = katze_throbber_expose_event;
GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
g_object_class_install_property (gobject_class,
PROP_ICON_SIZE,
g_param_spec_int (
"icon-size",
"Icon size",
"Symbolic size to use for the animation",
0, G_MAXINT, GTK_ICON_SIZE_MENU,
flags));
g_object_class_install_property (gobject_class,
PROP_ICON_NAME,
g_param_spec_string (
"icon-name",
"Icon Name",
"The name of an icon containing animation frames",
"process-working",
flags));
g_object_class_install_property (gobject_class,
PROP_PIXBUF,
g_param_spec_object (
"pixbuf",
"Pixbuf",
"A GdkPixbuf containing animation frames",
GDK_TYPE_PIXBUF,
flags));
g_object_class_install_property (gobject_class,
PROP_ANIMATED,
g_param_spec_boolean (
"animated",
"Animated",
"Whether the throbber should be animated",
FALSE,
flags));
g_object_class_install_property (gobject_class,
PROP_STATIC_ICON_NAME,
g_param_spec_string (
"static-icon-name",
"Static Icon Name",
"The name of an icon to be used as the static image",
NULL,
flags));
g_object_class_install_property (gobject_class,
PROP_PIXBUF,
g_param_spec_object (
"static-pixbuf",
"Static Pixbuf",
"A GdkPixbuf to be used as the static image",
GDK_TYPE_PIXBUF,
flags));
g_object_class_install_property (gobject_class,
PROP_STATIC_STOCK_ID,
g_param_spec_string (
"static-stock-id",
"Static Stock ID",
"The stock ID of an icon to be used as the static image",
NULL,
flags));
g_type_class_add_private (object_class, sizeof (KatzeThrobberPrivate));
}
static void
katze_throbber_init (KatzeThrobber *throbber)
{
GTK_WIDGET_SET_FLAGS (throbber, GTK_NO_WINDOW);
2008-01-20 17:05:16 +00:00
throbber->priv = KATZE_THROBBER_GET_PRIVATE (throbber);
KatzeThrobberPrivate* priv = throbber->priv;
priv->timer_id = -1;
}
static void
katze_throbber_dispose (GObject *object)
{
KatzeThrobber* throbber = KATZE_THROBBER (object);
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
if (G_UNLIKELY (priv->timer_id >= 0))
g_source_remove (priv->timer_id);
(*G_OBJECT_CLASS (katze_throbber_parent_class)->dispose) (object);
}
static void
katze_throbber_destroy (GtkObject *object)
{
KatzeThrobber* throbber = KATZE_THROBBER (object);
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
katze_assign (priv->icon_name, NULL);
if (priv->pixbuf)
katze_object_assign (priv->pixbuf, NULL);
katze_assign (priv->static_icon_name, NULL);
if (priv->static_pixbuf)
katze_object_assign (priv->static_pixbuf, NULL);
katze_assign (priv->static_stock_id, NULL);
GTK_OBJECT_CLASS (katze_throbber_parent_class)->destroy (object);
}
static void
katze_throbber_set_property (GObject* object,
guint prop_id,
const GValue* value,
GParamSpec* pspec)
{
KatzeThrobber* throbber = KATZE_THROBBER (object);
switch (prop_id)
{
case PROP_ICON_SIZE:
katze_throbber_set_icon_size (throbber, g_value_get_int (value));
break;
case PROP_ICON_NAME:
katze_throbber_set_icon_name (throbber, g_value_get_string (value));
break;
case PROP_PIXBUF:
katze_throbber_set_pixbuf (throbber, g_value_get_object (value));
break;
case PROP_ANIMATED:
katze_throbber_set_animated (throbber, g_value_get_boolean (value));
break;
case PROP_STATIC_ICON_NAME:
katze_throbber_set_static_icon_name (throbber, g_value_get_string (value));
break;
case PROP_STATIC_PIXBUF:
katze_throbber_set_static_pixbuf (throbber, g_value_get_object (value));
break;
case PROP_STATIC_STOCK_ID:
katze_throbber_set_static_stock_id (throbber, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
katze_throbber_get_property (GObject* object,
guint prop_id,
GValue* value,
GParamSpec* pspec)
{
KatzeThrobber* throbber = KATZE_THROBBER (object);
switch (prop_id)
{
case PROP_ICON_SIZE:
g_value_set_int (value, katze_throbber_get_icon_size (throbber));
break;
case PROP_ICON_NAME:
g_value_set_string (value, katze_throbber_get_icon_name (throbber));
break;
case PROP_PIXBUF:
g_value_set_object (value, katze_throbber_get_pixbuf (throbber));
break;
case PROP_ANIMATED:
g_value_set_boolean (value, katze_throbber_get_animated (throbber));
break;
case PROP_STATIC_ICON_NAME:
g_value_set_string (value, katze_throbber_get_static_icon_name (throbber));
break;
case PROP_STATIC_PIXBUF:
g_value_set_object (value, katze_throbber_get_static_pixbuf (throbber));
break;
case PROP_STATIC_STOCK_ID:
g_value_set_string (value, katze_throbber_get_static_stock_id (throbber));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/**
* katze_throbber_new:
*
* Creates a new throbber widget.
*
* Return value: a new #KatzeThrobber
**/
GtkWidget*
katze_throbber_new (void)
{
KatzeThrobber* throbber = g_object_new (KATZE_TYPE_THROBBER,
NULL);
return GTK_WIDGET (throbber);
}
/**
* katze_throbber_set_icon_size:
* @throbber: a #KatzeThrobber
* @icon_size: the new icon size
*
* Sets the desired size of the throbber image. The animation and static image
* will be displayed in this size. If a pixbuf is used for the animation every
* single frame is assumed to have this size.
**/
void
katze_throbber_set_icon_size (KatzeThrobber* throbber,
GtkIconSize icon_size)
{
g_return_if_fail (KATZE_IS_THROBBER (throbber));
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
g_return_if_fail (gtk_icon_size_lookup (icon_size,
&priv->width,
&priv->height));
priv->icon_size = icon_size;
g_object_notify (G_OBJECT (throbber), "icon-size");
}
/**
* katze_throbber_set_icon_name:
* @throbber: a #KatzeThrobber
* @icon_name: an icon name or %NULL
*
* Sets the name of an icon that should provide the animation frames.
*
* The pixbuf is automatically invalidated.
**/
void
katze_throbber_set_icon_name (KatzeThrobber* throbber,
const gchar* icon_name)
{
g_return_if_fail (KATZE_IS_THROBBER (throbber));
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
katze_assign (priv->icon_name, g_strdup (icon_name));
if (icon_name)
icon_theme_changed (throbber);
g_object_notify (G_OBJECT (throbber), "icon-name");
}
/**
* katze_throbber_set_pixbuf:
* @throbber: a #KatzeThrobber
* @pixbuf: a #GdkPixbuf or %NULL
*
* Sets the pixbuf that should provide the animation frames. Every frame
* is assumed to have the icon size of the throbber, which can be specified
* with katze_throbber_set_icon_size ().
*
* The icon name is automatically invalidated.
**/
void
katze_throbber_set_pixbuf (KatzeThrobber* throbber,
2008-01-20 17:05:16 +00:00
GdkPixbuf* pixbuf)
{
g_return_if_fail (KATZE_IS_THROBBER (throbber));
g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
katze_object_assign (priv->pixbuf, pixbuf);
if (pixbuf)
{
g_object_ref (pixbuf);
katze_assign (priv->icon_name, NULL);
}
gtk_widget_queue_draw (GTK_WIDGET (throbber));
g_object_notify (G_OBJECT (throbber), "pixbuf");
}
/**
* katze_throbber_set_animated:
* @throbber: a #KatzeThrobber
* @animated: %TRUE to animate the throbber
*
* Sets the animation state of the throbber.
**/
void
katze_throbber_set_animated (KatzeThrobber* throbber,
gboolean animated)
{
g_return_if_fail (KATZE_IS_THROBBER (throbber));
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
if (G_UNLIKELY (priv->animated == animated))
return;
priv->animated = animated;
if (animated && (priv->timer_id < 0))
priv->timer_id = g_timeout_add_full (
G_PRIORITY_LOW, 50,
(GSourceFunc)katze_throbber_timeout,
throbber,
(GDestroyNotify)katze_throbber_timeout_destroy);
gtk_widget_queue_draw (GTK_WIDGET (throbber));
g_object_notify (G_OBJECT (throbber), "animated");
}
/**
* katze_throbber_set_static_icon_name:
* @throbber: a #KatzeThrobber
* @icon_name: an icon name or %NULL
*
* Sets the name of an icon that should provide the static image.
*
* The static pixbuf and stock ID are automatically invalidated.
**/
void
katze_throbber_set_static_icon_name (KatzeThrobber* throbber,
const gchar* icon_name)
{
g_return_if_fail (KATZE_IS_THROBBER (throbber));
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
katze_assign (priv->static_icon_name, g_strdup (icon_name));
if (icon_name)
{
katze_assign (priv->static_stock_id, NULL);
icon_theme_changed (throbber);
}
g_object_notify (G_OBJECT (throbber), "static-icon-name");
}
/**
* katze_throbber_set_static_pixbuf:
* @throbber: a #KatzeThrobber
* @pixbuf: a #GdkPixbuf or %NULL
*
* Sets the pixbuf that should provide the static image. The pixbuf is
* assumed to have the icon size of the throbber, which can be specified
* with katze_throbber_set_icon_size ().
*
* The static icon name and stock ID are automatically invalidated.
**/
void
katze_throbber_set_static_pixbuf (KatzeThrobber* throbber,
2008-01-20 17:05:16 +00:00
GdkPixbuf* pixbuf)
{
g_return_if_fail (KATZE_IS_THROBBER (throbber));
g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
katze_object_assign (priv->static_pixbuf, pixbuf);
if (pixbuf)
{
g_object_ref (pixbuf);
katze_assign (priv->static_icon_name, NULL);
katze_assign (priv->static_stock_id, NULL);
}
g_object_notify (G_OBJECT (throbber), "static-pixbuf");
}
/**
* katze_throbber_set_static_stock_id:
* @throbber: a #KatzeThrobber
* @stock_id: a stock ID or %NULL
*
* Sets the stock ID of an icon that should provide the static image.
*
* The statc icon name and pixbuf are automatically invalidated.
**/
void
katze_throbber_set_static_stock_id (KatzeThrobber* throbber,
const gchar* stock_id)
{
g_return_if_fail (KATZE_IS_THROBBER (throbber));
if (stock_id)
{
GtkStockItem stock_item;
g_return_if_fail (gtk_stock_lookup (stock_id, &stock_item));
}
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
katze_assign (priv->static_stock_id, g_strdup (stock_id));
if (stock_id)
icon_theme_changed (throbber);
g_object_notify (G_OBJECT (throbber), "static-stock-id");
}
/**
* katze_throbber_get_icon_size:
* @throbber: a #KatzeThrobber
*
* Retrieves the size of the throbber.
*
* Return value: the size of the throbber
**/
GtkIconSize
katze_throbber_get_icon_size (KatzeThrobber* throbber)
{
g_return_val_if_fail (KATZE_IS_THROBBER (throbber), GTK_ICON_SIZE_INVALID);
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
return priv->icon_size;
}
/**
* katze_throbber_get_icon_name:
* @throbber: a #KatzeThrobber
*
* Retrieves the name of the icon providing the animation frames.
*
* Return value: the name of the icon providing the animation frames, or %NULL
**/
const gchar*
katze_throbber_get_icon_name (KatzeThrobber* throbber)
{
g_return_val_if_fail (KATZE_IS_THROBBER (throbber), NULL);
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
return priv->icon_name;
}
/**
* katze_throbber_get_pixbuf:
* @throbber: a #KatzeThrobber
*
* Retrieves the #GdkPixbuf providing the animation frames if an icon name
* or pixbuf is available. The caller of this function does not own a
* reference to the returned pixbuf.
*
* Return value: the pixbuf providing the animation frames, or %NULL
**/
GdkPixbuf*
katze_throbber_get_pixbuf (KatzeThrobber* throbber)
{
g_return_val_if_fail (KATZE_IS_THROBBER (throbber), NULL);
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
return priv->pixbuf;
}
/**
* katze_throbber_get_animated:
* @throbber: a #KatzeThrobber
*
* Retrieves the status of the animation, whcih can be animated or static.
*
* Return value: %TRUE if the throbber is animated
**/
gboolean
katze_throbber_get_animated (KatzeThrobber* throbber)
{
g_return_val_if_fail (KATZE_IS_THROBBER (throbber), FALSE);
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
return priv->animated;
}
/**
* katze_throbber_get_static_icon_name:
* @throbber: a #KatzeThrobber
*
* Retrieves the name of the icon providing the static image, if an icon name
* for the static image was specified.
*
* Return value: the name of the icon providing the static image, or %NULL
**/
const gchar*
katze_throbber_get_static_icon_name (KatzeThrobber* throbber)
{
g_return_val_if_fail (KATZE_IS_THROBBER (throbber), NULL);
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
return priv->static_icon_name;
}
/**
* katze_throbber_get_static pixbuf:
* @throbber: a #KatzeThrobber
*
* Retrieves the #GdkPixbuf providing the static image, if an icon name, a
* pixbuf or a stock ID for the static image was specified. The caller of this
* function does not own a reference to the returned pixbuf.
*
* Return value: the pixbuf providing the static image, or %NULL
**/
GdkPixbuf*
katze_throbber_get_static_pixbuf (KatzeThrobber* throbber)
{
g_return_val_if_fail (KATZE_IS_THROBBER (throbber), NULL);
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
return priv->static_pixbuf;
}
/**
* katze_throbber_get_static_stock_id:
* @throbber: a #KatzeThrobber
*
* Retrieves the stock ID of the icon providing the static image, if a
* stock ID for the static image was specified.
*
* Return value: the stock ID of the icon providing the static image, or %NULL
**/
const gchar*
katze_throbber_get_static_stock_id (KatzeThrobber* throbber)
{
g_return_val_if_fail (KATZE_IS_THROBBER (throbber), NULL);
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
return priv->static_stock_id;
}
static void
katze_throbber_realize (GtkWidget* widget)
{
(*GTK_WIDGET_CLASS (katze_throbber_parent_class)->realize) (widget);
icon_theme_changed (KATZE_THROBBER (widget));
}
static void
katze_throbber_unrealize (GtkWidget* widget)
{
if (GTK_WIDGET_CLASS (katze_throbber_parent_class)->unrealize)
GTK_WIDGET_CLASS (katze_throbber_parent_class)->unrealize (widget);
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = KATZE_THROBBER(widget)->priv;
katze_object_assign (priv->pixbuf, NULL);
katze_object_assign (priv->static_pixbuf, NULL);
}
static void
pixbuf_assign_icon (GdkPixbuf** pixbuf,
const gchar* icon_name,
KatzeThrobber* throbber)
{
if (*pixbuf)
g_object_unref (*pixbuf);
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
GdkScreen* screen = gtk_widget_get_screen (GTK_WIDGET (throbber));
GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen (screen);
*pixbuf = gtk_icon_theme_load_icon (icon_theme,
icon_name,
MAX (priv->width, priv->height),
(GtkIconLookupFlags) 0,
NULL);
}
static void
icon_theme_changed (KatzeThrobber* throbber)
{
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
if (priv->icon_name)
pixbuf_assign_icon (&priv->pixbuf, priv->icon_name,
throbber);
if (priv->static_icon_name)
pixbuf_assign_icon (&priv->static_pixbuf, priv->static_icon_name,
throbber);
else if (priv->static_stock_id)
{
if (priv->static_pixbuf)
g_object_unref (priv->static_pixbuf);
priv->static_pixbuf = gtk_widget_render_icon (GTK_WIDGET (throbber),
priv->static_stock_id,
priv->icon_size,
NULL);
}
gtk_widget_queue_draw (GTK_WIDGET (throbber));
}
static void
katze_throbber_map (GtkWidget* widget)
{
(*GTK_WIDGET_CLASS (katze_throbber_parent_class)->map) (widget);
}
static void
katze_throbber_unmap (GtkWidget* widget)
{
if (GTK_WIDGET_CLASS (katze_throbber_parent_class)->unmap)
GTK_WIDGET_CLASS (katze_throbber_parent_class)->unmap (widget);
}
static gboolean
katze_throbber_timeout (KatzeThrobber* throbber)
{
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
priv->index++;
gtk_widget_queue_draw (GTK_WIDGET (throbber));
return priv->animated;
}
static void
katze_throbber_timeout_destroy (KatzeThrobber* throbber)
{
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = throbber->priv;
priv->index = 0;
priv->timer_id = -1;
}
static void
katze_throbber_style_set (GtkWidget* widget,
2008-01-20 17:05:16 +00:00
GtkStyle* prev_style)
{
if (GTK_WIDGET_CLASS (katze_throbber_parent_class)->style_set)
GTK_WIDGET_CLASS (katze_throbber_parent_class)->style_set (widget,
prev_style);
icon_theme_changed (KATZE_THROBBER (widget));
}
static void
katze_throbber_screen_changed (GtkWidget* widget,
2008-01-20 17:05:16 +00:00
GdkScreen* prev_screen)
{
if (GTK_WIDGET_CLASS (katze_throbber_parent_class)->screen_changed)
GTK_WIDGET_CLASS (katze_throbber_parent_class)->screen_changed (
widget,
prev_screen);
icon_theme_changed (KATZE_THROBBER (widget));
}
static void
katze_throbber_size_request (GtkWidget* widget,
GtkRequisition* requisition)
{
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = KATZE_THROBBER (widget)->priv;
requisition->width = priv->width;
requisition->height = priv->height;
GTK_WIDGET_CLASS (katze_throbber_parent_class)->size_request (widget,
requisition);
}
static gboolean
katze_throbber_expose_event (GtkWidget* widget,
GdkEventExpose* event)
{
2008-01-20 17:05:16 +00:00
KatzeThrobberPrivate* priv = KATZE_THROBBER (widget)->priv;
if (G_UNLIKELY (!priv->width || !priv->height))
return TRUE;
if (G_UNLIKELY (!priv->pixbuf && !priv->static_pixbuf))
if (priv->animated && !priv->pixbuf && !priv->icon_name)
return TRUE;
if (!priv->animated &&
(priv->static_pixbuf || priv->static_icon_name || priv->static_stock_id))
{
if (G_UNLIKELY (!priv->static_pixbuf && priv->static_icon_name))
{
icon_theme_changed (KATZE_THROBBER (widget));
if (!priv->static_pixbuf)
{
g_warning ("Named icon '%s' couldn't be loaded",
priv->static_icon_name);
katze_assign (priv->static_icon_name, NULL);
return TRUE;
}
}
else if (G_UNLIKELY (!priv->static_pixbuf && priv->static_stock_id))
{
icon_theme_changed (KATZE_THROBBER (widget));
if (!priv->static_pixbuf)
{
g_warning ("Stock icon '%s' couldn't be loaded",
priv->static_stock_id);
katze_assign (priv->static_stock_id, NULL);
return TRUE;
}
}
gdk_draw_pixbuf (event->window, NULL, priv->static_pixbuf,
0, 0,
widget->allocation.x,
widget->allocation.y,
priv->width, priv->height,
GDK_RGB_DITHER_NONE, 0, 0);
}
else
{
if (G_UNLIKELY (priv->icon_name && !priv->pixbuf))
{
icon_theme_changed (KATZE_THROBBER (widget));
if (!priv->pixbuf)
{
g_warning ("Icon '%s' couldn't be loaded", priv->icon_name);
katze_assign (priv->icon_name, NULL);
return TRUE;
}
}
if (G_UNLIKELY (!priv->pixbuf))
return TRUE;
gint cols = gdk_pixbuf_get_width (priv->pixbuf) / priv->width;
gint rows = gdk_pixbuf_get_height (priv->pixbuf) / priv->height;
if (G_LIKELY (cols > 0 && rows > 0))
{
gint index = priv->index % (cols * rows);
if (G_LIKELY (priv->timer_id >= 0))
index = MAX (index, 1);
guint x = (index % cols) * priv->width;
guint y = (index / cols) * priv->height;
gdk_draw_pixbuf (event->window, NULL, priv->pixbuf,
x, y,
widget->allocation.x,
widget->allocation.y,
priv->width, priv->height,
GDK_RGB_DITHER_NONE, 0, 0);
}
else
{
g_warning ("Animation frames are broken");
katze_assign (priv->icon_name, NULL);
katze_object_assign (priv->pixbuf, NULL);
}
}
return TRUE;
}