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.
41 * #HildonWeekdayPicker has been deprecated since Hildon 2.2 and should not
42 * be used in newly written code. See
43 * <link linkend="hildon-migrating-date-widgets">Migrating Date Widgets</link>
44 * section to know how to migrate this deprecated widget.
49 * <title>HildonWeekdayPicker example</title>
52 * HildonWeekdayPicker *picker = hildon_weekday_picker_new ();
54 * hildon_weekday_picker_set_day (picker, i);
55 * hildon_weekday_picker_unset_day (picker, i);
56 * hildon_weekday_picker_toggle_day (picker, i);
57 * hildon_weekday_picker_set_all (picker);
59 * hildon_weekday_picker_unset_all( picker );
65 /* GDate numbers days from 1 to 7 and G_DATE_MONDAY is 1st day. However
66 according to locale settings first day is sunday. To get around this
67 problem, we addjust GDate days numbering to be same as locale
70 #undef HILDON_DISABLE_DEPRECATED
78 #include <sys/types.h>
83 #include <gdk/gdkkeysyms.h>
85 #include "hildon-weekday-picker.h"
86 #include "hildon-private.h"
87 #include "hildon-weekday-picker-private.h"
89 static GtkContainerClass* parent_class;
92 hildon_weekday_picker_class_init (HildonWeekdayPickerClass *picker_class);
95 hildon_weekday_picker_init (HildonWeekdayPicker *picker);
98 hildon_weekday_picker_size_allocate (GtkWidget *widget,
99 GtkAllocation *allocation);
101 hildon_weekday_picker_focus (GtkWidget *widget,
102 GtkDirectionType direction);
104 hildon_weekday_picker_size_request (GtkWidget *widget,
105 GtkRequisition *requisition);
107 hildon_weekday_picker_forall (GtkContainer *container,
108 gboolean include_internals,
109 GtkCallback callback,
110 gpointer callback_data);
113 hildon_weekday_picker_destroy (GtkObject *self);
116 button_toggle (GtkToggleButton *togglebutton,
121 SELECTION_CHANGED_SIGNAL,
125 static guint signals [LAST_SIGNAL] = { 0 } ;
128 * hildon_weekday_picker_get_type:
130 * Initializes and returns the type of a hildon weekday picker.
132 * Returns: GType of #HildonWeekdayPicker
135 hildon_weekday_picker_get_type (void)
137 static GType picker_type = 0;
140 static const GTypeInfo picker_info = {
141 sizeof (HildonWeekdayPickerClass),
142 NULL, /* base_init */
143 NULL, /* base_finalize */
144 (GClassInitFunc) hildon_weekday_picker_class_init,
145 NULL, /* class_finalize */
146 NULL, /* class_data */
147 sizeof (HildonWeekdayPicker),
149 (GInstanceInitFunc) hildon_weekday_picker_init,
151 picker_type = g_type_register_static (GTK_TYPE_CONTAINER,
152 "HildonWeekdayPicker",
160 hildon_weekday_picker_class_init (HildonWeekdayPickerClass *picker_class)
162 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (picker_class);
163 GtkContainerClass *container_class = GTK_CONTAINER_CLASS (picker_class);
164 GObjectClass *object_class = G_OBJECT_CLASS (picker_class);
166 parent_class = g_type_class_peek_parent (picker_class);
168 g_type_class_add_private (picker_class,
169 sizeof (HildonWeekdayPickerPrivate));
171 /* Override virtual methods */
172 widget_class->size_request = hildon_weekday_picker_size_request;
173 widget_class->size_allocate = hildon_weekday_picker_size_allocate;
174 widget_class->focus = hildon_weekday_picker_focus;
175 container_class->forall = hildon_weekday_picker_forall;
176 GTK_OBJECT_CLASS (picker_class)->destroy = hildon_weekday_picker_destroy;
178 /* Create a signal for reporting user actions */
179 signals [SELECTION_CHANGED_SIGNAL] = g_signal_new ("selection_changed",
184 G_STRUCT_OFFSET (HildonWeekdayPickerClass, selection_changed),
186 g_cclosure_marshal_VOID__INT,
187 G_TYPE_NONE, 1, G_TYPE_INT);
191 hildon_weekday_picker_init (HildonWeekdayPicker *picker)
193 HildonWeekdayPickerPrivate *priv;
196 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
199 /* weekday indexes to be used with nl_langinfo. These are shifted
200 * by one for glib compability */
202 -1, /* 0 = invalid date */
203 ABDAY_2, /* 1 = monday in glib */
204 ABDAY_3, /* 2 = tuesday in glib */
205 ABDAY_4, /* 3 = wednesday in glib */
206 ABDAY_5, /* 4 = thursday in glib */
207 ABDAY_6, /* 5 = friday in glib */
208 ABDAY_7, /* 6 = saturday in glib */
209 ABDAY_1 }; /* 7 = sunday in glib */
210 GtkSizeGroup *sgroup;
212 sgroup = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
214 /* Check our first weekday */
215 day = *nl_langinfo (_NL_TIME_FIRST_WEEKDAY);
218 /* Shift the days by one. This is done because GDateWeekday
219 * starts with Monday(1) and langinfo's first day is Sunday */
225 /* Initialize and pack day buttons */
226 for (i = 1; i <= 7; i++) {
228 gtk_toggle_button_new_with_label (nl_langinfo (wdays[day]));
229 priv->day_order_buttons [day] = priv->buttons [i];
235 g_signal_connect (GTK_WIDGET (priv->buttons [i]),
236 "toggled", G_CALLBACK (button_toggle), picker);
238 gtk_size_group_add_widget (sgroup, priv->buttons [i]);
240 gtk_widget_set_parent (priv->buttons [i], GTK_WIDGET (picker));
241 gtk_widget_show (priv->buttons[i]);
244 GTK_WIDGET_SET_FLAGS (picker, GTK_NO_WINDOW);
246 g_object_unref (sgroup);
250 * hildon_weekday_picker_new:
252 * Creates a new #HildonWeekdayPicker.
254 * Returns: pointer to a new #HildonWeekdayPicker widget.
257 hildon_weekday_picker_new (void)
259 return g_object_new (HILDON_TYPE_WEEKDAY_PICKER, NULL);
263 hildon_weekday_picker_forall (GtkContainer *container,
264 gboolean include_internals,
265 GtkCallback callback,
266 gpointer callback_data)
268 HildonWeekdayPicker *picker;
269 HildonWeekdayPickerPrivate *priv;
272 g_assert (container);
275 picker = HILDON_WEEKDAY_PICKER (container);
276 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
279 /* We only have internal children */
280 if (! include_internals)
283 /* Activate callback for each day button */
284 for (i = 1; i <= 7; ++i) {
285 (*callback) (priv->buttons [i], callback_data);
290 hildon_weekday_picker_destroy (GtkObject *self)
292 HildonWeekdayPickerPrivate *priv;
295 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (self);
298 /* Destroy internal children... */
299 for (i = 1; i <= 7; ++i) {
300 if (priv->buttons [i])
302 gtk_widget_unparent (priv->buttons [i]);
303 priv->buttons [i] = NULL;
307 /* ... and chain to parent. */
308 if (GTK_OBJECT_CLASS (parent_class)->destroy)
309 GTK_OBJECT_CLASS (parent_class)->destroy (self);
314 hildon_weekday_picker_size_request (GtkWidget *widget,
315 GtkRequisition *requisition)
317 HildonWeekdayPicker *picker;
318 HildonWeekdayPickerPrivate *priv;
322 picker = HILDON_WEEKDAY_PICKER (widget);
323 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
326 requisition->width = 0;
327 requisition->height = 0;
329 /* Request an area that is as wide as all of the buttons
330 together and tall enough to hold heightest button */
331 for (i = 1; i <= 7; ++i) {
332 gtk_widget_size_request (priv->buttons [i], &req);
333 requisition->width += req.width;
334 if (req.height > requisition->height)
335 requisition->height = req.height;
341 hildon_weekday_picker_size_allocate (GtkWidget *widget,
342 GtkAllocation *allocation)
344 HildonWeekdayPicker *picker;
345 HildonWeekdayPickerPrivate *priv;
348 GtkRequisition child_requisition;
351 GtkTextDirection direction;
354 g_assert (allocation);
356 /* Check orientation */
357 direction = gtk_widget_get_direction (widget);
359 picker = HILDON_WEEKDAY_PICKER (widget);
360 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
363 header_x = allocation->x;
364 widget->allocation = *allocation;
366 if (direction == GTK_TEXT_DIR_LTR || direction == GTK_TEXT_DIR_NONE)
371 /* Allocate day buttons side by side honouring the text direction */
372 for (i = 1; i <= 7; ++i) {
373 gtk_widget_get_child_requisition (priv->buttons[sval], &child_requisition);
376 alloc.y = allocation->y;
377 alloc.width = child_requisition.width;
378 alloc.height = child_requisition.height;
379 header_x += alloc.width;
380 gtk_widget_size_allocate (priv->buttons [sval], &alloc);
381 if (direction == GTK_TEXT_DIR_RTL)
389 hildon_weekday_picker_focus (GtkWidget *widget,
390 GtkDirectionType direction)
393 GtkDirectionType effective_direction;
395 g_assert (HILDON_IS_WEEKDAY_PICKER (widget));
397 retval = hildon_private_composite_focus (widget, direction, &effective_direction);
400 return GTK_WIDGET_CLASS (parent_class)->focus (widget, effective_direction);
406 button_toggle (GtkToggleButton *button,
409 HildonWeekdayPicker *picker;
410 HildonWeekdayPickerPrivate *priv;
416 picker = HILDON_WEEKDAY_PICKER (wpicker);
418 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
421 for (i = 1; i <= 7; ++i) {
422 if (GTK_WIDGET (button) == priv->day_order_buttons [i]) {
423 g_signal_emit (GTK_WIDGET (picker),
424 signals [SELECTION_CHANGED_SIGNAL], 0, i);
431 * hildon_weekday_picker_set_day:
432 * @picker: the #HildonWeekdayPicker widget
433 * @day: day to be set active
435 * Sets specified weekday active.
438 hildon_weekday_picker_set_day (HildonWeekdayPicker *picker,
441 HildonWeekdayPickerPrivate *priv;
443 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
444 g_return_if_fail (g_date_valid_weekday(day));
446 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
448 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
449 (priv->day_order_buttons[day]), TRUE);
453 * hildon_weekday_picker_unset_day:
454 * @picker: the #HildonWeekdayPicker widget
455 * @day: day to be set inactive
457 * Unselect specified weekday.
460 hildon_weekday_picker_unset_day (HildonWeekdayPicker *picker,
463 HildonWeekdayPickerPrivate *priv;
465 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
466 g_return_if_fail (g_date_valid_weekday (day));
468 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
471 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
472 (priv->day_order_buttons [day]), FALSE);
476 * hildon_weekday_picker_toggle_day:
477 * @picker: the #HildonWeekdayPicker widget
478 * @day: day to be toggled
480 * Toggles current status of the specified weekday.
483 hildon_weekday_picker_toggle_day (HildonWeekdayPicker *picker,
486 HildonWeekdayPickerPrivate *priv;
488 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
489 g_return_if_fail (g_date_valid_weekday (day));
491 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
494 gtk_toggle_button_set_active (
495 GTK_TOGGLE_BUTTON (priv->day_order_buttons [day]),
496 ! gtk_toggle_button_get_active(
497 GTK_TOGGLE_BUTTON (priv->day_order_buttons[day])));
501 * hildon_weekday_picker_set_all:
502 * @picker: the #HildonWeekdayPicker widget
504 * Sets all weekdays active.
507 hildon_weekday_picker_set_all (HildonWeekdayPicker *picker)
509 HildonWeekdayPickerPrivate *priv;
512 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
514 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
517 for (i = 1; i <= 7; i++)
518 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->buttons [i]), TRUE);
522 * hildon_weekday_picker_unset_all:
523 * @picker: the #HildonWeekdayPicker widget
525 * Sets all weekdays inactive.
528 hildon_weekday_picker_unset_all (HildonWeekdayPicker *picker)
530 HildonWeekdayPickerPrivate *priv;
533 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
535 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
538 for (i = 1; i <= 7; i++)
539 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->buttons [i]), FALSE);
543 * hildon_weekday_picker_isset_day:
544 * @picker: the #HildonWeekdayPicker widget
545 * @day: day to be checked.
547 * Checks if the specified weekday is set active.
549 * Returns: TRUE if the day is set, FALSE if the day is not set
552 hildon_weekday_picker_isset_day (HildonWeekdayPicker *picker,
555 HildonWeekdayPickerPrivate *priv;
557 g_return_val_if_fail (HILDON_IS_WEEKDAY_PICKER (picker), FALSE);
558 g_return_val_if_fail (g_date_valid_weekday (day), FALSE);
560 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
563 return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->day_order_buttons[day]));