3
* Copyright (c) 2007 Nick Schermer <nick@xfce.org>
2
* Copyright (C) 2007-2010 Nick Schermer <nick@xfce.org>
5
* This program is free software; you can redistribute it and/or modify it
4
* This library is free software; you can redistribute it and/or modify it
6
5
* under the terms of the GNU General Public License as published by the Free
7
6
* Software Foundation; either version 2 of the License, or (at your option)
10
* This program is distributed in the hope that it will be useful, but WITHOUT
9
* This library is distributed in the hope that it will be useful, but WITHOUT
11
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15
* You should have received a copy of the GNU General Public License along with
16
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17
* Place, Suite 330, Boston, MA 02111-1307 USA
14
* You should have received a copy of the GNU Library General Public License
15
* along with this library; if not, write to the Free Software Foundation,
16
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20
19
#ifdef HAVE_CONFIG_H
64
static gboolean xfce_clock_analog_update (gpointer user_data);
81
76
struct _XfceClockAnalogClass
83
GtkImageClass __parent__;
78
GtkImageClass __parent__;
86
81
struct _XfceClockAnalog
91
guint show_seconds : 1;
85
ClockPluginTimeout *timeout;
87
guint show_seconds : 1;
96
G_DEFINE_TYPE (XfceClockAnalog, xfce_clock_analog, GTK_TYPE_IMAGE);
92
XFCE_PANEL_DEFINE_TYPE (XfceClockAnalog, xfce_clock_analog, GTK_TYPE_IMAGE)
101
97
xfce_clock_analog_class_init (XfceClockAnalogClass *klass)
103
GObjectClass *gobject_class;
104
GtkWidgetClass *gtkwidget_class;
106
gobject_class = G_OBJECT_CLASS (klass);
107
gobject_class->finalize = xfce_clock_analog_finalize;
108
gobject_class->set_property = xfce_clock_analog_set_property;
109
gobject_class->get_property = xfce_clock_analog_get_property;
111
gtkwidget_class = GTK_WIDGET_CLASS (klass);
112
gtkwidget_class->size_request = xfce_clock_analog_size_request;
113
gtkwidget_class->expose_event = xfce_clock_analog_expose_event;
116
* Whether we display seconds
118
g_object_class_install_property (gobject_class,
120
g_param_spec_boolean ("show-seconds", "show-seconds", "show-seconds",
121
FALSE, PANEL_PARAM_READWRITE));
99
GObjectClass *gobject_class;
100
GtkWidgetClass *gtkwidget_class;
102
gobject_class = G_OBJECT_CLASS (klass);
103
gobject_class->set_property = xfce_clock_analog_set_property;
104
gobject_class->get_property = xfce_clock_analog_get_property;
105
gobject_class->finalize = xfce_clock_analog_finalize;
107
gtkwidget_class = GTK_WIDGET_CLASS (klass);
108
gtkwidget_class->expose_event = xfce_clock_analog_expose_event;
110
g_object_class_install_property (gobject_class,
112
g_param_spec_double ("size-ratio", NULL, NULL,
113
-1, G_MAXDOUBLE, 1.0,
115
| G_PARAM_STATIC_STRINGS));
117
g_object_class_install_property (gobject_class,
119
g_param_spec_enum ("orientation", NULL, NULL,
120
GTK_TYPE_ORIENTATION,
121
GTK_ORIENTATION_HORIZONTAL,
123
| G_PARAM_STATIC_STRINGS));
125
g_object_class_install_property (gobject_class,
127
g_param_spec_boolean ("show-seconds", NULL, NULL,
130
| G_PARAM_STATIC_STRINGS));
146
149
const GValue *value,
147
150
GParamSpec *pspec)
149
XfceClockAnalog *analog = XFCE_CLOCK_ANALOG (object);
152
XfceClockAnalog *analog = XFCE_CLOCK_ANALOG (object);
153
case PROP_SHOW_SECONDS:
154
analog->show_seconds = g_value_get_boolean (value);
158
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
156
case PROP_ORIENTATION:
159
case PROP_SHOW_SECONDS:
160
analog->show_seconds = g_value_get_boolean (value);
164
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
168
/* reschedule the timeout and redraw */
169
clock_plugin_timeout_set_interval (analog->timeout,
170
analog->show_seconds ? CLOCK_INTERVAL_SECOND : CLOCK_INTERVAL_MINUTE);
171
xfce_clock_analog_update (analog);
169
180
GParamSpec *pspec)
171
XfceClockAnalog *analog = XFCE_CLOCK_ANALOG (object);
182
XfceClockAnalog *analog = XFCE_CLOCK_ANALOG (object);
175
case PROP_SHOW_SECONDS:
176
g_value_set_boolean (value, analog->show_seconds);
180
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
186
case PROP_SHOW_SECONDS:
187
g_value_set_boolean (value, analog->show_seconds);
190
case PROP_SIZE_RATIO:
191
g_value_set_double (value, 1.0);
195
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
188
xfce_clock_analog_size_request (GtkWidget *widget,
189
GtkRequisition *requisition)
203
xfce_clock_analog_finalize (GObject *object)
193
/* get the current widget size */
194
gtk_widget_get_size_request (widget, &width, &height);
196
/* square the widget */
197
requisition->width = requisition->height = MAX (width, height);
205
/* stop the timeout */
206
clock_plugin_timeout_free (XFCE_CLOCK_ANALOG (object)->timeout);
208
(*G_OBJECT_CLASS (xfce_clock_analog_parent_class)->finalize) (object);
203
214
xfce_clock_analog_expose_event (GtkWidget *widget,
204
215
GdkEventExpose *event)
206
XfceClockAnalog *analog = XFCE_CLOCK_ANALOG (widget);
208
gdouble angle, radius;
212
g_return_val_if_fail (XFCE_CLOCK_IS_ANALOG (analog), FALSE);
214
/* get center of the widget and the radius */
215
xc = (widget->allocation.width / 2.0);
216
yc = (widget->allocation.height / 2.0);
217
radius = MIN (xc, yc);
219
/* add the window offset */
220
xc += widget->allocation.x;
221
yc += widget->allocation.y;
223
/* get the cairo context */
224
cr = gdk_cairo_create (widget->window);
226
if (G_LIKELY (cr != NULL))
217
XfceClockAnalog *analog = XFCE_CLOCK_ANALOG (widget);
219
gdouble angle, radius;
223
panel_return_val_if_fail (XFCE_CLOCK_IS_ANALOG (analog), FALSE);
225
/* get center of the widget and the radius */
226
xc = (widget->allocation.width / 2.0);
227
yc = (widget->allocation.height / 2.0);
228
radius = MIN (xc, yc);
230
/* add the window offset */
231
xc += widget->allocation.x;
232
yc += widget->allocation.y;
234
/* get the cairo context */
235
cr = gdk_cairo_create (widget->window);
237
if (G_LIKELY (cr != NULL))
228
/* clip the drawing area */
229
gdk_cairo_rectangle (cr, &event->area);
232
/* get the local time */
233
xfce_clock_util_get_localtime (&tm);
235
/* set the line properties */
236
cairo_set_line_width (cr, 1);
237
gdk_cairo_set_source_color (cr, &widget->style->fg[GTK_STATE_NORMAL]);
240
xfce_clock_analog_draw_ticks (cr, xc, yc, radius);
242
if (analog->show_seconds)
239
/* clip the drawing region */
240
gdk_cairo_rectangle (cr, &event->area);
243
/* get the local time */
244
clock_plugin_get_localtime (&tm);
246
/* set the line properties */
247
cairo_set_line_width (cr, 1);
248
gdk_cairo_set_source_color (cr, &widget->style->fg[GTK_WIDGET_STATE (widget)]);
251
xfce_clock_analog_draw_ticks (cr, xc, yc, radius);
253
if (analog->show_seconds)
245
angle = TICKS_TO_RADIANS (tm.tm_sec);
246
xfce_clock_analog_draw_pointer (cr, xc, yc, radius, angle, 0.7, TRUE);
256
angle = TICKS_TO_RADIANS (tm.tm_sec);
257
xfce_clock_analog_draw_pointer (cr, xc, yc, radius, angle, 0.7, TRUE);
250
angle = TICKS_TO_RADIANS (tm.tm_min);
251
xfce_clock_analog_draw_pointer (cr, xc, yc, radius, angle, 0.8, FALSE);
254
angle = HOURS_TO_RADIANS (tm.tm_hour, tm.tm_min);
255
xfce_clock_analog_draw_pointer (cr, xc, yc, radius, angle, 0.5, FALSE);
261
angle = TICKS_TO_RADIANS (tm.tm_min);
262
xfce_clock_analog_draw_pointer (cr, xc, yc, radius, angle, 0.8, FALSE);
265
angle = HOURS_TO_RADIANS (tm.tm_hour, tm.tm_min);
266
xfce_clock_analog_draw_pointer (cr, xc, yc, radius, angle, 0.5, FALSE);
275
for (i = 0; i < 12; i++)
286
for (i = 0; i < 12; i++)
278
angle = HOURS_TO_RADIANS (i, 0);
279
x = xc + sin (angle) * (radius * (1.0 - CLOCK_SCALE));
280
y = yc + cos (angle) * (radius * (1.0 - CLOCK_SCALE));
289
angle = HOURS_TO_RADIANS (i, 0);
290
x = xc + sin (angle) * (radius * (1.0 - CLOCK_SCALE));
291
y = yc + cos (angle) * (radius * (1.0 - CLOCK_SCALE));
283
cairo_move_to (cr, x, y);
284
cairo_arc (cr, x, y, radius * CLOCK_SCALE, 0, 2 * M_PI);
285
cairo_close_path (cr);
294
cairo_move_to (cr, x, y);
295
cairo_arc (cr, x, y, radius * CLOCK_SCALE, 0, 2 * G_PI);
296
cairo_close_path (cr);
306
/* calculate tip position */
307
xt = xc + sin (angle) * radius * scale;
308
yt = yc + cos (angle) * radius * scale;
313
cairo_move_to (cr, xc, yc);
314
cairo_line_to (cr, xt, yt);
321
/* calculate start position */
322
xs = xc + sin (angle - 0.5 * M_PI) * radius * CLOCK_SCALE;
323
ys = yc + cos (angle - 0.5 * M_PI) * radius * CLOCK_SCALE;
325
/* draw the pointer */
326
cairo_move_to (cr, xs, ys);
327
cairo_arc (cr, xc, yc, radius * CLOCK_SCALE, -angle + M_PI, -angle);
328
cairo_line_to (cr, xt, yt);
329
cairo_close_path (cr);
331
/* fill the pointer */
317
/* calculate tip position */
318
xt = xc + sin (angle) * radius * scale;
319
yt = yc + cos (angle) * radius * scale;
324
cairo_move_to (cr, xc, yc);
325
cairo_line_to (cr, xt, yt);
332
/* calculate start position */
333
xs = xc + sin (angle - 0.5 * G_PI) * radius * CLOCK_SCALE;
334
ys = yc + cos (angle - 0.5 * G_PI) * radius * CLOCK_SCALE;
336
/* draw the pointer */
337
cairo_move_to (cr, xs, ys);
338
cairo_arc (cr, xc, yc, radius * CLOCK_SCALE, -angle + G_PI, -angle);
339
cairo_line_to (cr, xt, yt);
340
cairo_close_path (cr);
342
/* fill the pointer */
350
xfce_clock_analog_update (gpointer user_data)
352
GtkWidget *widget = GTK_WIDGET (user_data);
354
panel_return_val_if_fail (XFCE_CLOCK_IS_ANALOG (user_data), FALSE);
356
/* update if the widget if visible */
357
if (G_LIKELY (GTK_WIDGET_VISIBLE (widget)))
358
gtk_widget_queue_draw (widget);