1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
3
* @file libbling/bling-spinner.c A apple-esque spinner widger
5
* @Copyright (C) 2007 John Stowers, Neil Jagdish Patel.
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.
22
* Code adapted from egg-spinner
23
* by Christian Hergert <christian.hergert@gmail.com>
33
#include "nma-bling-spinner.h"
35
#define NMA_BLING_SPINNER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NMA_TYPE_BLING_SPINNER, NmaBlingSpinnerPrivate))
37
G_DEFINE_TYPE (NmaBlingSpinner, nma_bling_spinner, GTK_TYPE_DRAWING_AREA);
46
struct _NmaBlingSpinnerPrivate
57
static void nma_bling_spinner_class_init(NmaBlingSpinnerClass *klass);
58
static void nma_bling_spinner_init(NmaBlingSpinner *spinner);
59
static void nma_bling_spinner_finalize (GObject *gobject);
60
static void nma_bling_spinner_set_property(GObject *gobject, guint prop_id, const GValue *value, GParamSpec *pspec);
61
static gboolean nma_bling_spinner_expose(GtkWidget *widget, GdkEventExpose *event);
62
static void nma_bling_spinner_screen_changed (GtkWidget* widget, GdkScreen* old_screen);
64
static GtkDrawingAreaClass *parent_class;
66
/* DRAWING FUNCTIONS */
68
draw (GtkWidget *widget, cairo_t *cr)
70
NmaBlingSpinnerPrivate *priv;
71
GtkAllocation allocation;
77
priv = NMA_BLING_SPINNER_GET_PRIVATE (widget);
79
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
81
#if GTK_CHECK_VERSION(2,18,0)
82
gtk_widget_get_allocation (widget, &allocation);
84
allocation = widget->allocation;
86
if ((allocation.width < 12) || (allocation.height < 12))
87
gtk_widget_set_size_request(widget, 12, 12);
89
//x = allocation.x + allocation.width / 2;
90
//y = allocation.y + allocation.height / 2;
91
x = allocation.width / 2;
92
y = allocation.height / 2;
93
radius = MIN (allocation.width / 2, allocation.height / 2);
94
half = priv->lines / 2;
96
/*FIXME: render in B&W for non transparency */
98
for (i = 0; i < priv->lines; i++) {
99
int inset = 0.7 * radius;
100
/* transparency is a function of time and intial value */
101
double t = (double) ((i + priv->lines - priv->current)
102
% priv->lines) / priv->lines;
106
cairo_set_source_rgba (cr, 0, 0, 0, t);
107
//cairo_set_line_width (cr, 2 * cairo_get_line_width (cr));
108
cairo_set_line_width (cr, 2.0);
110
x + (radius - inset) * cos (i * M_PI / half),
111
y + (radius - inset) * sin (i * M_PI / half));
113
x + radius * cos (i * M_PI / half),
114
y + radius * sin (i * M_PI / half));
122
/* GOBJECT INIT CODE */
124
nma_bling_spinner_class_init(NmaBlingSpinnerClass *klass)
126
GObjectClass *gobject_class;
127
GtkWidgetClass *widget_class;
129
parent_class = g_type_class_peek_parent(klass);
131
gobject_class = G_OBJECT_CLASS(klass);
132
g_type_class_add_private (gobject_class, sizeof (NmaBlingSpinnerPrivate));
133
gobject_class->set_property = nma_bling_spinner_set_property;
134
gobject_class->finalize = nma_bling_spinner_finalize;
136
widget_class = GTK_WIDGET_CLASS(klass);
137
widget_class->expose_event = nma_bling_spinner_expose;
138
widget_class->screen_changed = nma_bling_spinner_screen_changed;
140
g_object_class_install_property(gobject_class, PROP_NUM_LINES,
141
g_param_spec_uint("lines", "Num Lines",
142
"The number of lines to animate",
144
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
149
nma_bling_spinner_init (NmaBlingSpinner *spinner)
151
NmaBlingSpinnerPrivate *priv;
153
priv = NMA_BLING_SPINNER_GET_PRIVATE (spinner);
157
#if GTK_CHECK_VERSION(2,18,0)
158
gtk_widget_set_has_window (GTK_WIDGET (spinner), FALSE);
160
GTK_WIDGET_SET_FLAGS (GTK_WIDGET (spinner), GTK_NO_WINDOW);
165
nma_bling_spinner_expose (GtkWidget *widget, GdkEventExpose *event)
169
/* get cairo context */
170
cr = gdk_cairo_create (gtk_widget_get_window (widget));
172
/* set a clip region for the expose event */
174
event->area.x, event->area.y,
175
event->area.width, event->area.height);
178
cairo_translate (cr, event->area.x, event->area.y);
180
/* draw clip region */
190
nma_bling_spinner_screen_changed (GtkWidget* widget, GdkScreen* old_screen)
192
NmaBlingSpinner *spinner;
193
GdkScreen* new_screen;
194
GdkColormap* colormap;
196
spinner = NMA_BLING_SPINNER(widget);
198
new_screen = gtk_widget_get_screen (widget);
199
colormap = gdk_screen_get_rgba_colormap (new_screen);
202
colormap = gdk_screen_get_rgb_colormap (new_screen);
204
gtk_widget_set_colormap (widget, colormap);
208
nma_bling_spinner_timeout (gpointer data)
210
NmaBlingSpinner *spinner;
211
NmaBlingSpinnerPrivate *priv;
213
spinner = NMA_BLING_SPINNER (data);
214
priv = NMA_BLING_SPINNER_GET_PRIVATE (spinner);
216
if (priv->current + 1 >= priv->lines) {
222
gtk_widget_queue_draw (GTK_WIDGET (data));
228
nma_bling_spinner_set_property(GObject *gobject, guint prop_id,
229
const GValue *value, GParamSpec *pspec)
231
NmaBlingSpinner *spinner;
232
NmaBlingSpinnerPrivate *priv;
234
spinner = NMA_BLING_SPINNER(gobject);
235
priv = NMA_BLING_SPINNER_GET_PRIVATE (spinner);
240
priv->lines = g_value_get_uint(value);
243
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
249
nma_bling_spinner_finalize (GObject *gobject)
251
NmaBlingSpinner *spinner;
252
NmaBlingSpinnerPrivate *priv;
254
spinner = NMA_BLING_SPINNER(gobject);
255
priv = NMA_BLING_SPINNER_GET_PRIVATE (spinner);
257
if (priv->timeout != 0) {
258
g_source_remove (priv->timeout);
264
* nma_bling_spinner_new
266
* Returns a default spinner. Not yet started.
268
* Returns: a new #NmaBlingSpinner
271
nma_bling_spinner_new (void)
273
return g_object_new (NMA_TYPE_BLING_SPINNER, NULL);
277
* nma_bling_spinner_start
279
* Starts the animation
282
nma_bling_spinner_start (NmaBlingSpinner *spinner)
284
NmaBlingSpinnerPrivate *priv;
286
g_return_if_fail (NMA_IS_BLING_SPINNER (spinner));
288
priv = NMA_BLING_SPINNER_GET_PRIVATE (spinner);
289
if (priv->timeout != 0)
291
priv->timeout = g_timeout_add (80, nma_bling_spinner_timeout, spinner);
295
* nma_bling_spinner_stop
297
* Stops the animation
300
nma_bling_spinner_stop (NmaBlingSpinner *spinner)
302
NmaBlingSpinnerPrivate *priv;
304
g_return_if_fail (NMA_IS_BLING_SPINNER (spinner));
306
priv = NMA_BLING_SPINNER_GET_PRIVATE (spinner);
307
if (priv->timeout == 0)
309
g_source_remove (priv->timeout);