summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--Makefile.am2
-rwxr-xr-xautogen.sh1
-rw-r--r--configure.in4
-rw-r--r--katze/Makefile.am13
-rw-r--r--katze/katze-throbber.c878
-rw-r--r--katze/katze-throbber.h119
-rw-r--r--katze/katze-utils.c12
-rw-r--r--katze/katze-utils.h50
-rw-r--r--katze/katze.h18
-rw-r--r--src/Makefile.am46
-rw-r--r--src/browser.c7
-rw-r--r--src/helpers.c14
13 files changed, 1142 insertions, 27 deletions
diff --git a/.gitignore b/.gitignore
index 14af9aa6..9f8d6522 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,16 @@
+*.la
+*.lo
*.o
.deps
+.libs
aclocal.m4
autom4te.cache
config.*
configure
depcomp
install-sh
+libtool
+ltmain.sh
Makefile
Makefile.in
missing
diff --git a/Makefile.am b/Makefile.am
index cd36747b..95418862 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
AUTOMAKE_OPTIONS = gnu
-SUBDIRS = src
+SUBDIRS = katze src
desktopdir = $(datadir)/applications
desktop_DATA = midori.desktop
diff --git a/autogen.sh b/autogen.sh
index 863dee9f..739a102c 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,5 +1,6 @@
#!/bin/sh
+libtoolize --copy --force
aclocal
autoheader
autoconf
diff --git a/configure.in b/configure.in
index 46034966..80742357 100644
--- a/configure.in
+++ b/configure.in
@@ -4,6 +4,7 @@ AC_CONFIG_SRCDIR([src/main.h])
AC_CONFIG_HEADER([config.h])
AM_INIT_AUTOMAKE([AC_PACKAGE_TARNAME()], [AC_PACKAGE_VERSION()])
+AM_PROG_LIBTOOL
# Checks for programs
AC_PROG_CC
@@ -83,7 +84,8 @@ AC_DEFINE_UNQUOTED([LIBXML_VER], "$LIBXML_VER", [libXML2 version])
# Here we tell the configure script which files to *create*
AC_CONFIG_FILES([
- Makefile \
+ Makefile \
+ katze/Makefile \
src/Makefile
])
AC_OUTPUT
diff --git a/katze/Makefile.am b/katze/Makefile.am
new file mode 100644
index 00000000..f0b2a9fb
--- /dev/null
+++ b/katze/Makefile.am
@@ -0,0 +1,13 @@
+INCLUDES = \
+ $(GTK_CFLAGS)
+
+noinst_LTLIBRARIES = \
+ libkatze.la
+
+libkatze_la_LIBADD = \
+ $(GTK_LIBS)
+
+libkatze_la_SOURCES = \
+ katze.h \
+ katze-throbber.c katze-throbber.h \
+ katze-utils.c katze-utils.h
diff --git a/katze/katze-throbber.c b/katze/katze-throbber.c
new file mode 100644
index 00000000..fb31912f
--- /dev/null
+++ b/katze/katze-throbber.c
@@ -0,0 +1,878 @@
+/*
+ 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);
+
+ KatzeThrobberPrivate* priv = KATZE_THROBBER_GET_PRIVATE (throbber);
+ priv->timer_id = -1;
+}
+
+static void
+katze_throbber_dispose (GObject *object)
+{
+ KatzeThrobber* throbber = KATZE_THROBBER (object);
+ KatzeThrobberPrivate* priv = KATZE_THROBBER_GET_PRIVATE (throbber);
+
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+
+ 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));
+
+ KatzeThrobberPrivate* priv = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+ 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_GET_PRIVATE (KATZE_THROBBER (widget));
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+
+ 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 = KATZE_THROBBER_GET_PRIVATE (throbber);
+
+ priv->index++;
+ gtk_widget_queue_draw (GTK_WIDGET (throbber));
+
+ return priv->animated;
+}
+
+static void
+katze_throbber_timeout_destroy (KatzeThrobber* throbber)
+{
+ KatzeThrobberPrivate* priv = KATZE_THROBBER_GET_PRIVATE (throbber);
+
+ 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_GET_PRIVATE (KATZE_THROBBER (widget));
+
+ 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_GET_PRIVATE (KATZE_THROBBER (widget));
+
+ 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;
+}
diff --git a/katze/katze-throbber.h b/katze/katze-throbber.h
new file mode 100644
index 00000000..ebd51028
--- /dev/null
+++ b/katze/katze-throbber.h
@@ -0,0 +1,119 @@
+/*
+ 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.
+*/
+
+#ifndef __KATZE_THROBBER_H__
+#define __KATZE_THROBBER_H__
+
+#include <gdk/gdk.h>
+#include <gtk/gtkmisc.h>
+
+#include "katze-utils.h"
+
+G_BEGIN_DECLS
+
+#define KATZE_TYPE_THROBBER \
+ (katze_throbber_get_type ())
+#define KATZE_THROBBER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), KATZE_TYPE_THROBBER, KatzeThrobber))
+#define KATZE_THROBBER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), KATZE_TYPE_THROBBER, KatzeThrobberClass))
+#define KATZE_IS_THROBBER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KATZE_TYPE_THROBBER))
+#define KATZE_IS_THROBBER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), KATZE_TYPE_THROBBER))
+#define KATZE_THROBBER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), KATZE_TYPE_THROBBER, KatzeThrobberClass))
+
+typedef struct _KatzeThrobber KatzeThrobber;
+typedef struct _KatzeThrobberPrivate KatzeThrobberPrivate;
+typedef struct _KatzeThrobberClass KatzeThrobberClass;
+
+struct _KatzeThrobber
+{
+ KatzeThrobberPrivate* priv;
+ GtkWidget parent_object;
+
+ /* Padding for future expansion */
+ void (*_katze_reserved1) (void);
+ void (*_katze_reserved2) (void);
+ void (*_katze_reserved3) (void);
+ void (*_katze_reserved4) (void);
+};
+
+struct _KatzeThrobberClass
+{
+ GtkMiscClass parent_class;
+
+ /* Padding for future expansion */
+ void (*_katze_reserved1) (void);
+ void (*_katze_reserved2) (void);
+ void (*_katze_reserved3) (void);
+ void (*_katze_reserved4) (void);
+};
+
+GType
+katze_throbber_get_type (void) G_GNUC_CONST;
+
+GtkWidget*
+katze_throbber_new (void);
+
+void
+katze_throbber_set_icon_size (KatzeThrobber* throbber,
+ GtkIconSize icon_size);
+
+void
+katze_throbber_set_icon_name (KatzeThrobber* throbber,
+ const gchar* icon_size);
+
+void
+katze_throbber_set_pixbuf (KatzeThrobber* throbber,
+ GdkPixbuf* pixbuf);
+
+void
+katze_throbber_set_animated (KatzeThrobber* throbber,
+ gboolean animated);
+
+void
+katze_throbber_set_static_icon_name (KatzeThrobber* throbber,
+ const gchar* icon_name);
+
+void
+katze_throbber_set_static_pixbuf (KatzeThrobber* throbber,
+ GdkPixbuf* pixbuf);
+
+void
+katze_throbber_set_static_stock_id (KatzeThrobber* throbber,
+ const gchar* stock_id);
+
+GtkIconSize
+katze_throbber_get_icon_size (KatzeThrobber* throbber);
+
+const gchar*
+katze_throbber_get_icon_name (KatzeThrobber* throbber);
+
+GdkPixbuf*
+katze_throbber_get_pixbuf (KatzeThrobber* throbber);
+
+gboolean
+katze_throbber_get_animated (KatzeThrobber* throbber);
+
+const gchar*
+katze_throbber_get_static_icon_name (KatzeThrobber *throbber);
+
+GdkPixbuf*
+katze_throbber_get_static_pixbuf (KatzeThrobber* throbber);
+
+const gchar*
+katze_throbber_get_static_stock_id (KatzeThrobber* throbber);
+
+G_END_DECLS
+
+#endif /* __KATZE_THROBBER_H__ */
diff --git a/katze/katze-utils.c b/katze/katze-utils.c
new file mode 100644
index 00000000..620a5d01
--- /dev/null
+++ b/katze/katze-utils.c
@@ -0,0 +1,12 @@
+/*
+ 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-utils.h"
diff --git a/katze/katze-utils.h b/katze/katze-utils.h
new file mode 100644
index 00000000..45dda897
--- /dev/null
+++ b/katze/katze-utils.h
@@ -0,0 +1,50 @@
+/*
+ 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.
+*/
+
+#ifndef __KATZE_UTILS_H__
+#define __KATZE_UTILS_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ * katze_assign:
+ * @lvalue: a pointer
+ * @rvalue: the new value
+ *
+ * Frees @lvalue if needed and assigns it the value of @rvalue.
+ **/
+#define katze_assign(lvalue, rvalue) \
+ if (1) \
+ { \
+ g_free (lvalue); \
+ lvalue = rvalue; \
+ }
+
+/**
+ * katze_object_assign:
+ * @lvalue: a gobject
+ * @rvalue: the new value
+ *
+ * Unrefs @lvalue if needed and assigns it the value of @rvalue.
+ **/
+#define katze_object_assign(lvalue, rvalue) \
+ if (1) \
+ { \
+ if (lvalue) \
+ g_object_unref (lvalue); \
+ lvalue = rvalue; \
+ }
+
+G_END_DECLS
+
+#endif /* __KATZE_UTILS_H__ */
diff --git a/katze/katze.h b/katze/katze.h
new file mode 100644
index 00000000..f401be3c
--- /dev/null
+++ b/katze/katze.h
@@ -0,0 +1,18 @@
+/*
+ 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.
+*/
+
+#ifndef __KATZE__
+#define __KATZE__
+
+#include "katze-throbber.h"
+#include "katze-utils.h"
+
+#endif /* __KATZE_THROBBER_H__ */
diff --git a/src/Makefile.am b/src/Makefile.am
index c8db7753..6246932a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,17 +1,31 @@
-INCLUDES = $(GTK_CFLAGS) $(WEBKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBSEXY_CFLAGS)
-LDADD = $(GTK_LIBS) $(WEBKIT_LIBS) $(LIBXML_LIBS) $(LIBSEXY_LIBS)
+INCLUDES = \
+ $(GTK_CFLAGS) \
+ $(WEBKIT_CFLAGS) \
+ $(LIBXML_CFLAGS) \
+ $(LIBSEXY_CFLAGS) \
+ -I../katze
-bin_PROGRAMS = midori
-midori_SOURCES = main.c main.h \
- browser.c browser.h \
- prefs.c prefs.h \
- webSearch.c webSearch.h \
- helpers.c helpers.h \
- webView.c webView.h \
- sokoke.c sokoke.h \
- conf.c conf.h \
- search.c search.h \
- xbel.c xbel.h \
- global.h \
- ui.h \
- debug.h
+LDADD = \
+ $(GTK_LIBS) \
+ $(WEBKIT_LIBS) \
+ $(LIBXML_LIBS) \
+ $(LIBSEXY_LIBS) \
+ ../katze/libkatze.la
+
+bin_PROGRAMS = \
+ midori
+
+midori_SOURCES = \
+ main.c main.h \
+ browser.c browser.h \
+ prefs.c prefs.h \
+ webSearch.c webSearch.h \
+ helpers.c helpers.h \
+ webView.c webView.h \
+ sokoke.c sokoke.h \
+ conf.c conf.h \
+ search.c search.h \
+ xbel.c xbel.h \
+ global.h \
+ ui.h \
+ debug.h
diff --git a/src/browser.c b/src/browser.c
index f98d4016..8dac19a5 100644
--- a/src/browser.c
+++ b/src/browser.c
@@ -18,6 +18,7 @@
#include "webView.h"
#include "webSearch.h"
#include "xbel.h"
+#include "../katze/katze.h"
#include <gdk/gdkkeysyms.h>
#include <string.h>
@@ -1190,7 +1191,7 @@ CBrowser* browser_new(CBrowser* oldBrowser)
browser->menubar = gtk_ui_manager_get_widget(ui_manager, "/menubar");
GtkWidget* menuitem = gtk_menu_item_new();
gtk_widget_show(menuitem);
- browser->throbber = gtk_image_new_from_stock(GTK_STOCK_EXECUTE, GTK_ICON_SIZE_MENU);
+ browser->throbber = katze_throbber_new();
gtk_widget_show(browser->throbber);
gtk_container_add(GTK_CONTAINER(menuitem), browser->throbber);
gtk_widget_set_sensitive(menuitem, FALSE);
@@ -1561,7 +1562,9 @@ CBrowser* browser_new(CBrowser* oldBrowser)
, G_CALLBACK(on_notebook_tab_mouse_up), browser);
GtkWidget* hbox = gtk_hbox_new(FALSE, 1);
gtk_container_add(GTK_CONTAINER(eventbox), GTK_WIDGET(hbox));
- browser->webView_icon = gtk_image_new_from_stock(GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
+ browser->webView_icon = katze_throbber_new();
+ katze_throbber_set_static_stock_id(KATZE_THROBBER(browser->webView_icon)
+ , GTK_STOCK_FILE);
gtk_box_pack_start(GTK_BOX(hbox), browser->webView_icon, FALSE, FALSE, 0);
browser->webView_name = gtk_label_new(xbel_item_get_title(browser->sessionItem));
gtk_misc_set_alignment(GTK_MISC(browser->webView_name), 0.0, 0.5);
diff --git a/src/helpers.c b/src/helpers.c
index 2981931c..74ed68e6 100644
--- a/src/helpers.c
+++ b/src/helpers.c
@@ -13,6 +13,7 @@
#include "search.h"
#include "sokoke.h"
+#include "../katze/katze.h"
#include <string.h>
#include <webkit.h>
@@ -231,14 +232,11 @@ void update_favicon(CBrowser* browser)
// TODO: Retrieve mime type and load icon; don't forget ftp listings
}
else
- gtk_image_set_from_stock(GTK_IMAGE(browser->webView_icon)
- , GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
- }
- else
- {
- gtk_image_set_from_stock(GTK_IMAGE(browser->webView_icon)
- , GTK_STOCK_EXECUTE, GTK_ICON_SIZE_MENU);
+ katze_throbber_set_static_stock_id(KATZE_THROBBER(browser->webView_icon)
+ , GTK_STOCK_FILE);
}
+ katze_throbber_set_animated(KATZE_THROBBER(browser->webView_icon)
+ , browser->loadedPercent != -1);
}
void update_security(CBrowser* browser)
@@ -382,6 +380,8 @@ void update_gui_state(CBrowser* browser)
g_object_set(action, "tooltip", "Stop loading the current page", NULL);
gtk_widget_show(browser->progress);
}
+ katze_throbber_set_animated(KATZE_THROBBER(browser->throbber)
+ , browser->loadedPercent != -1);
gtk_image_set_from_stock(GTK_IMAGE(browser->location_icon), GTK_STOCK_FILE
, GTK_ICON_SIZE_MENU);