1 /* GTK - The GIMP Toolkit
3 * Copyright (C) 2009 Matthias Clasen <mclasen@redhat.com>
4 * Copyright (C) 2008 Richard Hughes <richard@hughsie.com>
5 * Copyright (C) 2009 Bastien Nocera <hadess@hadess.net>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * Modified by the GTK+ Team and others 2007. See the AUTHORS
25 * file for a list of people on the GTK+ Team. See the ChangeLog
26 * files for a list of changes. These files are distributed with
27 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
32 #include "gtkcellrendererspinner.h"
33 #include "gtkiconfactory.h"
34 #include "gtkicontheme.h"
35 #include "gtktypebuiltins.h"
39 #undef GDK_DEPRECATED_FOR
40 #define GDK_DEPRECATED
41 #define GDK_DEPRECATED_FOR(f)
42 #undef GTK_DISABLE_DEPRECATED
44 #include "deprecated/gtkstyle.h"
48 * SECTION:gtkcellrendererspinner
49 * @Short_description: Renders a spinning animation in a cell
50 * @Title: GtkCellRendererSpinner
51 * @See_also: #GtkSpinner, #GtkCellRendererProgress
53 * GtkCellRendererSpinner renders a spinning animation in a cell, very
54 * similar to #GtkSpinner. It can often be used as an alternative
55 * to a #GtkCellRendererProgress for displaying indefinite activity,
56 * instead of actual progress.
58 * To start the animation in a cell, set the #GtkCellRendererSpinner:active
59 * property to %TRUE and increment the #GtkCellRendererSpinner:pulse property
60 * at regular intervals. The usual way to set the cell renderer properties
61 * for each cell is to bind them to columns in your tree model using e.g.
62 * gtk_tree_view_column_add_attribute().
73 struct _GtkCellRendererSpinnerPrivate
77 GtkIconSize icon_size, old_icon_size;
82 static void gtk_cell_renderer_spinner_get_property (GObject *object,
86 static void gtk_cell_renderer_spinner_set_property (GObject *object,
90 static void gtk_cell_renderer_spinner_get_size (GtkCellRenderer *cell,
92 const GdkRectangle *cell_area,
97 static void gtk_cell_renderer_spinner_render (GtkCellRenderer *cell,
100 const GdkRectangle *background_area,
101 const GdkRectangle *cell_area,
102 GtkCellRendererState flags);
104 G_DEFINE_TYPE (GtkCellRendererSpinner, gtk_cell_renderer_spinner, GTK_TYPE_CELL_RENDERER)
107 gtk_cell_renderer_spinner_class_init (GtkCellRendererSpinnerClass *klass)
109 GObjectClass *object_class = G_OBJECT_CLASS (klass);
110 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
112 object_class->get_property = gtk_cell_renderer_spinner_get_property;
113 object_class->set_property = gtk_cell_renderer_spinner_set_property;
115 cell_class->get_size = gtk_cell_renderer_spinner_get_size;
116 cell_class->render = gtk_cell_renderer_spinner_render;
118 /* GtkCellRendererSpinner:active:
120 * Whether the spinner is active (ie. shown) in the cell
124 g_object_class_install_property (object_class,
126 g_param_spec_boolean ("active",
128 P_("Whether the spinner is active (ie. shown) in the cell"),
132 * GtkCellRendererSpinner:pulse:
134 * Pulse of the spinner. Increment this value to draw the next frame of the
135 * spinner animation. Usually, you would update this value in a timeout.
137 * By default, the #GtkSpinner widget draws one full cycle of the animation,
138 * consisting of 12 frames, in 750 milliseconds.
142 g_object_class_install_property (object_class,
144 g_param_spec_uint ("pulse",
146 P_("Pulse of the spinner"),
150 * GtkCellRendererSpinner:size:
152 * The #GtkIconSize value that specifies the size of the rendered spinner.
156 g_object_class_install_property (object_class,
158 g_param_spec_enum ("size",
160 P_("The GtkIconSize value that specifies the size of the rendered spinner"),
161 GTK_TYPE_ICON_SIZE, GTK_ICON_SIZE_MENU,
165 g_type_class_add_private (object_class, sizeof (GtkCellRendererSpinnerPrivate));
169 gtk_cell_renderer_spinner_init (GtkCellRendererSpinner *cell)
171 cell->priv = G_TYPE_INSTANCE_GET_PRIVATE (cell,
172 GTK_TYPE_CELL_RENDERER_SPINNER,
173 GtkCellRendererSpinnerPrivate);
175 cell->priv->pulse = 0;
176 cell->priv->old_icon_size = GTK_ICON_SIZE_INVALID;
177 cell->priv->icon_size = GTK_ICON_SIZE_MENU;
181 * gtk_cell_renderer_spinner_new:
183 * Returns a new cell renderer which will show a spinner to indicate
186 * Return value: a new #GtkCellRenderer
191 gtk_cell_renderer_spinner_new (void)
193 return g_object_new (GTK_TYPE_CELL_RENDERER_SPINNER, NULL);
197 gtk_cell_renderer_spinner_update_size (GtkCellRendererSpinner *cell,
200 GtkCellRendererSpinnerPrivate *priv = cell->priv;
202 GtkSettings *settings;
204 if (priv->old_icon_size == priv->icon_size)
207 screen = gtk_widget_get_screen (GTK_WIDGET (widget));
208 settings = gtk_settings_get_for_screen (screen);
210 if (!gtk_icon_size_lookup_for_settings (settings, priv->icon_size, &priv->size, NULL))
212 g_warning ("Invalid icon size %u\n", priv->icon_size);
218 gtk_cell_renderer_spinner_get_property (GObject *object,
223 GtkCellRendererSpinner *cell = GTK_CELL_RENDERER_SPINNER (object);
224 GtkCellRendererSpinnerPrivate *priv = cell->priv;
229 g_value_set_boolean (value, priv->active);
232 g_value_set_uint (value, priv->pulse);
235 g_value_set_enum (value, priv->icon_size);
238 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
243 gtk_cell_renderer_spinner_set_property (GObject *object,
248 GtkCellRendererSpinner *cell = GTK_CELL_RENDERER_SPINNER (object);
249 GtkCellRendererSpinnerPrivate *priv = cell->priv;
254 priv->active = g_value_get_boolean (value);
257 priv->pulse = g_value_get_uint (value);
260 priv->old_icon_size = priv->icon_size;
261 priv->icon_size = g_value_get_enum (value);
264 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
269 gtk_cell_renderer_spinner_get_size (GtkCellRenderer *cellr,
271 const GdkRectangle *cell_area,
277 GtkCellRendererSpinner *cell = GTK_CELL_RENDERER_SPINNER (cellr);
278 GtkCellRendererSpinnerPrivate *priv = cell->priv;
282 gfloat xalign, yalign;
285 rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
287 gtk_cell_renderer_spinner_update_size (cell, widget);
301 align = rtl ? 1.0 - xalign : xalign;
302 *x_offset = align * (cell_area->width - w);
303 *x_offset = MAX (*x_offset, 0);
307 align = rtl ? 1.0 - yalign : yalign;
308 *y_offset = align * (cell_area->height - h);
309 *y_offset = MAX (*y_offset, 0);
327 gtk_cell_renderer_spinner_render (GtkCellRenderer *cellr,
330 const GdkRectangle *background_area,
331 const GdkRectangle *cell_area,
332 GtkCellRendererState flags)
334 GtkCellRendererSpinner *cell = GTK_CELL_RENDERER_SPINNER (cellr);
335 GtkCellRendererSpinnerPrivate *priv = cell->priv;
337 GdkRectangle pix_rect;
338 GdkRectangle draw_rect;
344 gtk_cell_renderer_spinner_get_size (cellr, widget, (GdkRectangle *) cell_area,
345 &pix_rect.x, &pix_rect.y,
346 &pix_rect.width, &pix_rect.height);
352 pix_rect.x += cell_area->x + xpad;
353 pix_rect.y += cell_area->y + ypad;
354 pix_rect.width -= xpad * 2;
355 pix_rect.height -= ypad * 2;
357 if (!gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect))
360 state = GTK_STATE_NORMAL;
361 if (gtk_widget_get_state (widget) == GTK_STATE_INSENSITIVE ||
362 !gtk_cell_renderer_get_sensitive (cellr))
364 state = GTK_STATE_INSENSITIVE;
368 if ((flags & GTK_CELL_RENDERER_SELECTED) != 0)
370 if (gtk_widget_has_focus (widget))
371 state = GTK_STATE_SELECTED;
373 state = GTK_STATE_ACTIVE;
376 state = GTK_STATE_PRELIGHT;
381 gdk_cairo_rectangle (cr, cell_area);
384 gtk_paint_spinner (gtk_widget_get_style (widget),
390 draw_rect.x, draw_rect.y,
391 draw_rect.width, draw_rect.height);