summaryrefslogtreecommitdiff
path: root/gtk/gtkcellrendererspinner.c
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2009-07-21 02:16:56 +0100
committerBastien Nocera <hadess@hadess.net>2009-10-14 14:58:30 +0100
commitd21700f5105c2e4b215aa2b4d4f8c90121748cda (patch)
treeb03eb0b607309e6eb10b92c97bd333d0485f79b3 /gtk/gtkcellrendererspinner.c
parentdf53e6ad8b8939f1e7bb9a48987f972fec6cfa4c (diff)
downloadgtk+-d21700f5105c2e4b215aa2b4d4f8c90121748cda.tar.gz
Bug 319607 – Add a throbber (activity widget) to GTK+
Add GtkSpinner activity throbber, as well as a cell renderer.
Diffstat (limited to 'gtk/gtkcellrendererspinner.c')
-rw-r--r--gtk/gtkcellrendererspinner.c362
1 files changed, 362 insertions, 0 deletions
diff --git a/gtk/gtkcellrendererspinner.c b/gtk/gtkcellrendererspinner.c
new file mode 100644
index 0000000000..6501b267c8
--- /dev/null
+++ b/gtk/gtkcellrendererspinner.c
@@ -0,0 +1,362 @@
+/* GTK - The GIMP Toolkit
+ *
+ * Copyright (C) 2009 Matthias Clasen <mclasen@redhat.com>
+ * Copyright (C) 2008 Richard Hughes <richard@hughsie.com>
+ * Copyright (C) 2009 Bastien Nocera <hadess@hadess.net>
+ *
+ * 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 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 2007. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+
+#include "gtkintl.h"
+#include <gtk/gtk.h>
+#include "gtkcellrendererspinner.h"
+#include "gtkalias.h"
+
+enum {
+ PROP_0,
+ PROP_ACTIVE,
+ PROP_PULSE,
+ PROP_SIZE
+};
+
+struct _GtkCellRendererSpinnerPrivate
+{
+ gboolean active;
+ guint pulse;
+ GtkIconSize icon_size, old_icon_size;
+ gint size;
+};
+
+#define GTK_CELL_RENDERER_SPINNER_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), \
+ GTK_TYPE_CELL_RENDERER_SPINNER, \
+ GtkCellRendererSpinnerPrivate))
+
+static void gtk_cell_renderer_spinner_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gtk_cell_renderer_spinner_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_cell_renderer_spinner_get_size (GtkCellRenderer *cell,
+ GtkWidget *widget,
+ GdkRectangle *cell_area,
+ gint *x_offset,
+ gint *y_offset,
+ gint *width,
+ gint *height);
+static void gtk_cell_renderer_spinner_render (GtkCellRenderer *cell,
+ GdkWindow *window,
+ GtkWidget *widget,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GdkRectangle *expose_area,
+ guint flags);
+
+G_DEFINE_TYPE (GtkCellRendererSpinner, gtk_cell_renderer_spinner, GTK_TYPE_CELL_RENDERER)
+
+static void
+gtk_cell_renderer_spinner_class_init (GtkCellRendererSpinnerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
+
+ object_class->get_property = gtk_cell_renderer_spinner_get_property;
+ object_class->set_property = gtk_cell_renderer_spinner_set_property;
+
+ cell_class->get_size = gtk_cell_renderer_spinner_get_size;
+ cell_class->render = gtk_cell_renderer_spinner_render;
+
+ /* GtkCellRendererSpinner::active:
+ *
+ * Whether the spinner is active (ie. shown) in the cell
+ *
+ * Since 2.20
+ */
+ g_object_class_install_property (object_class,
+ PROP_ACTIVE,
+ g_param_spec_boolean ("active",
+ P_("Active"),
+ P_("Whether the spinner is active (ie. shown) in the cell"),
+ FALSE,
+ G_PARAM_READWRITE));
+ /* GtkCellRendererSpinner::pulse:
+ *
+ * Pulse of the spinner. Increment this value to draw the next frame of the spinner animation.
+ * Usually, you would update this value in a timeout, every 80 milliseconds to show a full
+ * animation within one second.
+ *
+ * Since 2.20
+ */
+ g_object_class_install_property (object_class,
+ PROP_PULSE,
+ g_param_spec_uint ("pulse",
+ P_("Pulse"),
+ P_("Pulse of the spinner"),
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE));
+ /* GtkCellRendererSpinner::size:
+ *
+ * The #GtkIconSize value that specifies the size of the rendered spinner.
+ *
+ * Since 2.20
+ */
+ g_object_class_install_property (object_class,
+ PROP_SIZE,
+ g_param_spec_enum ("size",
+ P_("Size"),
+ P_("The #GtkIconSize value that specifies the size of the rendered spinner"),
+ GTK_TYPE_ICON_SIZE, GTK_ICON_SIZE_MENU,
+ G_PARAM_READWRITE));
+
+
+ g_type_class_add_private (object_class, sizeof (GtkCellRendererSpinnerPrivate));
+}
+
+static void
+gtk_cell_renderer_spinner_init (GtkCellRendererSpinner *cell)
+{
+ cell->priv = GTK_CELL_RENDERER_SPINNER_GET_PRIVATE (cell);
+ cell->priv->pulse = 0;
+ cell->priv->old_icon_size = GTK_ICON_SIZE_INVALID;
+ cell->priv->icon_size = GTK_ICON_SIZE_MENU;
+}
+
+/**
+ * gtk_cell_renderer_spinner_new
+ *
+ * Returns a new cell renderer which will show a spinner to indicate
+ * activity.
+ *
+ * Return value: a new #GtkCellRenderer
+ *
+ * Since: 2.20
+ */
+GtkCellRenderer *
+gtk_cell_renderer_spinner_new (void)
+{
+ return g_object_new (GTK_TYPE_CELL_RENDERER_SPINNER, NULL);
+}
+
+static void
+gtk_cell_renderer_spinner_update_size (GtkCellRendererSpinner *cell,
+ GtkWidget *widget)
+{
+ GtkCellRendererSpinnerPrivate *priv = cell->priv;
+ GdkScreen *screen;
+ GtkIconTheme *icon_theme;
+ GtkSettings *settings;
+
+ if (cell->priv->old_icon_size == cell->priv->icon_size)
+ return;
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (widget));
+ icon_theme = gtk_icon_theme_get_for_screen (screen);
+ settings = gtk_settings_get_for_screen (screen);
+
+ if (!gtk_icon_size_lookup_for_settings (settings, priv->icon_size, &priv->size, NULL))
+ {
+ g_warning ("Invalid icon size %u\n", priv->icon_size);
+ priv->size = 24;
+ }
+}
+
+static void
+gtk_cell_renderer_spinner_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkCellRendererSpinner *cell = GTK_CELL_RENDERER_SPINNER (object);
+ GtkCellRendererSpinnerPrivate *priv = cell->priv;
+
+ switch (param_id)
+ {
+ case PROP_ACTIVE:
+ g_value_set_boolean (value, priv->active);
+ break;
+ case PROP_PULSE:
+ g_value_set_uint (value, priv->pulse);
+ break;
+ case PROP_SIZE:
+ g_value_set_enum (value, priv->icon_size);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ }
+}
+
+static void
+gtk_cell_renderer_spinner_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkCellRendererSpinner *cell = GTK_CELL_RENDERER_SPINNER (object);
+ GtkCellRendererSpinnerPrivate *priv = cell->priv;
+
+ switch (param_id)
+ {
+ case PROP_ACTIVE:
+ priv->active = g_value_get_boolean (value);
+ break;
+ case PROP_PULSE:
+ priv->pulse = g_value_get_uint (value);
+ break;
+ case PROP_SIZE:
+ priv->old_icon_size = priv->icon_size;
+ priv->icon_size = g_value_get_enum (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ }
+}
+
+static void
+gtk_cell_renderer_spinner_get_size (GtkCellRenderer *cellr,
+ GtkWidget *widget,
+ GdkRectangle *cell_area,
+ gint *x_offset,
+ gint *y_offset,
+ gint *width,
+ gint *height)
+{
+ GtkCellRendererSpinner *cell = GTK_CELL_RENDERER_SPINNER (cellr);
+ GtkCellRendererSpinnerPrivate *priv = cell->priv;
+ gdouble align;
+ gint w, h;
+ gint xpad, ypad;
+ gfloat xalign, yalign;
+ gboolean rtl;
+
+ rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+
+ gtk_cell_renderer_spinner_update_size (cell, widget);
+
+ g_object_get (cellr,
+ "xpad", &xpad,
+ "ypad", &ypad,
+ "xalign", &xalign,
+ "yalign", &yalign,
+ NULL);
+ w = h = priv->size;
+
+ if (cell_area)
+ {
+ if (x_offset)
+ {
+ align = rtl ? 1.0 - xalign : xalign;
+ *x_offset = align * (cell_area->width - w);
+ *x_offset = MAX (*x_offset, 0);
+ }
+ if (y_offset)
+ {
+ align = rtl ? 1.0 - yalign : yalign;
+ *y_offset = align * (cell_area->height - h);
+ *y_offset = MAX (*y_offset, 0);
+ }
+ }
+ else
+ {
+ if (x_offset)
+ *x_offset = 0;
+ if (y_offset)
+ *y_offset = 0;
+ }
+
+ if (width)
+ *width = w;
+ if (height)
+ *height = h;
+}
+
+static void
+gtk_cell_renderer_spinner_render (GtkCellRenderer *cellr,
+ GdkWindow *window,
+ GtkWidget *widget,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GdkRectangle *expose_area,
+ guint flags)
+{
+ GtkCellRendererSpinner *cell = GTK_CELL_RENDERER_SPINNER (cellr);
+ GtkCellRendererSpinnerPrivate *priv = cell->priv;
+ GtkStateType state;
+ GdkRectangle pix_rect;
+ GdkRectangle draw_rect;
+ gint xpad, ypad;
+
+ if (!priv->active)
+ return;
+
+ gtk_cell_renderer_spinner_get_size (cellr, widget, cell_area,
+ &pix_rect.x, &pix_rect.y,
+ &pix_rect.width, &pix_rect.height);
+
+ g_object_get (cellr,
+ "xpad", &xpad,
+ "ypad", &ypad,
+ NULL);
+ pix_rect.x += cell_area->x + xpad;
+ pix_rect.y += cell_area->y + ypad;
+ pix_rect.width -= xpad * 2;
+ pix_rect.height -= ypad * 2;
+
+ if (!gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect) ||
+ !gdk_rectangle_intersect (expose_area, &pix_rect, &draw_rect))
+ {
+ return;
+ }
+
+ state = GTK_STATE_NORMAL;
+ if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE || !cellr->sensitive)
+ {
+ state = GTK_STATE_INSENSITIVE;
+ }
+ else
+ {
+ if ((flags & GTK_CELL_RENDERER_SELECTED) != 0)
+ {
+ if (GTK_WIDGET_HAS_FOCUS (widget))
+ state = GTK_STATE_SELECTED;
+ else
+ state = GTK_STATE_ACTIVE;
+ }
+ else
+ state = GTK_STATE_PRELIGHT;
+ }
+
+ gtk_paint_spinner (widget->style,
+ window,
+ state,
+ priv->pulse,
+ draw_rect.x, draw_rect.y,
+ draw_rect.width, draw_rect.height);
+}
+
+#define __GTK_CELL_RENDERER_SPINNER_C__
+#include "gtkaliasdef.c"