2 * This file is a part of hildon
4 * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
6 * Contact: Rodrigo Novo <rodrigo.novo@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; 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
26 * SECTION:hildon-weekday-picker
27 * @short_description: A widget for picking days on which a certain event
29 * @see_also: #HildonWeekdayPicker
31 * #HildonWeekdayPicker supports non-mutually exclusive selection of days of
32 * the week. Selected days of the week are shown with a pushed-in effect.
34 * #HildonWeekdayPicker is used where users are required to pick days on which
35 * a certain event should take place, for example, which days a Calendar event
36 * should be repeated on. It is used in Calendar in the Repeat dialog, in Tasks
37 * in the Repeat dialog and in the Email set-up wizard.
40 * <title>HildonWeekdayPicker example</title>
43 * HildonWeekdayPicker *picker = hildon_weekday_picker_new ();
45 * hildon_weekday_picker_set_day (picker, i);
46 * hildon_weekday_picker_unset_day (picker, i);
47 * hildon_weekday_picker_toggle_day (picker, i);
48 * hildon_weekday_picker_set_all (picker);
50 * hildon_weekday_picker_unset_all( picker );
56 /* GDate numbers days from 1 to 7 and G_DATE_MONDAY is 1st day. However
57 according to locale settings first day is sunday. To get around this
58 problem, we addjust GDate days numbering to be same as locale
61 #undef HILDON_DISABLE_DEPRECATED
69 #include <sys/types.h>
74 #include <gdk/gdkkeysyms.h>
76 #include "hildon-weekday-picker.h"
77 #include "hildon-private.h"
78 #include "hildon-weekday-picker-private.h"
80 static GtkContainerClass* parent_class;
83 hildon_weekday_picker_class_init (HildonWeekdayPickerClass *picker_class);
86 hildon_weekday_picker_init (HildonWeekdayPicker *picker);
89 hildon_weekday_picker_size_allocate (GtkWidget *widget,
90 GtkAllocation *allocation);
92 hildon_weekday_picker_focus (GtkWidget *widget,
93 GtkDirectionType direction);
95 hildon_weekday_picker_size_request (GtkWidget *widget,
96 GtkRequisition *requisition);
98 hildon_weekday_picker_forall (GtkContainer *container,
99 gboolean include_internals,
100 GtkCallback callback,
101 gpointer callback_data);
104 hildon_weekday_picker_destroy (GtkObject *self);
107 button_toggle (GtkToggleButton *togglebutton,
112 SELECTION_CHANGED_SIGNAL,
116 static guint signals [LAST_SIGNAL] = { 0 } ;
119 * hildon_weekday_picker_get_type:
121 * Initializes and returns the type of a hildon weekday picker.
123 * Returns: GType of #HildonWeekdayPicker
126 hildon_weekday_picker_get_type (void)
128 static GType picker_type = 0;
131 static const GTypeInfo picker_info = {
132 sizeof (HildonWeekdayPickerClass),
133 NULL, /* base_init */
134 NULL, /* base_finalize */
135 (GClassInitFunc) hildon_weekday_picker_class_init,
136 NULL, /* class_finalize */
137 NULL, /* class_data */
138 sizeof (HildonWeekdayPicker),
140 (GInstanceInitFunc) hildon_weekday_picker_init,
142 picker_type = g_type_register_static (GTK_TYPE_CONTAINER,
143 "HildonWeekdayPicker",
151 hildon_weekday_picker_class_init (HildonWeekdayPickerClass *picker_class)
153 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (picker_class);
154 GtkContainerClass *container_class = GTK_CONTAINER_CLASS (picker_class);
155 GObjectClass *object_class = G_OBJECT_CLASS (picker_class);
157 parent_class = g_type_class_peek_parent (picker_class);
159 g_type_class_add_private (picker_class,
160 sizeof (HildonWeekdayPickerPrivate));
162 /* Override virtual methods */
163 widget_class->size_request = hildon_weekday_picker_size_request;
164 widget_class->size_allocate = hildon_weekday_picker_size_allocate;
165 widget_class->focus = hildon_weekday_picker_focus;
166 container_class->forall = hildon_weekday_picker_forall;
167 GTK_OBJECT_CLASS (picker_class)->destroy = hildon_weekday_picker_destroy;
169 /* Create a signal for reporting user actions */
170 signals [SELECTION_CHANGED_SIGNAL] = g_signal_new ("selection_changed",
175 G_STRUCT_OFFSET (HildonWeekdayPickerClass, selection_changed),
177 g_cclosure_marshal_VOID__INT,
178 G_TYPE_NONE, 1, G_TYPE_INT);
182 hildon_weekday_picker_init (HildonWeekdayPicker *picker)
184 HildonWeekdayPickerPrivate *priv;
187 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
190 /* weekday indexes to be used with nl_langinfo. These are shifted
191 * by one for glib compability */
193 -1, /* 0 = invalid date */
194 ABDAY_2, /* 1 = monday in glib */
195 ABDAY_3, /* 2 = tuesday in glib */
196 ABDAY_4, /* 3 = wednesday in glib */
197 ABDAY_5, /* 4 = thursday in glib */
198 ABDAY_6, /* 5 = friday in glib */
199 ABDAY_7, /* 6 = saturday in glib */
200 ABDAY_1 }; /* 7 = sunday in glib */
201 GtkSizeGroup *sgroup;
203 sgroup = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
205 /* Check our first weekday */
206 day = *nl_langinfo (_NL_TIME_FIRST_WEEKDAY);
209 /* Shift the days by one. This is done because GDateWeekday
210 * starts with Monday(1) and langinfo's first day is Sunday */
216 /* Initialize and pack day buttons */
217 for (i = 1; i <= 7; i++) {
219 gtk_toggle_button_new_with_label (nl_langinfo (wdays[day]));
220 priv->day_order_buttons [day] = priv->buttons [i];
226 g_signal_connect (GTK_WIDGET (priv->buttons [i]),
227 "toggled", G_CALLBACK (button_toggle), picker);
229 gtk_size_group_add_widget (sgroup, priv->buttons [i]);
231 gtk_widget_set_parent (priv->buttons [i], GTK_WIDGET (picker));
232 gtk_widget_show (priv->buttons[i]);
235 GTK_WIDGET_SET_FLAGS (picker, GTK_NO_WINDOW);
237 g_object_unref (sgroup);
241 * hildon_weekday_picker_new:
243 * Creates a new #HildonWeekdayPicker.
245 * Returns: pointer to a new #HildonWeekdayPicker widget.
248 hildon_weekday_picker_new (void)
250 return g_object_new (HILDON_TYPE_WEEKDAY_PICKER, NULL);
254 hildon_weekday_picker_forall (GtkContainer *container,
255 gboolean include_internals,
256 GtkCallback callback,
257 gpointer callback_data)
259 HildonWeekdayPicker *picker;
260 HildonWeekdayPickerPrivate *priv;
263 g_assert (container);
266 picker = HILDON_WEEKDAY_PICKER (container);
267 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
270 /* We only have internal children */
271 if (! include_internals)
274 /* Activate callback for each day button */
275 for (i = 1; i <= 7; ++i) {
276 (*callback) (priv->buttons [i], callback_data);
281 hildon_weekday_picker_destroy (GtkObject *self)
283 HildonWeekdayPickerPrivate *priv;
286 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (self);
289 /* Destroy internal children... */
290 for (i = 1; i <= 7; ++i) {
291 if (priv->buttons [i])
293 gtk_widget_unparent (priv->buttons [i]);
294 priv->buttons [i] = NULL;
298 /* ... and chain to parent. */
299 if (GTK_OBJECT_CLASS (parent_class)->destroy)
300 GTK_OBJECT_CLASS (parent_class)->destroy (self);
305 hildon_weekday_picker_size_request (GtkWidget *widget,
306 GtkRequisition *requisition)
308 HildonWeekdayPicker *picker;
309 HildonWeekdayPickerPrivate *priv;
313 picker = HILDON_WEEKDAY_PICKER (widget);
314 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
317 requisition->width = 0;
318 requisition->height = 0;
320 /* Request an area that is as wide as all of the buttons
321 together and tall enough to hold heightest button */
322 for (i = 1; i <= 7; ++i) {
323 gtk_widget_size_request (priv->buttons [i], &req);
324 requisition->width += req.width;
325 if (req.height > requisition->height)
326 requisition->height = req.height;
332 hildon_weekday_picker_size_allocate (GtkWidget *widget,
333 GtkAllocation *allocation)
335 HildonWeekdayPicker *picker;
336 HildonWeekdayPickerPrivate *priv;
339 GtkRequisition child_requisition;
342 GtkTextDirection direction;
345 g_assert (allocation);
347 /* Check orientation */
348 direction = gtk_widget_get_direction (widget);
350 picker = HILDON_WEEKDAY_PICKER (widget);
351 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
354 header_x = allocation->x;
355 widget->allocation = *allocation;
357 if (direction == GTK_TEXT_DIR_LTR || direction == GTK_TEXT_DIR_NONE)
362 /* Allocate day buttons side by side honouring the text direction */
363 for (i = 1; i <= 7; ++i) {
364 gtk_widget_get_child_requisition (priv->buttons[sval], &child_requisition);
367 alloc.y = allocation->y;
368 alloc.width = child_requisition.width;
369 alloc.height = child_requisition.height;
370 header_x += alloc.width;
371 gtk_widget_size_allocate (priv->buttons [sval], &alloc);
372 if (direction == GTK_TEXT_DIR_RTL)
380 hildon_weekday_picker_focus (GtkWidget *widget,
381 GtkDirectionType direction)
384 GtkDirectionType effective_direction;
386 g_assert (HILDON_IS_WEEKDAY_PICKER (widget));
388 retval = hildon_private_composite_focus (widget, direction, &effective_direction);
391 return GTK_WIDGET_CLASS (parent_class)->focus (widget, effective_direction);
397 button_toggle (GtkToggleButton *button,
400 HildonWeekdayPicker *picker;
401 HildonWeekdayPickerPrivate *priv;
407 picker = HILDON_WEEKDAY_PICKER (wpicker);
409 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
412 for (i = 1; i <= 7; ++i) {
413 if (GTK_WIDGET (button) == priv->day_order_buttons [i]) {
414 g_signal_emit (GTK_WIDGET (picker),
415 signals [SELECTION_CHANGED_SIGNAL], 0, i);
422 * hildon_weekday_picker_set_day:
423 * @picker: the #HildonWeekdayPicker widget
424 * @day: day to be set active
426 * Sets specified weekday active.
429 hildon_weekday_picker_set_day (HildonWeekdayPicker *picker,
432 HildonWeekdayPickerPrivate *priv;
434 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
435 g_return_if_fail (g_date_valid_weekday(day));
437 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
439 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
440 (priv->day_order_buttons[day]), TRUE);
444 * hildon_weekday_picker_unset_day:
445 * @picker: the #HildonWeekdayPicker widget
446 * @day: day to be set inactive
448 * Unselect specified weekday.
451 hildon_weekday_picker_unset_day (HildonWeekdayPicker *picker,
454 HildonWeekdayPickerPrivate *priv;
456 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
457 g_return_if_fail (g_date_valid_weekday (day));
459 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
462 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
463 (priv->day_order_buttons [day]), FALSE);
467 * hildon_weekday_picker_toggle_day:
468 * @picker: the #HildonWeekdayPicker widget
469 * @day: day to be toggled
471 * Toggles current status of the specified weekday.
474 hildon_weekday_picker_toggle_day (HildonWeekdayPicker *picker,
477 HildonWeekdayPickerPrivate *priv;
479 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
480 g_return_if_fail (g_date_valid_weekday (day));
482 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
485 gtk_toggle_button_set_active (
486 GTK_TOGGLE_BUTTON (priv->day_order_buttons [day]),
487 ! gtk_toggle_button_get_active(
488 GTK_TOGGLE_BUTTON (priv->day_order_buttons[day])));
492 * hildon_weekday_picker_set_all:
493 * @picker: the #HildonWeekdayPicker widget
495 * Sets all weekdays active.
498 hildon_weekday_picker_set_all (HildonWeekdayPicker *picker)
500 HildonWeekdayPickerPrivate *priv;
503 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
505 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
508 for (i = 1; i <= 7; i++)
509 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->buttons [i]), TRUE);
513 * hildon_weekday_picker_unset_all:
514 * @picker: the #HildonWeekdayPicker widget
516 * Sets all weekdays inactive.
519 hildon_weekday_picker_unset_all (HildonWeekdayPicker *picker)
521 HildonWeekdayPickerPrivate *priv;
524 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
526 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
529 for (i = 1; i <= 7; i++)
530 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->buttons [i]), FALSE);
534 * hildon_weekday_picker_isset_day:
535 * @picker: the #HildonWeekdayPicker widget
536 * @day: day to be checked.
538 * Checks if the specified weekday is set active.
540 * Returns: TRUE if the day is set, FALSE if the day is not set
543 hildon_weekday_picker_isset_day (HildonWeekdayPicker *picker,
546 HildonWeekdayPickerPrivate *priv;
548 g_return_val_if_fail (HILDON_IS_WEEKDAY_PICKER (picker), FALSE);
549 g_return_val_if_fail (g_date_valid_weekday (day), FALSE);
551 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
554 return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->day_order_buttons[day]));