2 * This file is part of hildon-libs
4 * Copyright (C) 2005 Nokia Corporation.
6 * Contact: Luc Pionchon <luc.pionchon@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; either 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
25 /* GDate numbers days from 1 to 7 and G_DATE_MONDAY is 1st day. However
26 according to locale settings first day is sunday. To get around this
27 problem, we addjust GDate days numbering to be same as locale
36 #include <sys/types.h>
41 #include <gtk/gtksignal.h>
42 #include <gdk/gdkkeysyms.h>
43 #include <gtk/gtktogglebutton.h>
44 #include <gtk/gtksizegroup.h>
45 #include <gtk/gtkwindow.h>
46 #include "hildon-weekday-picker.h"
47 #include "hildon-composite-widget.h"
49 #define HILDON_WEEKDAY_PICKER_GET_PRIVATE(obj) \
50 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
51 HILDON_WEEKDAY_PICKER_TYPE, HildonWeekdayPickerPrivate));
53 static GtkContainerClass *parent_class;
55 typedef struct _HildonWeekdayPickerPrivate HildonWeekdayPickerPrivate;
58 hildon_weekday_picker_class_init(HildonWeekdayPickerClass * picker_class);
60 hildon_weekday_picker_init(HildonWeekdayPicker * picker);
62 hildon_weekday_picker_size_allocate(GtkWidget * widget,
63 GtkAllocation * allocation);
65 hildon_weekday_picker_size_request(GtkWidget * widget,
66 GtkRequisition * requisition);
68 hildon_weekday_picker_forall(GtkContainer * container,
69 gboolean include_internals,
70 GtkCallback callback, gpointer callback_data);
72 hildon_weekday_picker_destroy(GtkObject * self);
75 button_toggle(GtkToggleButton * togglebutton, gpointer wpicker);
77 struct _HildonWeekdayPickerPrivate {
78 GtkWidget *buttons[8]; /* weekday buttons in show order */
79 GtkWidget *day_order_buttons[8]; /* weekday buttons in glib day order */
83 SELECTION_CHANGED_SIGNAL,
87 static guint signals[LAST_SIGNAL] = { 0 };
89 GType hildon_weekday_picker_get_type(void)
91 static GType picker_type = 0;
94 static const GTypeInfo picker_info = {
95 sizeof(HildonWeekdayPickerClass),
97 NULL, /* base_finalize */
98 (GClassInitFunc) hildon_weekday_picker_class_init,
99 NULL, /* class_finalize */
100 NULL, /* class_data */
101 sizeof(HildonWeekdayPicker),
103 (GInstanceInitFunc) hildon_weekday_picker_init,
105 picker_type = g_type_register_static(GTK_TYPE_CONTAINER,
106 "HildonWeekdayPicker",
113 hildon_weekday_picker_class_init(HildonWeekdayPickerClass * picker_class)
115 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(picker_class);
116 GtkContainerClass *container_class = GTK_CONTAINER_CLASS(picker_class);
117 GObjectClass *object_class = G_OBJECT_CLASS(picker_class);
119 parent_class = g_type_class_peek_parent(picker_class);
121 g_type_class_add_private(picker_class,
122 sizeof(HildonWeekdayPickerPrivate));
124 /* Override virtual methods */
125 widget_class->size_request = hildon_weekday_picker_size_request;
126 widget_class->size_allocate = hildon_weekday_picker_size_allocate;
127 widget_class->focus = hildon_composite_widget_focus;
128 container_class->forall = hildon_weekday_picker_forall;
129 GTK_OBJECT_CLASS(picker_class)->destroy =
130 hildon_weekday_picker_destroy;
132 /* Create a signal for reporting user actions */
133 signals[SELECTION_CHANGED_SIGNAL] = g_signal_new("selection_changed",
139 (HildonWeekdayPickerClass,
140 selection_changed), NULL, NULL,
141 gtk_marshal_VOID__INT,
142 G_TYPE_NONE, 1, G_TYPE_INT);
146 hildon_weekday_picker_init(HildonWeekdayPicker * picker)
148 HildonWeekdayPickerPrivate *priv;
150 /* weekday indexes to be used with nl_langinfo. These are shifted
151 * by one for glib compability */
153 -1, /* 0 = invalid date */
154 ABDAY_2, /* 1 = monday in glib */
155 ABDAY_3, /* 2 = tuesday in glib */
156 ABDAY_4, /* 3 = wednesday in glib */
157 ABDAY_5, /* 4 = thursday in glib */
158 ABDAY_6, /* 5 = friday in glib */
159 ABDAY_7, /* 6 = saturday in glib */
160 ABDAY_1 }; /* 7 = sunday in glib */
161 GtkSizeGroup *sgroup;
163 sgroup = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
165 /* Check our first weekday */
166 day = *nl_langinfo(_NL_TIME_FIRST_WEEKDAY);
168 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
170 /* Shift the days by one. This is done because GDateWeekday
171 * starts with Monday(1) and langinfo's first day is Sunday */
176 /* Initialize and pack day buttons */
177 for (i = 1; i <= 7; i++) {
179 gtk_toggle_button_new_with_label(nl_langinfo(wdays[day]));
180 priv->day_order_buttons[day] = priv->buttons[i];
186 g_signal_connect(GTK_WIDGET(priv->buttons[i]),
187 "toggled", G_CALLBACK(button_toggle), picker);
189 gtk_size_group_add_widget(sgroup, priv->buttons[i]);
191 gtk_widget_set_parent(priv->buttons[i], GTK_WIDGET(picker));
192 gtk_widget_show(priv->buttons[i]);
195 GTK_WIDGET_SET_FLAGS(picker, GTK_NO_WINDOW);
197 g_object_unref( sgroup );
201 * hildon_weekday_picker_new:
203 * Creates a new #HildonWeekdayPicker.
205 * Return value: Pointer to a new @HildonWeekdayPicker widget.
207 GtkWidget *hildon_weekday_picker_new(void)
209 return g_object_new(HILDON_WEEKDAY_PICKER_TYPE, NULL);
213 hildon_weekday_picker_forall(GtkContainer * container,
214 gboolean include_internals, GtkCallback callback,
215 gpointer callback_data)
217 HildonWeekdayPicker *picker;
218 HildonWeekdayPickerPrivate *priv;
224 picker = HILDON_WEEKDAY_PICKER(container);
225 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
227 /* We only have internal children */
228 if (!include_internals)
231 /* Activate callback for each day button */
232 for (i = 1; i <= 7; ++i) {
233 (*callback) (priv->buttons[i], callback_data);
239 hildon_weekday_picker_destroy(GtkObject * self)
241 HildonWeekdayPickerPrivate *priv;
244 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(self);
246 /* Destroy internal children... */
247 for (i = 1; i <= 7; ++i) {
248 if (priv->buttons[i])
250 gtk_widget_unparent(priv->buttons[i]);
251 priv->buttons[i] = NULL;
255 /* ... and chain to parent. */
256 if (GTK_OBJECT_CLASS(parent_class)->destroy)
257 GTK_OBJECT_CLASS(parent_class)->destroy(self);
262 hildon_weekday_picker_size_request(GtkWidget * widget,
263 GtkRequisition *requisition)
265 HildonWeekdayPicker *picker;
266 HildonWeekdayPickerPrivate *priv;
270 picker = HILDON_WEEKDAY_PICKER(widget);
271 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
272 requisition->width = 0;
273 requisition->height = 0;
275 /* Request an area that is as wide as all of the buttons
276 together and tall enough to hold heightest button */
277 for (i = 1; i <= 7; ++i) {
278 gtk_widget_size_request(priv->buttons[i], &req);
279 requisition->width += req.width;
280 if (req.height > requisition->height)
281 requisition->height = req.height;
287 hildon_weekday_picker_size_allocate(GtkWidget * widget,
288 GtkAllocation * allocation)
290 HildonWeekdayPicker *picker;
291 HildonWeekdayPickerPrivate *priv;
294 GtkRequisition child_requisition;
297 GtkTextDirection direction;
300 g_assert(allocation);
302 /* Check orientation */
303 direction = gtk_widget_get_direction(widget);
305 picker = HILDON_WEEKDAY_PICKER(widget);
306 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
307 header_x = allocation->x;
308 widget->allocation = *allocation;
310 if (direction == GTK_TEXT_DIR_LTR || direction == GTK_TEXT_DIR_NONE)
315 /* Allocate day buttons side by side honouring the text direction */
316 for (i = 1; i <= 7; ++i) {
317 gtk_widget_get_child_requisition(priv->buttons[sval],
321 alloc.y = allocation->y;
322 alloc.width = child_requisition.width;
323 alloc.height = child_requisition.height;
324 header_x += alloc.width;
325 gtk_widget_size_allocate(priv->buttons[sval], &alloc);
326 if (direction == GTK_TEXT_DIR_RTL)
334 button_toggle(GtkToggleButton * button, gpointer wpicker)
336 HildonWeekdayPicker *picker;
337 HildonWeekdayPickerPrivate *priv;
343 picker = HILDON_WEEKDAY_PICKER(wpicker);
344 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
346 for (i = 1; i <= 7; ++i) {
347 if (GTK_WIDGET(button) == priv->day_order_buttons[i]) {
348 g_signal_emit (GTK_WIDGET(picker),
349 signals[SELECTION_CHANGED_SIGNAL], 0, i);
356 * hildon_weekday_picker_set_day:
357 * @picker: the @HildonWeekdayPicker widget
358 * @day: Day to be set active
360 * Set specified weekday active.
363 hildon_weekday_picker_set_day(HildonWeekdayPicker * picker,
366 HildonWeekdayPickerPrivate *priv;
368 g_return_if_fail(picker);
369 g_return_if_fail(g_date_valid_weekday(day));
371 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
373 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
374 (priv->day_order_buttons[day]), TRUE);
378 * hildon_weekday_picker_unset_day:
379 * @picker: the @HildonWeekdayPicker widget
380 * @day: Day to be set inactive
382 * Set specified weekday inactive.
385 hildon_weekday_picker_unset_day(HildonWeekdayPicker * picker,
388 HildonWeekdayPickerPrivate *priv;
390 g_return_if_fail(picker);
391 g_return_if_fail(g_date_valid_weekday(day));
393 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
395 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
396 (priv->day_order_buttons[day]), FALSE);
400 * hildon_weekday_picker_toggle_day:
401 * @picker: the @HildonWeekdayPicker widget
402 * @day: Day to be toggled
404 * Toggle current status of the specified weekday.
407 hildon_weekday_picker_toggle_day(HildonWeekdayPicker * picker,
410 HildonWeekdayPickerPrivate *priv;
412 g_return_if_fail(picker);
413 g_return_if_fail(g_date_valid_weekday(day));
415 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
417 gtk_toggle_button_set_active(
418 GTK_TOGGLE_BUTTON(priv->day_order_buttons[day]),
419 !gtk_toggle_button_get_active(
420 GTK_TOGGLE_BUTTON(priv->day_order_buttons[day])));
424 * hildon_weekday_picker_set_all:
425 * @picker: the @HildonWeekdayPicker widget
427 * Set all weekdays active.
430 hildon_weekday_picker_set_all(HildonWeekdayPicker * picker)
432 HildonWeekdayPickerPrivate *priv;
435 g_return_if_fail(picker);
437 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
439 for (i = 1; i <= 7; i++)
440 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->buttons[i]),
445 * hildon_weekday_picker_unset_all:
446 * @picker: the @HildonWeekdayPicker widget
448 * Set all weekdays inactive.
451 hildon_weekday_picker_unset_all(HildonWeekdayPicker * picker)
453 HildonWeekdayPickerPrivate *priv;
456 g_return_if_fail(picker);
458 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
460 for (i = 1; i <= 7; i++)
461 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->buttons[i]),
466 * hildon_weekday_picker_isset_day:
467 * @picker: the @HildonWeekdayPicker widget
468 * @day: Day to be checked.
470 * Check if the specified weekday is set active.
472 * Return value: TRUE if the day is set, FALSE is day is not set.
475 hildon_weekday_picker_isset_day(HildonWeekdayPicker * picker,
478 HildonWeekdayPickerPrivate *priv;
480 g_return_val_if_fail(picker, FALSE);
481 g_return_val_if_fail(g_date_valid_weekday(day), FALSE);
483 priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
485 return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
486 priv->day_order_buttons[day]));