2 * This file is part of hildon-libs
4 * Copyright (C) 2005 Nokia Corporation.
6 * Contact: Luc Pionchon <luc.pionchon@nokia.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * - Must check if graphics should be added to widgets weekday
33 * @shortdesc: Weekday Picker is a widget for selecting weekdays
34 * @longdesc: Weekday Picker is a widget for selecting weekdays.
35 * It shows seven toggle buttons that can have state on or off.
37 * @seealso: #HildonTimePicker
40 /* GDate numbers days from 1 to 7 and G_DATE_MONDAY is 1st day. However
41 according to locale settings first day is sunday. To get around this
42 problem, we addjust GDate days numbering to be same as locale
51 #include <sys/types.h>
56 #include <gtk/gtksignal.h>
57 #include <gdk/gdkkeysyms.h>
58 #include <gtk/gtktogglebutton.h>
59 #include <gtk/gtksizegroup.h>
60 #include <gtk/gtkwindow.h>
61 #include "hildon-weekday-picker.h"
62 #include "hildon-composite-widget.h"
64 #define _(string) dgettext(PACKAGE, string)
66 #define HILDON_WEEKDAY_PICKER_GET_PRIVATE(obj) \
67 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
68 HILDON_WEEKDAY_PICKER_TYPE, HildonWeekdayPickerPrivate));
70 static GtkContainerClass *parent_class;
72 typedef struct _HildonWeekdayPickerPrivate HildonWeekdayPickerPrivate;
75 hildon_weekday_picker_class_init(HildonWeekdayPickerClass * picker_class);
78 hildon_weekday_picker_init(HildonWeekdayPicker * picker);
81 hildon_weekday_picker_size_allocate(GtkWidget * widget,
82 GtkAllocation * allocation);
85 hildon_weekday_picker_size_request(GtkWidget * widget,
86 GtkRequisition * requisition);
89 hildon_weekday_picker_forall(GtkContainer * container,
90 gboolean include_internals,
91 GtkCallback callback, gpointer callback_data);
94 hildon_weekday_picker_destroy(GtkObject * self);
97 hildon_weekday_picker_mnemonic_activate(GtkWidget *widget,
98 gboolean group_cycling);
101 button_toggle(GtkToggleButton * togglebutton, gpointer data);
103 struct _HildonWeekdayPickerPrivate {
104 guint dayorder[8]; /* Lookup table for weekdays */
105 GtkWidget *buttons[8]; /* weekday buttons */
111 SELECTION_CHANGED_SIGNAL,
115 static guint signals[LAST_SIGNAL] = { 0 };
117 GType hildon_weekday_picker_get_type(void)
119 static GType picker_type = 0;
122 static const GTypeInfo picker_info = {
123 sizeof(HildonWeekdayPickerClass),
124 NULL, /* base_init */
125 NULL, /* base_finalize */
126 (GClassInitFunc) hildon_weekday_picker_class_init,
127 NULL, /* class_finalize */
128 NULL, /* class_data */
129 sizeof(HildonWeekdayPicker),
131 (GInstanceInitFunc) hildon_weekday_picker_init,
133 picker_type = g_type_register_static(GTK_TYPE_CONTAINER,
134 "HildonWeekdayPicker",
141 hildon_weekday_picker_class_init(HildonWeekdayPickerClass * picker_class)
143 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(picker_class);
144 GtkContainerClass *container_class = GTK_CONTAINER_CLASS(picker_class);
145 GObjectClass *object_class = G_OBJECT_CLASS(picker_class);
147 parent_class = g_type_class_peek_parent(picker_class);
149 g_type_class_add_private(picker_class,
150 sizeof(HildonWeekdayPickerPrivate));
152 widget_class->mnemonic_activate = hildon_weekday_picker_mnemonic_activate;
153 widget_class->size_request = hildon_weekday_picker_size_request;
154 widget_class->size_allocate = hildon_weekday_picker_size_allocate;
155 widget_class->focus = hildon_composite_widget_focus;
156 container_class->forall = hildon_weekday_picker_forall;
157 GTK_OBJECT_CLASS(picker_class)->destroy =
158 hildon_weekday_picker_destroy;
160 signals[SELECTION_CHANGED_SIGNAL] = g_signal_new("selection_changed",
166 (HildonWeekdayPickerClass,
167 selection_changed), NULL, NULL,
168 gtk_marshal_VOID__INT,
169 G_TYPE_NONE, 1, G_TYPE_INT);
173 hildon_weekday_picker_init(HildonWeekdayPicker * picker)
175 HildonWeekdayPickerPrivate *priv;
177 const gchar *wdays[8];
178 GtkSizeGroup *sgroup;
180 sgroup = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
182 /* NOTE: we query locales with "first_weekday" parameter, but this
183 seems to be broken on some installations. e.g. on my system I
184 receive "1" (Sunday) to be first day of the week on "fi_FI"
185 locale, when it should be "2" (Monday). */
187 /* Check our first weekday */
188 day = *nl_langinfo(_NL_TIME_FIRST_WEEKDAY);
190 wdays[1] = nl_langinfo(ABDAY_1);
191 wdays[2] = nl_langinfo(ABDAY_2);
192 wdays[3] = nl_langinfo(ABDAY_3);
193 wdays[4] = nl_langinfo(ABDAY_4);
194 wdays[5] = nl_langinfo(ABDAY_5);
195 wdays[6] = nl_langinfo(ABDAY_6);
196 wdays[7] = nl_langinfo(ABDAY_7);
198 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
200 for (i = 1; i <= 7; i++) {
201 priv->buttons[i] = gtk_toggle_button_new_with_label(wdays[day]);
202 priv->dayorder[i] = day++;
207 g_signal_connect(GTK_WIDGET(priv->buttons[i]),
208 "toggled", G_CALLBACK(button_toggle), picker);
210 priv->last_index = i;
211 gtk_size_group_add_widget(sgroup, priv->buttons[i]);
213 gtk_widget_set_parent(priv->buttons[i], GTK_WIDGET(picker));
214 gtk_widget_show(priv->buttons[i]);
217 GTK_WIDGET_SET_FLAGS(picker, GTK_NO_WINDOW);
221 * hildon_weekday_picker_new:
223 * Creates a new #HildonWeekdayPicker.
225 * Return value: Pointer to a new @HildonWeekdayPicker widget.
227 GtkWidget *hildon_weekday_picker_new(void)
229 return g_object_new(HILDON_WEEKDAY_PICKER_TYPE, NULL);
233 hildon_weekday_picker_mnemonic_activate(GtkWidget *widget,
234 gboolean group_cycling)
236 HildonWeekdayPickerPrivate *priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(widget);
237 gtk_widget_grab_focus(priv->buttons[1]);
242 hildon_weekday_picker_forall(GtkContainer * container,
243 gboolean include_internals, GtkCallback callback,
244 gpointer callback_data)
246 HildonWeekdayPicker *picker;
247 HildonWeekdayPickerPrivate *priv;
250 g_return_if_fail(container);
251 g_return_if_fail(callback);
253 picker = HILDON_WEEKDAY_PICKER(container);
254 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
256 if (!include_internals)
259 for (i = 1; i <= 7; ++i) {
260 (*callback) (priv->buttons[i], callback_data);
266 hildon_weekday_picker_destroy(GtkObject * self)
268 HildonWeekdayPickerPrivate *priv;
271 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(self);
273 for (i = 1; i <= 7; ++i) {
274 if (priv->buttons[i])
276 gtk_widget_unparent(priv->buttons[i]);
277 priv->buttons[i] = NULL;
281 if (GTK_OBJECT_CLASS(parent_class)->destroy)
282 GTK_OBJECT_CLASS(parent_class)->destroy(self);
287 hildon_weekday_picker_size_request(GtkWidget * widget,
288 GtkRequisition *requisition)
290 HildonWeekdayPicker *picker;
291 HildonWeekdayPickerPrivate *priv;
295 picker = HILDON_WEEKDAY_PICKER(widget);
296 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
297 requisition->width = 0;
298 requisition->height = 0;
300 for (i = 1; i <= 7; ++i) {
301 gtk_widget_size_request(priv->buttons[i], &req);
302 requisition->width += req.width;
303 if (req.height > requisition->height)
304 requisition->height = req.height;
310 hildon_weekday_picker_size_allocate(GtkWidget * widget,
311 GtkAllocation * allocation)
313 HildonWeekdayPicker *picker;
314 HildonWeekdayPickerPrivate *priv;
317 GtkRequisition child_requisition;
320 GtkTextDirection direction;
322 g_return_if_fail(widget);
323 g_return_if_fail(allocation);
325 /* Check orientation */
326 direction = gtk_widget_get_direction(widget);
328 picker = HILDON_WEEKDAY_PICKER(widget);
329 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
330 header_x = allocation->x;
331 widget->allocation = *allocation;
333 if (direction == GTK_TEXT_DIR_LTR || direction == GTK_TEXT_DIR_NONE)
337 for (i = 1; i <= 7; ++i) {
338 gtk_widget_get_child_requisition(priv->buttons[sval],
342 alloc.y = allocation->y;
343 alloc.width = child_requisition.width;
344 alloc.height = child_requisition.height;
345 header_x += alloc.width;
346 gtk_widget_size_allocate(priv->buttons[sval], &alloc);
347 if (direction == GTK_TEXT_DIR_RTL)
355 button_toggle(GtkToggleButton * button, gpointer data)
357 HildonWeekdayPicker *picker;
358 HildonWeekdayPickerPrivate *priv;
360 static guint wdays[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
362 g_return_if_fail(button);
363 g_return_if_fail(data);
365 picker = HILDON_WEEKDAY_PICKER(data);
366 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
368 for (i = 1; i <= 7; ++i) {
369 if (GTK_WIDGET(button) == priv->buttons[i]) {
370 priv->days ^= wdays[i];
371 g_signal_emit (GTK_WIDGET(picker), signals[SELECTION_CHANGED_SIGNAL],
372 0, priv->dayorder[i]);
379 * hildon_weekday_picker_set_day:
380 * @picker: the @HildonWeekdayPicker widget
381 * @day: Day to be set
383 * Select specified weekday.
386 hildon_weekday_picker_set_day(HildonWeekdayPicker * picker,
389 HildonWeekdayPickerPrivate *priv;
390 static guint wdays[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
393 g_return_if_fail(picker);
394 g_return_if_fail(day >= 1 && day <= 7);
396 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
398 if (day == G_DATE_SUNDAY)
403 for (i = 1; i <= 7; i++) {
404 if (priv->dayorder[i] == day) {
405 if (!(priv->days & wdays[i]))
406 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
407 (priv->buttons[i]), TRUE);
413 * hildon_weekday_picker_unset_day:
414 * @picker: the @HildonWeekdayPicker widget
415 * @day: Day to be unset
417 * Unselect specified weekday.
420 hildon_weekday_picker_unset_day(HildonWeekdayPicker * picker,
423 HildonWeekdayPickerPrivate *priv;
424 static guint wdays[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
427 g_return_if_fail(picker);
428 g_return_if_fail(day >= 1 && day <= 7);
430 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
432 if (day == G_DATE_SUNDAY)
437 for (i = 1; i <= 7; i++) {
438 if (priv->dayorder[i] == day) {
439 if (priv->days & wdays[i])
440 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
441 (priv->buttons[i]), FALSE);
447 * hildon_weekday_picker_toggle_day:
448 * @picker: the @HildonWeekdayPicker widget
449 * @day: Day to be toggled
451 * Toggle current status of the specified weekday.
454 hildon_weekday_picker_toggle_day(HildonWeekdayPicker * picker,
457 HildonWeekdayPickerPrivate *priv;
461 g_return_if_fail(picker);
462 g_return_if_fail(day >= 1 && day <= 7);
464 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
466 if (day == G_DATE_SUNDAY)
471 for (i = 1; i <= 7; i++) {
472 if (priv->dayorder[i] == day) {
473 is_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
475 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
477 is_active ? FALSE : TRUE);
483 * hildon_weekday_picker_set_all:
484 * @picker: the @HildonWeekdayPicker widget
489 hildon_weekday_picker_set_all(HildonWeekdayPicker * picker)
491 HildonWeekdayPickerPrivate *priv;
493 static guint wdays[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
495 g_return_if_fail(picker);
497 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
499 for (i = 1; i <= 7; i++) {
500 if (!(priv->days & wdays[i]))
501 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
502 (priv->buttons[i]), TRUE);
507 * hildon_weekday_picker_unset_all:
508 * @picker: the @HildonWeekdayPicker widget
510 * Unset all weekdays.
513 hildon_weekday_picker_unset_all(HildonWeekdayPicker * picker)
515 HildonWeekdayPickerPrivate *priv;
517 static guint wdays[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
519 g_return_if_fail(picker);
521 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
523 for (i = 1; i <= 7; i++) {
524 if (priv->days & wdays[i])
525 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
526 (priv->buttons[i]), FALSE);
531 * hildon_weekday_picker_set_all:
532 * @picker: the @HildonWeekdayPicker widget
533 * @day: Day to be checked.
535 * Check if the specified weekday is set.
537 * Return value: TRUE if the day is set.
540 hildon_weekday_picker_isset_day(HildonWeekdayPicker * picker,
543 HildonWeekdayPickerPrivate *priv;
546 g_return_val_if_fail(picker, FALSE);
547 g_return_val_if_fail(day >= 1 && day <= 7, FALSE);
549 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
551 if (day == G_DATE_SUNDAY)
556 for (i = 1; i <= 7; i++) {
557 if ( priv->dayorder[i] == day &&
558 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
559 (priv->buttons[i]))) {