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
67 #include <sys/types.h>
72 #include <gdk/gdkkeysyms.h>
74 #include "hildon-weekday-picker.h"
75 #include "hildon-private.h"
76 #include "hildon-weekday-picker-private.h"
78 static GtkContainerClass* parent_class;
81 hildon_weekday_picker_class_init (HildonWeekdayPickerClass *picker_class);
84 hildon_weekday_picker_init (HildonWeekdayPicker *picker);
87 hildon_weekday_picker_size_allocate (GtkWidget *widget,
88 GtkAllocation *allocation);
90 hildon_weekday_picker_focus (GtkWidget *widget,
91 GtkDirectionType direction);
93 hildon_weekday_picker_size_request (GtkWidget *widget,
94 GtkRequisition *requisition);
96 hildon_weekday_picker_forall (GtkContainer *container,
97 gboolean include_internals,
99 gpointer callback_data);
102 hildon_weekday_picker_destroy (GtkObject *self);
105 button_toggle (GtkToggleButton *togglebutton,
110 SELECTION_CHANGED_SIGNAL,
114 static guint signals [LAST_SIGNAL] = { 0 } ;
117 * hildon_weekday_picker_get_type:
119 * Initializes and returns the type of a hildon weekday picker.
121 * @Returns: GType of #HildonWeekdayPicker
124 hildon_weekday_picker_get_type (void)
126 static GType picker_type = 0;
129 static const GTypeInfo picker_info = {
130 sizeof (HildonWeekdayPickerClass),
131 NULL, /* base_init */
132 NULL, /* base_finalize */
133 (GClassInitFunc) hildon_weekday_picker_class_init,
134 NULL, /* class_finalize */
135 NULL, /* class_data */
136 sizeof (HildonWeekdayPicker),
138 (GInstanceInitFunc) hildon_weekday_picker_init,
140 picker_type = g_type_register_static (GTK_TYPE_CONTAINER,
141 "HildonWeekdayPicker",
149 hildon_weekday_picker_class_init (HildonWeekdayPickerClass *picker_class)
151 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (picker_class);
152 GtkContainerClass *container_class = GTK_CONTAINER_CLASS (picker_class);
153 GObjectClass *object_class = G_OBJECT_CLASS (picker_class);
155 parent_class = g_type_class_peek_parent (picker_class);
157 g_type_class_add_private (picker_class,
158 sizeof (HildonWeekdayPickerPrivate));
160 /* Override virtual methods */
161 widget_class->size_request = hildon_weekday_picker_size_request;
162 widget_class->size_allocate = hildon_weekday_picker_size_allocate;
163 widget_class->focus = hildon_weekday_picker_focus;
164 container_class->forall = hildon_weekday_picker_forall;
165 GTK_OBJECT_CLASS (picker_class)->destroy = hildon_weekday_picker_destroy;
167 /* Create a signal for reporting user actions */
168 signals [SELECTION_CHANGED_SIGNAL] = g_signal_new ("selection_changed",
173 G_STRUCT_OFFSET (HildonWeekdayPickerClass, selection_changed),
175 gtk_marshal_VOID__INT,
176 G_TYPE_NONE, 1, G_TYPE_INT);
180 hildon_weekday_picker_init (HildonWeekdayPicker *picker)
182 HildonWeekdayPickerPrivate *priv;
185 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
188 /* weekday indexes to be used with nl_langinfo. These are shifted
189 * by one for glib compability */
191 -1, /* 0 = invalid date */
192 ABDAY_2, /* 1 = monday in glib */
193 ABDAY_3, /* 2 = tuesday in glib */
194 ABDAY_4, /* 3 = wednesday in glib */
195 ABDAY_5, /* 4 = thursday in glib */
196 ABDAY_6, /* 5 = friday in glib */
197 ABDAY_7, /* 6 = saturday in glib */
198 ABDAY_1 }; /* 7 = sunday in glib */
199 GtkSizeGroup *sgroup;
201 sgroup = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
203 /* Check our first weekday */
204 day = *nl_langinfo (_NL_TIME_FIRST_WEEKDAY);
207 /* Shift the days by one. This is done because GDateWeekday
208 * starts with Monday(1) and langinfo's first day is Sunday */
214 /* Initialize and pack day buttons */
215 for (i = 1; i <= 7; i++) {
217 gtk_toggle_button_new_with_label (nl_langinfo (wdays[day]));
218 priv->day_order_buttons [day] = priv->buttons [i];
224 g_signal_connect (GTK_WIDGET (priv->buttons [i]),
225 "toggled", G_CALLBACK (button_toggle), picker);
227 gtk_size_group_add_widget (sgroup, priv->buttons [i]);
229 gtk_widget_set_parent (priv->buttons [i], GTK_WIDGET (picker));
230 gtk_widget_show (priv->buttons[i]);
233 GTK_WIDGET_SET_FLAGS (picker, GTK_NO_WINDOW);
235 g_object_unref (sgroup);
239 * hildon_weekday_picker_new:
241 * Creates a new #HildonWeekdayPicker.
243 * Returns: pointer to a new #HildonWeekdayPicker widget.
246 hildon_weekday_picker_new (void)
248 return g_object_new (HILDON_TYPE_WEEKDAY_PICKER, NULL);
252 hildon_weekday_picker_forall (GtkContainer *container,
253 gboolean include_internals,
254 GtkCallback callback,
255 gpointer callback_data)
257 HildonWeekdayPicker *picker;
258 HildonWeekdayPickerPrivate *priv;
261 g_assert (container);
264 picker = HILDON_WEEKDAY_PICKER (container);
265 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
268 /* We only have internal children */
269 if (! include_internals)
272 /* Activate callback for each day button */
273 for (i = 1; i <= 7; ++i) {
274 (*callback) (priv->buttons [i], callback_data);
279 hildon_weekday_picker_destroy (GtkObject *self)
281 HildonWeekdayPickerPrivate *priv;
284 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (self);
287 /* Destroy internal children... */
288 for (i = 1; i <= 7; ++i) {
289 if (priv->buttons [i])
291 gtk_widget_unparent (priv->buttons [i]);
292 priv->buttons [i] = NULL;
296 /* ... and chain to parent. */
297 if (GTK_OBJECT_CLASS (parent_class)->destroy)
298 GTK_OBJECT_CLASS (parent_class)->destroy (self);
303 hildon_weekday_picker_size_request (GtkWidget *widget,
304 GtkRequisition *requisition)
306 HildonWeekdayPicker *picker;
307 HildonWeekdayPickerPrivate *priv;
311 picker = HILDON_WEEKDAY_PICKER (widget);
312 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
315 requisition->width = 0;
316 requisition->height = 0;
318 /* Request an area that is as wide as all of the buttons
319 together and tall enough to hold heightest button */
320 for (i = 1; i <= 7; ++i) {
321 gtk_widget_size_request (priv->buttons [i], &req);
322 requisition->width += req.width;
323 if (req.height > requisition->height)
324 requisition->height = req.height;
330 hildon_weekday_picker_size_allocate (GtkWidget *widget,
331 GtkAllocation *allocation)
333 HildonWeekdayPicker *picker;
334 HildonWeekdayPickerPrivate *priv;
337 GtkRequisition child_requisition;
340 GtkTextDirection direction;
343 g_assert (allocation);
345 /* Check orientation */
346 direction = gtk_widget_get_direction (widget);
348 picker = HILDON_WEEKDAY_PICKER (widget);
349 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
352 header_x = allocation->x;
353 widget->allocation = *allocation;
355 if (direction == GTK_TEXT_DIR_LTR || direction == GTK_TEXT_DIR_NONE)
360 /* Allocate day buttons side by side honouring the text direction */
361 for (i = 1; i <= 7; ++i) {
362 gtk_widget_get_child_requisition (priv->buttons[sval], &child_requisition);
365 alloc.y = allocation->y;
366 alloc.width = child_requisition.width;
367 alloc.height = child_requisition.height;
368 header_x += alloc.width;
369 gtk_widget_size_allocate (priv->buttons [sval], &alloc);
370 if (direction == GTK_TEXT_DIR_RTL)
378 hildon_weekday_picker_focus (GtkWidget *widget,
379 GtkDirectionType direction)
382 GtkDirectionType effective_direction;
384 g_assert (HILDON_IS_WEEKDAY_PICKER (widget));
386 retval = hildon_private_composite_focus (widget, direction, &effective_direction);
389 return GTK_WIDGET_CLASS (parent_class)->focus (widget, effective_direction);
395 button_toggle (GtkToggleButton *button,
398 HildonWeekdayPicker *picker;
399 HildonWeekdayPickerPrivate *priv;
405 picker = HILDON_WEEKDAY_PICKER (wpicker);
407 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
410 for (i = 1; i <= 7; ++i) {
411 if (GTK_WIDGET (button) == priv->day_order_buttons [i]) {
412 g_signal_emit (GTK_WIDGET (picker),
413 signals [SELECTION_CHANGED_SIGNAL], 0, i);
420 * hildon_weekday_picker_set_day:
421 * @picker: the #HildonWeekdayPicker widget
422 * @day: day to be set active
424 * Sets specified weekday active.
427 hildon_weekday_picker_set_day (HildonWeekdayPicker *picker,
430 HildonWeekdayPickerPrivate *priv;
432 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
433 g_return_if_fail (g_date_valid_weekday(day));
435 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
437 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
438 (priv->day_order_buttons[day]), TRUE);
442 * hildon_weekday_picker_unset_day:
443 * @picker: the #HildonWeekdayPicker widget
444 * @day: day to be set inactive
446 * Unselect specified weekday.
449 hildon_weekday_picker_unset_day (HildonWeekdayPicker *picker,
452 HildonWeekdayPickerPrivate *priv;
454 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
455 g_return_if_fail (g_date_valid_weekday (day));
457 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
460 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
461 (priv->day_order_buttons [day]), FALSE);
465 * hildon_weekday_picker_toggle_day:
466 * @picker: the #HildonWeekdayPicker widget
467 * @day: day to be toggled
469 * Toggles current status of the specified weekday.
472 hildon_weekday_picker_toggle_day (HildonWeekdayPicker *picker,
475 HildonWeekdayPickerPrivate *priv;
477 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
478 g_return_if_fail (g_date_valid_weekday (day));
480 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
483 gtk_toggle_button_set_active (
484 GTK_TOGGLE_BUTTON (priv->day_order_buttons [day]),
485 ! gtk_toggle_button_get_active(
486 GTK_TOGGLE_BUTTON (priv->day_order_buttons[day])));
490 * hildon_weekday_picker_set_all:
491 * @picker: the #HildonWeekdayPicker widget
493 * Sets all weekdays active.
496 hildon_weekday_picker_set_all (HildonWeekdayPicker *picker)
498 HildonWeekdayPickerPrivate *priv;
501 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
503 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
506 for (i = 1; i <= 7; i++)
507 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->buttons [i]), TRUE);
511 * hildon_weekday_picker_unset_all:
512 * @picker: the #HildonWeekdayPicker widget
514 * Sets all weekdays inactive.
517 hildon_weekday_picker_unset_all (HildonWeekdayPicker *picker)
519 HildonWeekdayPickerPrivate *priv;
522 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
524 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
527 for (i = 1; i <= 7; i++)
528 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->buttons [i]), FALSE);
532 * hildon_weekday_picker_isset_day:
533 * @picker: the #HildonWeekdayPicker widget
534 * @day: day to be checked.
536 * Checks if the specified weekday is set active.
538 * Returns: TRUE if the day is set, FALSE if the day is not set
541 hildon_weekday_picker_isset_day (HildonWeekdayPicker *picker,
544 HildonWeekdayPickerPrivate *priv;
546 g_return_val_if_fail (HILDON_IS_WEEKDAY_PICKER (picker), FALSE);
547 g_return_val_if_fail (g_date_valid_weekday (day), FALSE);
549 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
552 return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->day_order_buttons[day]));