2 * This file is a part of hildon
4 * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
6 * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@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
65 #include "hildon-weekday-picker.h"
68 #include <sys/types.h>
73 #include <gtk/gtksignal.h>
74 #include <gdk/gdkkeysyms.h>
75 #include <gtk/gtktogglebutton.h>
76 #include <gtk/gtksizegroup.h>
77 #include <gtk/gtkwindow.h>
78 #include "hildon-private.h"
79 #include "hildon-weekday-picker-private.h"
81 static GtkContainerClass* parent_class;
84 hildon_weekday_picker_class_init (HildonWeekdayPickerClass *picker_class);
87 hildon_weekday_picker_init (HildonWeekdayPicker *picker);
90 hildon_weekday_picker_size_allocate (GtkWidget *widget,
91 GtkAllocation *allocation);
93 hildon_weekday_picker_focus (GtkWidget *widget,
94 GtkDirectionType direction);
96 hildon_weekday_picker_size_request (GtkWidget *widget,
97 GtkRequisition *requisition);
99 hildon_weekday_picker_forall (GtkContainer *container,
100 gboolean include_internals,
101 GtkCallback callback,
102 gpointer callback_data);
105 hildon_weekday_picker_destroy (GtkObject *self);
108 button_toggle (GtkToggleButton *togglebutton,
113 SELECTION_CHANGED_SIGNAL,
117 static guint signals [LAST_SIGNAL] = { 0 } ;
120 * hildon_weekday_picker_get_type:
122 * Initializes and returns the type of a hildon weekday picker.
124 * @Returns: GType of #HildonWeekdayPicker
127 hildon_weekday_picker_get_type (void)
129 static GType picker_type = 0;
132 static const GTypeInfo picker_info = {
133 sizeof (HildonWeekdayPickerClass),
134 NULL, /* base_init */
135 NULL, /* base_finalize */
136 (GClassInitFunc) hildon_weekday_picker_class_init,
137 NULL, /* class_finalize */
138 NULL, /* class_data */
139 sizeof (HildonWeekdayPicker),
141 (GInstanceInitFunc) hildon_weekday_picker_init,
143 picker_type = g_type_register_static (GTK_TYPE_CONTAINER,
144 "HildonWeekdayPicker",
152 hildon_weekday_picker_class_init (HildonWeekdayPickerClass *picker_class)
154 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (picker_class);
155 GtkContainerClass *container_class = GTK_CONTAINER_CLASS (picker_class);
156 GObjectClass *object_class = G_OBJECT_CLASS (picker_class);
158 parent_class = g_type_class_peek_parent (picker_class);
160 g_type_class_add_private (picker_class,
161 sizeof (HildonWeekdayPickerPrivate));
163 /* Override virtual methods */
164 widget_class->size_request = hildon_weekday_picker_size_request;
165 widget_class->size_allocate = hildon_weekday_picker_size_allocate;
166 widget_class->focus = hildon_weekday_picker_focus;
167 container_class->forall = hildon_weekday_picker_forall;
168 GTK_OBJECT_CLASS (picker_class)->destroy = hildon_weekday_picker_destroy;
170 /* Create a signal for reporting user actions */
171 signals [SELECTION_CHANGED_SIGNAL] = g_signal_new ("selection_changed",
176 G_STRUCT_OFFSET (HildonWeekdayPickerClass, selection_changed),
178 gtk_marshal_VOID__INT,
179 G_TYPE_NONE, 1, G_TYPE_INT);
183 hildon_weekday_picker_init (HildonWeekdayPicker *picker)
185 HildonWeekdayPickerPrivate *priv;
188 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
191 /* weekday indexes to be used with nl_langinfo. These are shifted
192 * by one for glib compability */
194 -1, /* 0 = invalid date */
195 ABDAY_2, /* 1 = monday in glib */
196 ABDAY_3, /* 2 = tuesday in glib */
197 ABDAY_4, /* 3 = wednesday in glib */
198 ABDAY_5, /* 4 = thursday in glib */
199 ABDAY_6, /* 5 = friday in glib */
200 ABDAY_7, /* 6 = saturday in glib */
201 ABDAY_1 }; /* 7 = sunday in glib */
202 GtkSizeGroup *sgroup;
204 sgroup = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
206 /* Check our first weekday */
207 day = *nl_langinfo (_NL_TIME_FIRST_WEEKDAY);
210 /* Shift the days by one. This is done because GDateWeekday
211 * starts with Monday(1) and langinfo's first day is Sunday */
217 /* Initialize and pack day buttons */
218 for (i = 1; i <= 7; i++) {
220 gtk_toggle_button_new_with_label (nl_langinfo (wdays[day]));
221 priv->day_order_buttons [day] = priv->buttons [i];
227 g_signal_connect (GTK_WIDGET (priv->buttons [i]),
228 "toggled", G_CALLBACK (button_toggle), picker);
230 gtk_size_group_add_widget (sgroup, priv->buttons [i]);
232 gtk_widget_set_parent (priv->buttons [i], GTK_WIDGET (picker));
233 gtk_widget_show (priv->buttons[i]);
236 GTK_WIDGET_SET_FLAGS (picker, GTK_NO_WINDOW);
238 g_object_unref (sgroup);
242 * hildon_weekday_picker_new:
244 * Creates a new #HildonWeekdayPicker.
246 * Returns: pointer to a new #HildonWeekdayPicker widget.
249 hildon_weekday_picker_new (void)
251 return g_object_new (HILDON_TYPE_WEEKDAY_PICKER, NULL);
255 hildon_weekday_picker_forall (GtkContainer *container,
256 gboolean include_internals,
257 GtkCallback callback,
258 gpointer callback_data)
260 HildonWeekdayPicker *picker;
261 HildonWeekdayPickerPrivate *priv;
264 g_assert (container);
267 picker = HILDON_WEEKDAY_PICKER (container);
268 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
271 /* We only have internal children */
272 if (! include_internals)
275 /* Activate callback for each day button */
276 for (i = 1; i <= 7; ++i) {
277 (*callback) (priv->buttons [i], callback_data);
282 hildon_weekday_picker_destroy (GtkObject *self)
284 HildonWeekdayPickerPrivate *priv;
287 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (self);
290 /* Destroy internal children... */
291 for (i = 1; i <= 7; ++i) {
292 if (priv->buttons [i])
294 gtk_widget_unparent (priv->buttons [i]);
295 priv->buttons [i] = NULL;
299 /* ... and chain to parent. */
300 if (GTK_OBJECT_CLASS (parent_class)->destroy)
301 GTK_OBJECT_CLASS (parent_class)->destroy (self);
306 hildon_weekday_picker_size_request (GtkWidget *widget,
307 GtkRequisition *requisition)
309 HildonWeekdayPicker *picker;
310 HildonWeekdayPickerPrivate *priv;
314 picker = HILDON_WEEKDAY_PICKER (widget);
315 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
318 requisition->width = 0;
319 requisition->height = 0;
321 /* Request an area that is as wide as all of the buttons
322 together and tall enough to hold heightest button */
323 for (i = 1; i <= 7; ++i) {
324 gtk_widget_size_request (priv->buttons [i], &req);
325 requisition->width += req.width;
326 if (req.height > requisition->height)
327 requisition->height = req.height;
333 hildon_weekday_picker_size_allocate (GtkWidget *widget,
334 GtkAllocation *allocation)
336 HildonWeekdayPicker *picker;
337 HildonWeekdayPickerPrivate *priv;
340 GtkRequisition child_requisition;
343 GtkTextDirection direction;
346 g_assert (allocation);
348 /* Check orientation */
349 direction = gtk_widget_get_direction (widget);
351 picker = HILDON_WEEKDAY_PICKER (widget);
352 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
355 header_x = allocation->x;
356 widget->allocation = *allocation;
358 if (direction == GTK_TEXT_DIR_LTR || direction == GTK_TEXT_DIR_NONE)
363 /* Allocate day buttons side by side honouring the text direction */
364 for (i = 1; i <= 7; ++i) {
365 gtk_widget_get_child_requisition (priv->buttons[sval], &child_requisition);
368 alloc.y = allocation->y;
369 alloc.width = child_requisition.width;
370 alloc.height = child_requisition.height;
371 header_x += alloc.width;
372 gtk_widget_size_allocate (priv->buttons [sval], &alloc);
373 if (direction == GTK_TEXT_DIR_RTL)
381 hildon_weekday_picker_focus (GtkWidget *widget,
382 GtkDirectionType direction)
385 GtkDirectionType effective_direction;
387 g_assert (HILDON_IS_WEEKDAY_PICKER (widget));
389 retval = hildon_private_composite_focus (widget, direction, &effective_direction);
392 return GTK_WIDGET_CLASS (parent_class)->focus (widget, effective_direction);
398 button_toggle (GtkToggleButton *button,
401 HildonWeekdayPicker *picker;
402 HildonWeekdayPickerPrivate *priv;
408 picker = HILDON_WEEKDAY_PICKER (wpicker);
410 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
413 for (i = 1; i <= 7; ++i) {
414 if (GTK_WIDGET (button) == priv->day_order_buttons [i]) {
415 g_signal_emit (GTK_WIDGET (picker),
416 signals [SELECTION_CHANGED_SIGNAL], 0, i);
423 * hildon_weekday_picker_set_day:
424 * @picker: the #HildonWeekdayPicker widget
425 * @day: day to be set active
427 * Sets specified weekday active.
430 hildon_weekday_picker_set_day (HildonWeekdayPicker *picker,
433 HildonWeekdayPickerPrivate *priv;
435 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
436 g_return_if_fail (g_date_valid_weekday(day));
438 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
440 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
441 (priv->day_order_buttons[day]), TRUE);
445 * hildon_weekday_picker_unset_day:
446 * @picker: the #HildonWeekdayPicker widget
447 * @day: day to be set inactive
449 * Unselect specified weekday.
452 hildon_weekday_picker_unset_day (HildonWeekdayPicker *picker,
455 HildonWeekdayPickerPrivate *priv;
457 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
458 g_return_if_fail (g_date_valid_weekday (day));
460 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
463 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
464 (priv->day_order_buttons [day]), FALSE);
468 * hildon_weekday_picker_toggle_day:
469 * @picker: the #HildonWeekdayPicker widget
470 * @day: day to be toggled
472 * Toggles current status of the specified weekday.
475 hildon_weekday_picker_toggle_day (HildonWeekdayPicker *picker,
478 HildonWeekdayPickerPrivate *priv;
480 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
481 g_return_if_fail (g_date_valid_weekday (day));
483 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
486 gtk_toggle_button_set_active (
487 GTK_TOGGLE_BUTTON (priv->day_order_buttons [day]),
488 ! gtk_toggle_button_get_active(
489 GTK_TOGGLE_BUTTON (priv->day_order_buttons[day])));
493 * hildon_weekday_picker_set_all:
494 * @picker: the #HildonWeekdayPicker widget
496 * Sets all weekdays active.
499 hildon_weekday_picker_set_all (HildonWeekdayPicker *picker)
501 HildonWeekdayPickerPrivate *priv;
504 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
506 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
509 for (i = 1; i <= 7; i++)
510 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->buttons [i]), TRUE);
514 * hildon_weekday_picker_unset_all:
515 * @picker: the #HildonWeekdayPicker widget
517 * Sets all weekdays inactive.
520 hildon_weekday_picker_unset_all (HildonWeekdayPicker *picker)
522 HildonWeekdayPickerPrivate *priv;
525 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
527 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
530 for (i = 1; i <= 7; i++)
531 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->buttons [i]), FALSE);
535 * hildon_weekday_picker_isset_day:
536 * @picker: the #HildonWeekdayPicker widget
537 * @day: day to be checked.
539 * Checks if the specified weekday is set active.
541 * Returns: TRUE if the day is set, FALSE if the day is not set
544 hildon_weekday_picker_isset_day (HildonWeekdayPicker *picker,
547 HildonWeekdayPickerPrivate *priv;
549 g_return_val_if_fail (HILDON_IS_WEEKDAY_PICKER (picker), FALSE);
550 g_return_val_if_fail (g_date_valid_weekday (day), FALSE);
552 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
555 return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->day_order_buttons[day]));