2 * This file is part of hildon-libs
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
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 /* 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
49 #include "hildon-weekday-picker.h"
52 #include <sys/types.h>
57 #include <gtk/gtksignal.h>
58 #include <gdk/gdkkeysyms.h>
59 #include <gtk/gtktogglebutton.h>
60 #include <gtk/gtksizegroup.h>
61 #include <gtk/gtkwindow.h>
62 #include "hildon-composite-widget.h"
63 #include "hildon-weekday-picker-private.h"
65 static GtkContainerClass* parent_class;
68 hildon_weekday_picker_class_init (HildonWeekdayPickerClass *picker_class);
71 hildon_weekday_picker_init (HildonWeekdayPicker *picker);
74 hildon_weekday_picker_size_allocate (GtkWidget *widget,
75 GtkAllocation *allocation);
77 hildon_weekday_picker_size_request (GtkWidget *widget,
78 GtkRequisition *requisition);
80 hildon_weekday_picker_forall (GtkContainer *container,
81 gboolean include_internals,
83 gpointer callback_data);
86 hildon_weekday_picker_destroy (GtkObject *self);
89 button_toggle (GtkToggleButton *togglebutton,
94 SELECTION_CHANGED_SIGNAL,
98 static guint signals [LAST_SIGNAL] = { 0 } ;
101 hildon_weekday_picker_get_type (void)
103 static GType picker_type = 0;
106 static const GTypeInfo picker_info = {
107 sizeof (HildonWeekdayPickerClass),
108 NULL, /* base_init */
109 NULL, /* base_finalize */
110 (GClassInitFunc) hildon_weekday_picker_class_init,
111 NULL, /* class_finalize */
112 NULL, /* class_data */
113 sizeof (HildonWeekdayPicker),
115 (GInstanceInitFunc) hildon_weekday_picker_init,
117 picker_type = g_type_register_static (GTK_TYPE_CONTAINER,
118 "HildonWeekdayPicker",
126 hildon_weekday_picker_class_init (HildonWeekdayPickerClass *picker_class)
128 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (picker_class);
129 GtkContainerClass *container_class = GTK_CONTAINER_CLASS (picker_class);
130 GObjectClass *object_class = G_OBJECT_CLASS (picker_class);
132 parent_class = g_type_class_peek_parent (picker_class);
134 g_type_class_add_private (picker_class,
135 sizeof (HildonWeekdayPickerPrivate));
137 /* Override virtual methods */
138 widget_class->size_request = hildon_weekday_picker_size_request;
139 widget_class->size_allocate = hildon_weekday_picker_size_allocate;
140 widget_class->focus = hildon_composite_widget_focus;
141 container_class->forall = hildon_weekday_picker_forall;
142 GTK_OBJECT_CLASS (picker_class)->destroy = hildon_weekday_picker_destroy;
144 /* Create a signal for reporting user actions */
145 signals [SELECTION_CHANGED_SIGNAL] = g_signal_new ("selection_changed",
150 G_STRUCT_OFFSET (HildonWeekdayPickerClass, selection_changed),
152 gtk_marshal_VOID__INT,
153 G_TYPE_NONE, 1, G_TYPE_INT);
157 hildon_weekday_picker_init (HildonWeekdayPicker *picker)
159 HildonWeekdayPickerPrivate *priv;
162 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
165 /* weekday indexes to be used with nl_langinfo. These are shifted
166 * by one for glib compability */
168 -1, /* 0 = invalid date */
169 ABDAY_2, /* 1 = monday in glib */
170 ABDAY_3, /* 2 = tuesday in glib */
171 ABDAY_4, /* 3 = wednesday in glib */
172 ABDAY_5, /* 4 = thursday in glib */
173 ABDAY_6, /* 5 = friday in glib */
174 ABDAY_7, /* 6 = saturday in glib */
175 ABDAY_1 }; /* 7 = sunday in glib */
176 GtkSizeGroup *sgroup;
178 sgroup = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
180 /* Check our first weekday */
181 day = *nl_langinfo (_NL_TIME_FIRST_WEEKDAY);
184 /* Shift the days by one. This is done because GDateWeekday
185 * starts with Monday(1) and langinfo's first day is Sunday */
191 /* Initialize and pack day buttons */
192 for (i = 1; i <= 7; i++) {
194 gtk_toggle_button_new_with_label (nl_langinfo (wdays[day]));
195 priv->day_order_buttons [day] = priv->buttons [i];
201 g_signal_connect (GTK_WIDGET (priv->buttons [i]),
202 "toggled", G_CALLBACK (button_toggle), picker);
204 gtk_size_group_add_widget (sgroup, priv->buttons [i]);
206 gtk_widget_set_parent (priv->buttons [i], GTK_WIDGET (picker));
207 gtk_widget_show (priv->buttons[i]);
210 GTK_WIDGET_SET_FLAGS (picker, GTK_NO_WINDOW);
212 g_object_unref (sgroup);
216 * hildon_weekday_picker_new:
218 * Creates a new #HildonWeekdayPicker.
220 * Returns: pointer to a new #HildonWeekdayPicker widget.
223 hildon_weekday_picker_new (void)
225 return g_object_new (HILDON_TYPE_WEEKDAY_PICKER, NULL);
229 hildon_weekday_picker_forall (GtkContainer *container,
230 gboolean include_internals,
231 GtkCallback callback,
232 gpointer callback_data)
234 HildonWeekdayPicker *picker;
235 HildonWeekdayPickerPrivate *priv;
238 g_assert (container);
241 picker = HILDON_WEEKDAY_PICKER (container);
242 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
245 /* We only have internal children */
246 if (! include_internals)
249 /* Activate callback for each day button */
250 for (i = 1; i <= 7; ++i) {
251 (*callback) (priv->buttons [i], callback_data);
256 hildon_weekday_picker_destroy (GtkObject *self)
258 HildonWeekdayPickerPrivate *priv;
261 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (self);
264 /* Destroy internal children... */
265 for (i = 1; i <= 7; ++i) {
266 if (priv->buttons [i])
268 gtk_widget_unparent (priv->buttons [i]);
269 priv->buttons [i] = NULL;
273 /* ... and chain to parent. */
274 if (GTK_OBJECT_CLASS (parent_class)->destroy)
275 GTK_OBJECT_CLASS (parent_class)->destroy (self);
280 hildon_weekday_picker_size_request (GtkWidget *widget,
281 GtkRequisition *requisition)
283 HildonWeekdayPicker *picker;
284 HildonWeekdayPickerPrivate *priv;
288 picker = HILDON_WEEKDAY_PICKER (widget);
289 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
292 requisition->width = 0;
293 requisition->height = 0;
295 /* Request an area that is as wide as all of the buttons
296 together and tall enough to hold heightest button */
297 for (i = 1; i <= 7; ++i) {
298 gtk_widget_size_request (priv->buttons [i], &req);
299 requisition->width += req.width;
300 if (req.height > requisition->height)
301 requisition->height = req.height;
307 hildon_weekday_picker_size_allocate (GtkWidget *widget,
308 GtkAllocation *allocation)
310 HildonWeekdayPicker *picker;
311 HildonWeekdayPickerPrivate *priv;
314 GtkRequisition child_requisition;
317 GtkTextDirection direction;
320 g_assert (allocation);
322 /* Check orientation */
323 direction = gtk_widget_get_direction (widget);
325 picker = HILDON_WEEKDAY_PICKER (widget);
326 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
329 header_x = allocation->x;
330 widget->allocation = *allocation;
332 if (direction == GTK_TEXT_DIR_LTR || direction == GTK_TEXT_DIR_NONE)
337 /* Allocate day buttons side by side honouring the text direction */
338 for (i = 1; i <= 7; ++i) {
339 gtk_widget_get_child_requisition (priv->buttons[sval], &child_requisition);
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,
358 HildonWeekdayPicker *picker;
359 HildonWeekdayPickerPrivate *priv;
365 picker = HILDON_WEEKDAY_PICKER (wpicker);
367 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
370 for (i = 1; i <= 7; ++i) {
371 if (GTK_WIDGET (button) == priv->day_order_buttons [i]) {
372 g_signal_emit (GTK_WIDGET (picker),
373 signals [SELECTION_CHANGED_SIGNAL], 0, i);
380 * hildon_weekday_picker_set_day:
381 * @picker: the #HildonWeekdayPicker widget
382 * @day: day to be set active
384 * Sets specified weekday active.
387 hildon_weekday_picker_set_day (HildonWeekdayPicker *picker,
390 HildonWeekdayPickerPrivate *priv;
392 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
393 g_return_if_fail (g_date_valid_weekday(day));
395 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
397 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
398 (priv->day_order_buttons[day]), TRUE);
402 * hildon_weekday_picker_unset_day:
403 * @picker: the #HildonWeekdayPicker widget
404 * @day: day to be set inactive
406 * Unselect specified weekday.
409 hildon_weekday_picker_unset_day (HildonWeekdayPicker *picker,
412 HildonWeekdayPickerPrivate *priv;
414 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
415 g_return_if_fail (g_date_valid_weekday (day));
417 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
420 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
421 (priv->day_order_buttons [day]), FALSE);
425 * hildon_weekday_picker_toggle_day:
426 * @picker: the #HildonWeekdayPicker widget
427 * @day: day to be toggled
429 * Toggles current status of the specified weekday.
432 hildon_weekday_picker_toggle_day (HildonWeekdayPicker *picker,
435 HildonWeekdayPickerPrivate *priv;
437 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
438 g_return_if_fail (g_date_valid_weekday (day));
440 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
443 gtk_toggle_button_set_active (
444 GTK_TOGGLE_BUTTON (priv->day_order_buttons [day]),
445 ! gtk_toggle_button_get_active(
446 GTK_TOGGLE_BUTTON (priv->day_order_buttons[day])));
450 * hildon_weekday_picker_set_all:
451 * @picker: the #HildonWeekdayPicker widget
453 * Sets all weekdays active.
456 hildon_weekday_picker_set_all (HildonWeekdayPicker *picker)
458 HildonWeekdayPickerPrivate *priv;
461 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
463 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
466 for (i = 1; i <= 7; i++)
467 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->buttons [i]), TRUE);
471 * hildon_weekday_picker_unset_all:
472 * @picker: the #HildonWeekdayPicker widget
474 * Sets all weekdays inactive.
477 hildon_weekday_picker_unset_all (HildonWeekdayPicker *picker)
479 HildonWeekdayPickerPrivate *priv;
482 g_return_if_fail (HILDON_IS_WEEKDAY_PICKER (picker));
484 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
487 for (i = 1; i <= 7; i++)
488 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->buttons [i]), FALSE);
492 * hildon_weekday_picker_isset_day:
493 * @picker: the #HildonWeekdayPicker widget
494 * @day: day to be checked.
496 * Checks if the specified weekday is set active.
498 * Returns: TRUE if the day is set, FALSE if the day is not set
501 hildon_weekday_picker_isset_day (HildonWeekdayPicker *picker,
504 HildonWeekdayPickerPrivate *priv;
506 g_return_val_if_fail (HILDON_IS_WEEKDAY_PICKER (picker), FALSE);
507 g_return_val_if_fail (g_date_valid_weekday (day), FALSE);
509 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE (picker);
512 return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->day_order_buttons[day]));