2 * This file is part of hildon-libs
4 * Copyright (C) 2005, 2006 Nokia Corporation.
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-time-picker
27 * @short_description: A dialog popup widget which lets the user set the time
28 * @see_also: #HildonTimeEditor
30 * #HildonTimePicker is a dialog popup widget which lets the user set the time,
31 * using up/down arrows on hours and minutes. There are two arrows for minutes,
32 * so that minutes can be added also in 10 min increments.This widget is mainly
33 * used as a part of #HildonTimeEditor implementation.
36 #include "hildon-time-picker.h"
37 #include <hildon-widgets/hildon-defines.h>
38 #include <hildon-widgets/hildon-private.h>
39 #include <hildon-widgets/gtk-infoprint.h>
41 #include <gdk/gdkkeysyms.h>
54 #define _(String) dgettext(PACKAGE, String)
56 #define HILDON_TIME_PICKER_GET_PRIVATE(obj) \
57 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
58 HILDON_TYPE_TIME_PICKER, HildonTimePickerPrivate))
60 #define DEFAULT_HOURS 1
61 #define DEFAULT_MINUTES 1
62 #define DEFAULT_ARROW_WIDTH 26
63 #define DEFAULT_ARROW_HEIGHT 26
65 #define MINS_IN_1H (60)
66 #define MINS_IN_24H (MINS_IN_1H * 24)
67 #define MINS_IN_12H (MINS_IN_1H * 12)
69 #define HILDON_TIME_PICKER_LABEL_X_PADDING 0
70 #define HILDON_TIME_PICKER_LABEL_Y_PADDING 1
73 /* Indices for grouped labels in priv->widgets */
77 WIDGET_GROUP_10_MINUTES,
78 WIDGET_GROUP_1_MINUTES,
84 /* Indices for up/down buttons in group->buttons */
99 /* buttons are used for hours and minutes, but not for am/pm */
100 GtkWidget *buttons[BUTTON_COUNT];
102 } HildonTimePickerWidgetGroup;
104 static GtkDialogClass *parent_class;
106 struct _HildonTimePickerPrivate
108 HildonTimePickerWidgetGroup widgets[WIDGET_GROUP_COUNT];
114 guint minutes; /* time in minutes since midnight */
115 gint mul; /* for key repeat handling */
118 guint show_ampm : 1; /* 12 hour clock, show AM/PM */
120 guint button_press : 1;
121 guint start_key_repeat : 1;
130 static gint button_multipliers[WIDGET_GROUP_COUNT][2] =
132 { MINS_IN_1H, -MINS_IN_1H },
139 hildon_time_picker_class_init( HildonTimePickerClass *klass );
142 hildon_time_picker_init( HildonTimePicker *picker );
145 hildon_time_picker_key_repeat_timeout( gpointer tpicker );
148 hildon_time_picker_change_time( HildonTimePicker *picker, guint minutes );
151 hildon_time_picker_ampm_release( GtkWidget *widget, GdkEvent *event,
152 HildonTimePicker *picker );
155 hildon_time_picker_arrow_press( GtkWidget *widget, GdkEvent *event,
156 HildonTimePicker *picker );
158 hildon_time_picker_arrow_release( GtkWidget *widget, GdkEvent *event,
159 HildonTimePicker *picker );
162 hildon_time_picker_finalize( GObject *object );
165 hildon_time_picker_get_property( GObject *object, guint param_id,
166 GValue *value, GParamSpec *pspec );
169 hildon_time_picker_set_property( GObject *object, guint param_id,
170 const GValue *value, GParamSpec *pspec );
173 hildon_time_picker_event_box_focus_in( GtkWidget *widget, GdkEvent *event,
177 hildon_time_picker_event_box_focus_out( GtkWidget *widget, GdkEvent *event,
181 hildon_time_picker_event_box_key_press( GtkWidget *widget, GdkEventKey *event,
182 HildonTimePicker *picker );
185 hildon_time_picker_event_box_key_release( GtkWidget *widget, GdkEventKey *event,
186 HildonTimePicker *picker );
189 hildon_time_picker_event_box_button_press( GtkWidget *widget, GdkEventKey *event,
193 hildon_time_picker_map( GtkWidget *widget );
196 frame_size_request (GtkWidget *widget, GtkRequisition *requistion);
198 GType hildon_time_picker_get_type( void )
200 static GType picker_type = 0;
204 static const GTypeInfo picker_info =
206 sizeof(HildonTimePickerClass),
207 NULL, /* base_init */
208 NULL, /* base_finalize */
209 (GClassInitFunc)hildon_time_picker_class_init,
210 NULL, /* class_finalize */
211 NULL, /* class_data */
212 sizeof(HildonTimePicker),
214 (GInstanceInitFunc)hildon_time_picker_init,
216 picker_type = g_type_register_static( GTK_TYPE_DIALOG, "HildonTimePicker",
224 hildon_time_picker_class_init( HildonTimePickerClass *klass )
226 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
227 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
228 parent_class = g_type_class_peek_parent( klass );
230 gobject_class->finalize = hildon_time_picker_finalize;
231 gobject_class->get_property = hildon_time_picker_get_property;
232 gobject_class->set_property = hildon_time_picker_set_property;
233 widget_class->map = hildon_time_picker_map;
236 * HildonTimePicker:minutes:
238 * Currently selected time in minutes since midnight.
240 g_object_class_install_property( gobject_class, PROP_MINUTES,
241 g_param_spec_uint("minutes",
243 "The selected time in minutes "
246 G_PARAM_READABLE | G_PARAM_WRITABLE) );
248 gtk_widget_class_install_style_property( widget_class,
249 g_param_spec_uint("arrow-width",
251 "Increase/decrease arrows width.",
256 gtk_widget_class_install_style_property( widget_class,
257 g_param_spec_uint("arrow-height",
259 "Increase/decrease arrows height.",
261 DEFAULT_ARROW_HEIGHT,
264 g_type_class_add_private( klass, sizeof(HildonTimePickerPrivate) );
267 /* Okay, this is really bad. We make the requisition of the frames a bit larger
268 * so that it doesn't "change" when digits are changed (see #37489). It's a
269 * really bad solution to a problem, but the whole layout of the time picker is
270 * on crack anyways */
271 static void frame_size_request (GtkWidget *widget, GtkRequisition *requistion)
273 int framed = requistion->width / 10;
274 requistion->width = (framed + 1) * 10;
277 static void hildon_time_picker_init( HildonTimePicker *picker )
279 HildonTimePickerPrivate *priv = HILDON_TIME_PICKER_GET_PRIVATE(picker);
280 gint widget_group_table_column_pos[WIDGET_GROUP_COUNT];
281 GtkSettings *settings = NULL;
282 GtkDialog *dialog = GTK_DIALOG(picker);
283 GtkTable *table = NULL;
284 GtkWidget *maintocenter, *colon_label;
285 const struct tm *local = NULL;
288 GtkSizeGroup *size_group;
292 widget_group_table_column_pos[WIDGET_GROUP_HOURS] = 1;
293 widget_group_table_column_pos[WIDGET_GROUP_10_MINUTES] = 3;
294 widget_group_table_column_pos[WIDGET_GROUP_1_MINUTES] = 4;
295 widget_group_table_column_pos[WIDGET_GROUP_AMPM] = 5;
297 /* Get AM/PM strings from locale. If they're set, the time is wanted
299 priv->am_symbol = g_strdup(nl_langinfo(AM_STR));
300 priv->pm_symbol = g_strdup(nl_langinfo(PM_STR));
302 priv->show_ampm = priv->am_symbol[0] != '\0';
305 /* Check if AM/PM should be before or after time.
306 %p is the AM/PM string, so we assume that if the format string
307 begins with %p it's in the beginning, and in any other case it's
308 in the end (although that's not necessarily the case). */
309 if (strncmp(nl_langinfo(T_FMT_AMPM), "%p", 2) == 0)
311 /* Before time. Update column position. */
312 priv->ampm_left = TRUE;
313 widget_group_table_column_pos[WIDGET_GROUP_AMPM] = 0;
317 gtk_widget_push_composite_child();
319 /* Pack all our internal widgets into a table */
320 table = GTK_TABLE(gtk_table_new(3, 6, FALSE));
322 /* Put everything centered into window */
323 maintocenter = gtk_alignment_new( 0.5, 0, 0, 0 );
325 /* Create our internal widgets */
326 for (i = 0; i < WIDGET_GROUP_COUNT; i++)
328 HildonTimePickerWidgetGroup *group = &priv->widgets[i];
329 gint table_column = widget_group_table_column_pos[i];
331 /* Create frame and attach to table. With AM/PM label we're attaching
333 group->frame = gtk_frame_new(NULL);
334 if (i != WIDGET_GROUP_AMPM)
336 gtk_table_attach(table, group->frame, table_column, table_column + 1,
337 1, 2, GTK_EXPAND, GTK_EXPAND, 0, 0);
341 /* FIXME: is it needed to force it to 0 here? */
342 gtk_container_set_border_width(GTK_CONTAINER(group->frame), 0);
344 /* Create eventbox inside frame */
345 group->eventbox = gtk_event_box_new();
346 gtk_container_add(GTK_CONTAINER(group->frame), group->eventbox);
348 g_object_set(group->eventbox, "can-focus", TRUE, NULL);
349 gtk_widget_set_events(group->eventbox,
350 GDK_FOCUS_CHANGE_MASK | GDK_BUTTON_PRESS_MASK );
352 /* Connect signals to eventbox */
353 g_signal_connect(group->eventbox, "key-release-event",
354 G_CALLBACK(hildon_time_picker_event_box_key_release),
356 g_signal_connect(group->eventbox, "key-press-event",
357 G_CALLBACK(hildon_time_picker_event_box_key_press),
359 g_signal_connect(group->eventbox, "focus-in-event",
360 G_CALLBACK(hildon_time_picker_event_box_focus_in),
362 g_signal_connect(group->eventbox, "focus-out-event",
363 G_CALLBACK(hildon_time_picker_event_box_focus_out),
365 g_signal_connect(group->eventbox, "button-press-event",
366 G_CALLBACK(hildon_time_picker_event_box_button_press),
369 /* Create label inside eventbox */
370 group->label = GTK_LABEL(gtk_label_new(NULL));
371 g_signal_connect(group->frame, "size-request",
372 G_CALLBACK(frame_size_request),
374 gtk_misc_set_alignment (GTK_MISC (group->label), 0.5, 0.5);
375 gtk_container_add(GTK_CONTAINER(group->eventbox), GTK_WIDGET(group->label));
377 if (i != WIDGET_GROUP_AMPM)
381 /* Add some padding to hour and minute labels, and make them bigger */
382 gtk_misc_set_padding(GTK_MISC(group->label),
383 HILDON_TIME_PICKER_LABEL_X_PADDING,
384 HILDON_TIME_PICKER_LABEL_Y_PADDING);
385 gtk_widget_set_name(GTK_WIDGET(group->label), "osso-LargeFont");
387 /* Create up and down buttons for hours and mins */
388 for (button = 0; button < BUTTON_COUNT; button++)
390 gint table_row = button == BUTTON_UP ? 0 : 2;
392 group->buttons[button] = gtk_button_new();
393 gtk_table_attach(table, group->buttons[button],
394 table_column, table_column + 1,
395 table_row, table_row + 1,
396 GTK_SHRINK, GTK_SHRINK, 0, 0);
397 g_object_set(group->buttons[button], "can-focus", FALSE, NULL);
399 /* Connect signals */
400 g_signal_connect(group->buttons[button], "button-press-event",
401 G_CALLBACK(hildon_time_picker_arrow_press), picker);
402 g_signal_connect(group->buttons[button], "button-release-event",
403 G_CALLBACK(hildon_time_picker_arrow_release), picker);
406 gtk_widget_set_name(group->buttons[BUTTON_UP],
407 "hildon-time-picker-up");
408 gtk_widget_set_name(group->buttons[BUTTON_DOWN],
409 "hildon-time-picker-down");
413 /* Label between hour and minutes */
414 colon_label = gtk_label_new(NULL);
415 _hildon_time_editor_get_time_separators(GTK_LABEL(colon_label), NULL);
417 gtk_table_attach(table, colon_label, 2, 3, 1, 2,
418 GTK_SHRINK, GTK_SHRINK, 6, 0); /* FIXME: magic */
419 gtk_widget_set_name(colon_label, "osso-LargeFont" );
423 priv->key_repeat = 0;
424 priv->start_key_repeat = FALSE;
426 priv->button_press = FALSE;
428 gtk_table_set_row_spacing( table, 0, 6 );
429 gtk_table_set_row_spacing( table, 1, 6 );
433 gint table_column = widget_group_table_column_pos[WIDGET_GROUP_AMPM];
434 GtkWidget *ampmtotop = NULL;
436 /* Show the AM/PM label centered vertically */
437 ampmtotop = gtk_alignment_new( 0, 0.5, 0, 0 );
438 gtk_table_attach(table, ampmtotop, table_column, table_column + 1,
439 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
440 gtk_container_add(GTK_CONTAINER(ampmtotop),
441 priv->widgets[WIDGET_GROUP_AMPM].frame);
443 if (table_column != 0)
444 gtk_table_set_col_spacing(table, table_column - 1, 9);
446 /* Connect AM/PM signal handlers */
447 g_signal_connect(priv->widgets[WIDGET_GROUP_AMPM].eventbox,
448 "button-release-event",
449 G_CALLBACK(hildon_time_picker_ampm_release), picker);
452 gtk_widget_pop_composite_child();
454 /* Get button press repeater timeout from settings (in milliseconds) */
455 settings = gtk_settings_get_default();
456 g_object_get( settings, "gtk-update-timeout", &priv->key_repeat, NULL );
458 /* This dialog isn't modal */
459 gtk_window_set_modal( GTK_WINDOW(dialog), FALSE );
460 /* And final dialog packing */
461 gtk_dialog_set_has_separator( dialog, FALSE );
462 gtk_dialog_add_button( dialog, _("ecdg_bd_time_picker_close"),
465 gtk_container_add( GTK_CONTAINER(maintocenter), GTK_WIDGET(table) );
466 gtk_box_pack_start( GTK_BOX(dialog->vbox), maintocenter, TRUE, FALSE, 0 );
468 /* Set default time to current time */
469 stamp = time( NULL );
470 local = localtime( &stamp );
471 hildon_time_picker_set_time( picker, local->tm_hour, local->tm_min );
473 gtk_widget_show_all( maintocenter );
477 hildon_time_picker_set_property( GObject *object, guint param_id,
478 const GValue *value, GParamSpec *pspec )
480 HildonTimePicker *picker = HILDON_TIME_PICKER(object);
485 hildon_time_picker_change_time( picker, g_value_get_uint(value) );
489 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
495 hildon_time_picker_finalize( GObject *object )
497 HildonTimePicker *picker = HILDON_TIME_PICKER(object);
499 /* Make sure the timer is stopped */
500 if (picker->priv->timer_id)
501 g_source_remove(picker->priv->timer_id);
503 g_free(picker->priv->am_symbol);
504 g_free(picker->priv->pm_symbol);
506 if (G_OBJECT_CLASS(parent_class)->finalize)
507 G_OBJECT_CLASS(parent_class)->finalize(object);
511 hildon_time_picker_get_property( GObject *object, guint param_id,
512 GValue *value, GParamSpec *pspec )
514 HildonTimePickerPrivate *priv = HILDON_TIME_PICKER(object)->priv;
519 g_value_set_uint( value, priv->minutes );
523 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
529 hildon_time_picker_map( GtkWidget *widget )
533 HildonTimePickerPrivate *priv = HILDON_TIME_PICKER(widget)->priv;
535 /* Widget is now mapped. Set border for the dialog. */
536 gdk_window_set_decorations( widget->window, GDK_DECOR_BORDER );
538 /* Update hour/minute up/down buttons sizes from style properties */
539 gtk_widget_style_get( widget,
540 "arrow-width", &width,
541 "arrow-height", &height, NULL );
542 for (i = 0; i < WIDGET_GROUP_COUNT; i++)
544 if (priv->widgets[i].buttons[0] != NULL)
546 for (button = 0; button < BUTTON_COUNT; button++)
548 gtk_widget_set_size_request(priv->widgets[i].buttons[button],
554 GTK_WIDGET_CLASS(parent_class)->map( widget );
559 hildon_time_picker_event_box_button_press( GtkWidget *widget,
560 GdkEventKey *event, gpointer unused )
562 /* Clicked hour/minute field. Move focus to it. */
563 gtk_widget_grab_focus( widget );
568 hildon_time_picker_ampm_release( GtkWidget *widget, GdkEvent *event,
569 HildonTimePicker *picker )
571 /* Clicked AM/PM label. Move focus to it and move the time by 12 hours. */
572 gtk_widget_grab_focus( widget );
573 hildon_time_picker_change_time( picker, picker->priv->minutes > MINS_IN_12H ?
574 picker->priv->minutes - MINS_IN_12H :
575 picker->priv->minutes + MINS_IN_12H );
580 hildon_time_picker_arrow_press( GtkWidget *widget, GdkEvent *event,
581 HildonTimePicker *picker )
583 HildonTimePickerPrivate *priv = picker->priv;
587 /* Make sure we don't add repeat timer twice. Normally it shouldn't
588 happen but WM can cause button release to be lost. */
589 if( priv->button_press )
592 priv->start_key_repeat = priv->button_press = TRUE;
594 /* Find the widget which was clicked */
596 for (i = 0; i < WIDGET_GROUP_COUNT; i++)
598 for (button = 0; button < BUTTON_COUNT; button++)
600 if (priv->widgets[i].buttons[button] == widget)
602 /* Update multiplier and move the focus to the clicked field */
603 priv->mul = button_multipliers[i][button];
604 gtk_widget_grab_focus(priv->widgets[i].eventbox);
609 g_assert(priv->mul != 0);
611 /* Change the time now, wrapping if needed. */
612 newval = priv->minutes + priv->mul;
614 newval += MINS_IN_24H;
616 hildon_time_picker_change_time( picker, newval );
618 /* Keep changing the time as long as button is being pressed.
619 The first repeat takes 3 times longer to start than the rest. */
620 priv->timer_id = g_timeout_add(priv->key_repeat * 3,
621 hildon_time_picker_key_repeat_timeout,
627 hildon_time_picker_arrow_release( GtkWidget *widget, GdkEvent *event,
628 HildonTimePicker *picker )
630 HildonTimePickerPrivate *priv = picker->priv;
633 /* Stop repeat timer */
634 g_source_remove( priv->timer_id );
637 priv->button_press = FALSE;
642 hildon_time_picker_event_box_focus_in( GtkWidget *widget, GdkEvent *event,
645 /* Draw the widget in selected state so focus shows clearly. */
646 gtk_widget_set_state( widget, GTK_STATE_SELECTED );
651 hildon_time_picker_event_box_focus_out( GtkWidget *widget, GdkEvent *event,
654 /* Draw the widget in normal state */
655 gtk_widget_set_state( widget, GTK_STATE_NORMAL );
660 hildon_time_picker_lookup_eventbox_group(HildonTimePicker *picker,
665 for (i = 0; i < WIDGET_GROUP_COUNT; i++)
667 if (picker->priv->widgets[i].eventbox == widget)
674 hildon_time_picker_event_box_key_press( GtkWidget *widget, GdkEventKey *event,
675 HildonTimePicker *picker )
677 HildonTimePickerPrivate *priv = picker->priv;
678 HildonTimePickerWidgetGroup *group;
681 /* If mouse button is already being pressed, ignore this keypress */
685 group_idx = hildon_time_picker_lookup_eventbox_group(picker, widget);
686 group = group_idx < 0 ? NULL : &picker->priv->widgets[group_idx];
688 /* Handle keypresses in hour/minute/AMPM fields */
689 switch( event->keyval )
695 gint button = event->keyval == GDK_Up ? BUTTON_UP : BUTTON_DOWN;
697 if (group->buttons[button] != NULL)
699 /* Fake a button up/down press */
700 hildon_time_picker_arrow_press(group->buttons[button], NULL, picker);
701 gtk_widget_set_state(group->buttons[button], GTK_STATE_SELECTED);
705 /* Fake a AM/PM button release */
706 g_assert(group_idx == WIDGET_GROUP_AMPM);
707 hildon_time_picker_ampm_release(group->eventbox, NULL, picker);
713 /* If we're in leftmost field, stop this keypress signal.
714 Otherwise let the default key handler move focus to field in left. */
715 if (priv->show_ampm && priv->ampm_left)
717 /* AM/PM is the leftmost field */
718 if (group_idx == WIDGET_GROUP_AMPM)
723 /* Hours is the leftmost field */
724 if (group_idx == WIDGET_GROUP_HOURS)
730 /* If we're in rightmost field, stop this keypress signal.
731 Otherwise let the default key handler move focus to field in right. */
732 if (priv->show_ampm && !priv->ampm_left)
734 /* AM/PM is the rightmost field */
735 if (group_idx == WIDGET_GROUP_AMPM)
740 /* 1-minutes is the leftmost field */
741 if (group_idx == WIDGET_GROUP_1_MINUTES)
747 gtk_dialog_response (GTK_DIALOG (picker), GTK_RESPONSE_CANCEL);
751 gtk_dialog_response (GTK_DIALOG (picker), GTK_RESPONSE_OK);
759 hildon_time_picker_event_box_key_release( GtkWidget *widget, GdkEventKey *event,
760 HildonTimePicker *picker )
762 HildonTimePickerWidgetGroup *group;
765 /* Fake a button release if in key-press handler we faked a button press. */
766 switch( event->keyval )
770 group_idx = hildon_time_picker_lookup_eventbox_group(picker, widget);
773 gint button = event->keyval == GDK_Up ? BUTTON_UP : BUTTON_DOWN;
775 group = &picker->priv->widgets[group_idx];
776 if (group->buttons[button] != NULL)
778 /* Fake a button up/down press */
779 gtk_widget_set_state(group->buttons[button], GTK_STATE_NORMAL);
780 hildon_time_picker_arrow_release(group->buttons[button],
789 /* Button up/down is being pressed. Update the time. */
791 hildon_time_picker_key_repeat_timeout( gpointer tpicker )
793 HildonTimePicker *picker;
794 HildonTimePickerPrivate *priv = NULL;
797 GDK_THREADS_ENTER ();
799 picker = HILDON_TIME_PICKER(tpicker);
800 g_assert(picker != NULL);
804 /* Change the time, wrapping if needed */
805 newval = priv->minutes + priv->mul;
807 newval += MINS_IN_24H;
809 hildon_time_picker_change_time( picker, newval );
811 if( priv->start_key_repeat )
813 /* This is the first repeat. Shorten the timeout to key_repeat
814 (instead of the first time's 3*key_repeat) */
815 priv->timer_id = g_timeout_add(priv->key_repeat,
816 hildon_time_picker_key_repeat_timeout,
818 priv->start_key_repeat = FALSE;
820 GDK_THREADS_LEAVE ();
824 GDK_THREADS_LEAVE ();
831 hildon_time_picker_change_time( HildonTimePicker *picker, guint minutes )
833 HildonTimePickerPrivate *priv = picker->priv;
836 gboolean ampm = TRUE;
838 /* If the minutes isn't in valid range, wrap them. */
839 minutes %= MINS_IN_24H;
841 if( priv->minutes == minutes )
844 /* Minutes changed. Update widgets to show the new time. */
845 priv->minutes = minutes;
849 /* am < 12:00 <= pm */
850 ampm = !((guint)(minutes / MINS_IN_12H));
851 /* 12:00 - 23:59 -> 00:00 - 11:59 */
852 minutes %= MINS_IN_12H;
853 if( minutes < MINS_IN_1H )
854 /* 00:mm is always shown as 12:mm */
855 minutes += MINS_IN_12H;
857 /* Update the AM/PM label */
858 gtk_label_set_text(priv->widgets[WIDGET_GROUP_AMPM].label,
859 ampm ? priv->am_symbol : priv->pm_symbol);
862 /* Update hour and minute fields */
863 hours = minutes / MINS_IN_1H;
864 minutes %= MINS_IN_1H;
866 snprintf(str, sizeof(str), "%02d", hours);
867 gtk_label_set_text(priv->widgets[WIDGET_GROUP_HOURS].label, str);
869 snprintf(str, sizeof(str), "%d", minutes / 10);
870 gtk_label_set_text(priv->widgets[WIDGET_GROUP_10_MINUTES].label, str);
872 snprintf(str, sizeof(str), "%d", minutes % 10);
873 gtk_label_set_text(priv->widgets[WIDGET_GROUP_1_MINUTES].label, str);
875 g_object_notify( G_OBJECT(picker), "minutes" );
879 * hildon_time_picker_new:
880 * @parent: parent window
882 * #HildonTimePicker shows time picker dialog. The close button is placed
883 * in the dialog's action area and time picker is placed in dialogs vbox.
884 * The actual time picker consists of two #GtkLabel fields - one for hours
885 * and one for minutes - and an AM/PM button. A colon (:) is placed
886 * between hour and minute fields.
888 * Returns: pointer to a new #HildonTimePicker widget.
890 GtkWidget *hildon_time_picker_new( GtkWindow *parent )
892 GtkWidget *widget = g_object_new( HILDON_TYPE_TIME_PICKER,
893 "minutes", 360, NULL );
896 gtk_window_set_transient_for( GTK_WINDOW(widget), parent );
898 return GTK_WIDGET(widget);
902 * hildon_time_picker_set_time:
903 * @picker: the #HildonTimePicker widget
907 * Sets the time of the #HildonTimePicker widget.
909 void hildon_time_picker_set_time( HildonTimePicker *picker,
910 guint hours, guint minutes )
912 g_return_if_fail( HILDON_IS_TIME_PICKER(picker) );
913 hildon_time_picker_change_time( picker, hours * MINS_IN_1H + minutes );
917 * hildon_time_picker_get_time:
918 * @picker: the #HildonTimePicker widget
922 * Gets the time of the #HildonTimePicker widget.
924 void hildon_time_picker_get_time( HildonTimePicker *picker,
925 guint *hours, guint *minutes )
928 g_return_if_fail( HILDON_IS_TIME_PICKER(picker) );
930 current = picker->priv->minutes;
931 *hours = current / MINS_IN_1H;
932 *minutes = current % MINS_IN_1H;