e1f62329f1
The 'browser' struct is superseded by MidoriBrowser, which actually represents a window that holds pages, i.e. tabs. The tabs are currently of the type MidoriWebView, which is a slightly enhanced WebView. Also MidoriWebSettings is introduced to hold additional settings that Midori needs. The other two new classes are MidoriTrash, representing closed tabs and windows and MidoriPanel, representing the side panel. The refactoring allows for several features to be much more easily implemented, such as full support for multiple windows and instant saving of modified files, such as bookmarks or the session. Regressions are expected and not everything is done yet.
878 lines
26 KiB
C
878 lines
26 KiB
C
/*
|
|
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);
|
|
|
|
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);
|
|
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);
|
|
KatzeThrobberPrivate* priv = throbber->priv;
|
|
|
|
katze_assign (priv->icon_name, NULL);
|
|
katze_object_assign (priv->pixbuf, NULL);
|
|
katze_assign (priv->static_icon_name, NULL);
|
|
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));
|
|
|
|
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));
|
|
|
|
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,
|
|
GdkPixbuf* pixbuf)
|
|
{
|
|
g_return_if_fail (KATZE_IS_THROBBER (throbber));
|
|
g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
|
|
|
|
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));
|
|
|
|
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));
|
|
|
|
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,
|
|
GdkPixbuf* pixbuf)
|
|
{
|
|
g_return_if_fail (KATZE_IS_THROBBER (throbber));
|
|
g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
|
|
|
|
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));
|
|
}
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
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)
|
|
{
|
|
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)
|
|
{
|
|
KatzeThrobberPrivate* priv = throbber->priv;
|
|
|
|
priv->index++;
|
|
gtk_widget_queue_draw (GTK_WIDGET (throbber));
|
|
|
|
return priv->animated;
|
|
}
|
|
|
|
static void
|
|
katze_throbber_timeout_destroy (KatzeThrobber* throbber)
|
|
{
|
|
KatzeThrobberPrivate* priv = throbber->priv;
|
|
|
|
priv->index = 0;
|
|
priv->timer_id = -1;
|
|
}
|
|
|
|
static void
|
|
katze_throbber_style_set (GtkWidget* widget,
|
|
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,
|
|
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)
|
|
{
|
|
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)
|
|
{
|
|
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;
|
|
}
|