+2009-04-28 Alejandro Pinheiro <apinheiro@igalia.com>
+
+ * src/hildon-time-selector.h:
+ Added HildonTimeSelectorFormatPolicy
+ * src/hildon-time-selector.c:
+ Added PROP_TIME_FORMAT_POLICY
+ (_check_ampm_format): renamed to check_automatic_ampm_format
+ (update_format_policy), (update_format_dependant_columns): new functions
+ (hildon_time_selector_class_init)
+ (hildon_time_selector_contructor)
+ (hildon_time_selector_init)
+ (hildon_time_selector_get_property)
+ (hildon_time_selector_set_property)
+ (hildon_time_selector_get_time)
+ (hildon_time_selector_set_time)
+ * src/hildon-touch-selector.h: new file
+ * src/hildon-touch-selector.c
+ (hildon_touch_selector_emit_changed)
+ (hildon_touch_selector_block_changed)
+ (hildon_touch_selector_unblock_changed)
+ Added functions to allow to block the emission of the "changed" signal
+ * src/hildon-picker-dialog.c
+ (hildon_picker_dialog_show): call the parent show before the custom code
+ * examples/hildon-time-button-example.c
+ Modified, so now you can configure the time format using the new property
+
+ Added a new property "time-format-policy" that allow to choose the time
+ format: AM/PM, 24H or AUTOMATIC. AUTOMATIC is the default one. In this
+ case it uses gconf in order to check if the time selector must use
+ AM/PM or 24H.
+
+ Fixes: NB#111606 (HildonTimeSelector should expose API to set/unset am/pm
+ mode)
+
2009-04-28 Alberto Garcia <agarcia@igalia.com>
* src/hildon-note.c (hildon_note_init):
hildon_button_get_value (HILDON_BUTTON (button)));
}
+static void
+on_change_policy_clicked (GtkButton *button,
+ gpointer data)
+{
+ static HildonTimeSelectorFormatPolicy policy = HILDON_TIME_SELECTOR_FORMAT_POLICY_AUTOMATIC;
+ HildonPickerButton *time_button = NULL;
+ HildonTouchSelector *selector = NULL;
+
+ policy = (policy + 1)%3;
+
+ switch (policy)
+ {
+ case HILDON_TIME_SELECTOR_FORMAT_POLICY_AMPM:
+ hildon_button_set_value (HILDON_BUTTON (button),
+ "AMPM");
+ break;
+ case HILDON_TIME_SELECTOR_FORMAT_POLICY_24H:
+ hildon_button_set_value (HILDON_BUTTON (button),
+ "24H");
+ break;
+ case HILDON_TIME_SELECTOR_FORMAT_POLICY_AUTOMATIC:
+ hildon_button_set_value (HILDON_BUTTON (button),
+ "Automatic");
+ break;
+ }
+
+ time_button = HILDON_PICKER_BUTTON (data);
+ selector = hildon_picker_button_get_selector (time_button);
+
+ g_object_set (G_OBJECT (selector),
+ "time-format-policy", policy, NULL);
+}
+
int
main (int argc, char **argv)
{
HildonProgram *program = NULL;
GtkWidget *window = NULL;
GtkWidget *button;
+ GtkWidget *hbox;
+ GtkWidget *button2;
hildon_gtk_init (&argc, &argv);
g_signal_connect (G_OBJECT (button), "value-changed",
G_CALLBACK (on_picker_value_changed), NULL);
- gtk_container_add (GTK_CONTAINER (window), button);
+ button2 = hildon_button_new_with_text (HILDON_SIZE_AUTO_WIDTH |
+ HILDON_SIZE_AUTO_HEIGHT,
+ HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
+ "Change Policy", "Automatic");
+
+ g_signal_connect (G_OBJECT (button2), "clicked",
+ G_CALLBACK (on_change_policy_clicked), button);
+
+ hbox = gtk_hbox_new (FALSE, 10);
+
+ gtk_container_add (GTK_CONTAINER (hbox), button);
+ gtk_container_add (GTK_CONTAINER (hbox), button2);
+ gtk_container_add (GTK_CONTAINER (window), hbox);
- g_signal_connect (G_OBJECT (window), "delete-event",
+ g_signal_connect (G_OBJECT (window), "delete-event",
G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_show_all (window);
hildon-wizard-dialog-private.h \
hildon-calendar-private.h \
hildon-app-menu-private.h \
- hildon-bread-crumb-widget.h
+ hildon-bread-crumb-widget.h \
+ hildon-touch-selector-private.h
# Don't build the library until we have built the header that it needs:
$(OBJECTS) $(libhildon_$(API_VERSION_MAJOR)_la_OBJECTS): hildon-enum-types.h hildon-marshalers.c hildon-marshalers.h
HildonPickerDialog *dialog = HILDON_PICKER_DIALOG (widget);
HildonTouchSelector *selector;
+ GTK_WIDGET_CLASS (hildon_picker_dialog_parent_class)->show (widget);
+
if (dialog->priv->center_on_show) {
selector = hildon_picker_dialog_get_selector (dialog);
hildon_touch_selector_center_on_selected (selector);
_save_current_selection (dialog);
prepare_action_area (dialog);
- GTK_WIDGET_CLASS (hildon_picker_dialog_parent_class)->show (widget);
}
static void
#include <locale.h>
#include <gconf/gconf-client.h>
+#include "hildon-enum-types.h"
#include "hildon-time-selector.h"
+#include "hildon-touch-selector-private.h"
#define HILDON_TIME_SELECTOR_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_TIME_SELECTOR, HildonTimeSelectorPrivate))
enum
{
PROP_0,
- PROP_MINUTES_STEP
+ PROP_MINUTES_STEP,
+ PROP_TIME_FORMAT_POLICY
};
struct _HildonTimeSelectorPrivate
GtkTreeModel *ampm_model;
guint minutes_step;
+ HildonTimeSelectorFormatPolicy format_policy;
gboolean ampm_format; /* if using am/pm format or 24 h one */
gboolean pm; /* if we are on pm (only useful if ampm_format == TRUE) */
static void _get_real_time (gint * hours, gint * minutes);
static void _manage_ampm_selection_cb (HildonTouchSelector * selector,
gint num_column, gpointer data);
-static void _check_ampm_format (HildonTimeSelector * selector);
static void _set_pm (HildonTimeSelector * selector, gboolean pm);
static gchar *_custom_print_func (HildonTouchSelector * selector,
gpointer user_data);
static void
+check_automatic_ampm_format (HildonTimeSelector * selector);
+
+static void
+update_format_policy (HildonTimeSelector *selector,
+ HildonTimeSelectorFormatPolicy new_policy);
+static void
+update_format_dependant_columns (HildonTimeSelector *selector,
+ guint hours,
+ guint minutes);
+
+static void
hildon_time_selector_class_init (HildonTimeSelectorClass * class)
{
GObjectClass *gobject_class;
1, 30, 1,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+ /**
+ * HildonTimeSelector:time-format-policy:
+ *
+ * The visual policy of the time format
+ *
+ * Since: 2.2
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_TIME_FORMAT_POLICY,
+ g_param_spec_enum ("time_format_policy",
+ "time format policy",
+ "Visual policy of the time format",
+ HILDON_TYPE_TIME_SELECTOR_FORMAT_POLICY,
+ HILDON_TIME_SELECTOR_FORMAT_POLICY_AUTOMATIC,
+ G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
+
/* GtkWidget */
/* GtkContainer */
g_type_class_add_private (object_class, sizeof (HildonTimeSelectorPrivate));
}
+/* FIXME: the constructor was required because as we need the initial values
+ of the properties passed on g_object_new. But, probably use the method
+ constructed could be easier */
static GObject*
hildon_time_selector_constructor (GType type,
guint n_construct_properties,
hildon_touch_selector_set_print_func (HILDON_TOUCH_SELECTOR (selector),
_custom_print_func);
+ /* By default we use the automatic ampm format */
+ selector->priv->pm = TRUE;
+ check_automatic_ampm_format (selector);
+
_get_real_time (&selector->priv->creation_hours,
&selector->priv->creation_minutes);
-
- _check_ampm_format (selector);
-
}
static void
case PROP_MINUTES_STEP:
g_value_set_uint (value, priv->minutes_step);
break;
-
+ case PROP_TIME_FORMAT_POLICY:
+ g_value_set_enum (value, priv->format_policy);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
case PROP_MINUTES_STEP:
priv->minutes_step = g_value_get_uint (value);
break;
-
+ case PROP_TIME_FORMAT_POLICY:
+ update_format_policy (HILDON_TIME_SELECTOR (object),
+ g_value_get_enum (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
static void
hildon_time_selector_finalize (GObject * object)
{
- /* FIXME: FILL ME !! */
+ /* Note: we don't require to free the models. We don't manage it using own
+ references, so will be freed on the hildon-touch-selector finalize code.
+ See the implementation notes related to that on the touch selector
+ code. */
(*G_OBJECT_CLASS (hildon_time_selector_parent_class)->finalize) (object);
}
}
static void
-_check_ampm_format (HildonTimeSelector * selector)
+check_automatic_ampm_format (HildonTimeSelector * selector)
{
GConfClient *client = NULL;
gboolean value = TRUE;
}
selector->priv->ampm_format = !value;
- selector->priv->pm = TRUE;
}
static void
selector->priv->pm = pm;
- gtk_tree_model_iter_nth_child (selector->priv->ampm_model, &iter, NULL, pm);
+ if (selector->priv->ampm_model != NULL) {
+ gtk_tree_model_iter_nth_child (selector->priv->ampm_model, &iter, NULL, pm);
- hildon_touch_selector_select_iter (HILDON_TOUCH_SELECTOR (selector),
- COLUMN_AMPM, &iter, FALSE);
+ hildon_touch_selector_select_iter (HILDON_TOUCH_SELECTOR (selector),
+ COLUMN_AMPM, &iter, FALSE);
+ }
}
+static void
+update_format_policy (HildonTimeSelector *selector,
+ HildonTimeSelectorFormatPolicy new_policy)
+{
+ gboolean prev_ampm_format = FALSE;
+ guint hours;
+ guint minutes;
+ gint num_columns = -1;
+
+ num_columns = hildon_touch_selector_get_num_columns (HILDON_TOUCH_SELECTOR (selector));
+ prev_ampm_format = selector->priv->ampm_format;
+
+ if (new_policy != selector->priv->format_policy) {
+ selector->priv->format_policy = new_policy;
+
+ /* We get the hour previous all the changes, to avoid problems with the
+ changing widget structure */
+ if (num_columns >= 2) {/* we are on the object construction */
+ hildon_time_selector_get_time (selector, &hours, &minutes);
+ }
+
+ switch (new_policy)
+ {
+ case HILDON_TIME_SELECTOR_FORMAT_POLICY_AMPM:
+ selector->priv->ampm_format = TRUE;
+ break;
+ case HILDON_TIME_SELECTOR_FORMAT_POLICY_24H:
+ selector->priv->ampm_format = FALSE;
+ break;
+ case HILDON_TIME_SELECTOR_FORMAT_POLICY_AUTOMATIC:
+ check_automatic_ampm_format (selector);
+ break;
+ }
+ }
+
+ if (prev_ampm_format != selector->priv->ampm_format) {
+ update_format_dependant_columns (selector, hours, minutes);
+ }
+}
+
+static void
+update_format_dependant_columns (HildonTimeSelector *selector,
+ guint hours,
+ guint minutes)
+{
+ gint num_columns = -1;
+
+ num_columns = hildon_touch_selector_get_num_columns (HILDON_TOUCH_SELECTOR (selector));
+ if (num_columns < 2) {/* we are on the object construction */
+ return;
+ }
+
+ /* To avoid an extra and wrong VALUE_CHANGED signal on the model update */
+ hildon_touch_selector_block_changed (HILDON_TOUCH_SELECTOR(selector));
+
+ selector->priv->hours_model = _create_hours_model (selector);
+ hildon_touch_selector_set_model (HILDON_TOUCH_SELECTOR (selector),
+ 0,
+ selector->priv->hours_model);
+
+ /* We need to set NOW the correct hour on the hours column, because the number of
+ columns will be updated too, so a signal COLUMNS_CHANGED will be emitted. Some
+ other widget could have connected to this signal and ask for the hour, so this
+ emission could have a wrong hour. We could use a custom func to only modify the
+ hours selection, but hildon_time_selector_time manage yet all the ampm issues
+ to select the correct one */
+ hildon_time_selector_set_time (selector, hours, minutes);
+
+ /* if we are at this function, we are sure that a change on the number of columns
+ will happen, so check the column number is not required */
+ if (selector->priv->ampm_format) {
+ selector->priv->ampm_model = _create_ampm_model (selector);
+
+ hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
+ selector->priv->ampm_model, TRUE);
+
+ g_signal_connect (G_OBJECT (selector),
+ "changed", G_CALLBACK (_manage_ampm_selection_cb),
+ NULL);
+ } else {
+ selector->priv->ampm_model = NULL;
+ hildon_touch_selector_remove_column (HILDON_TOUCH_SELECTOR (selector), 2);
+ }
+
+ _set_pm (selector, hours >= 12);
+
+ hildon_touch_selector_unblock_changed (HILDON_TOUCH_SELECTOR (selector));
+}
/* ------------------------------ PUBLIC METHODS ---------------------------- */
/**
GtkTreeIter iter;
gint hours_item = 0;
+ g_return_val_if_fail (HILDON_IS_TIME_SELECTOR (selector), FALSE);
g_return_val_if_fail (hours <= 23, FALSE);
g_return_val_if_fail (minutes <= 59, FALSE);
- if (selector->priv->ampm_format) {
- _set_pm (selector, hours >= 12);
+ _set_pm (selector, hours >= 12);
+ if (selector->priv->ampm_format) {
hours_item = hours - selector->priv->pm * 12;
} else {
hours_item = hours;
{
GtkTreeIter iter;
+ g_return_if_fail (HILDON_IS_TIME_SELECTOR (selector));
+
if (hours != NULL) {
- hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
- COLUMN_HOURS, &iter);
- gtk_tree_model_get (selector->priv->hours_model,
- &iter, COLUMN_INT, hours, -1);
+ if (hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
+ COLUMN_HOURS, &iter)) {
+
+ gtk_tree_model_get (selector->priv->hours_model,
+ &iter, COLUMN_INT, hours, -1);
+ }
if (selector->priv->ampm_format) {
*hours %= 12;
*hours += selector->priv->pm * 12;
}
if (minutes != NULL) {
- hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
- COLUMN_MINUTES, &iter);
- gtk_tree_model_get (selector->priv->minutes_model,
- &iter, COLUMN_INT, minutes, -1);
+ if (hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
+ COLUMN_MINUTES, &iter)) {
+ gtk_tree_model_get (selector->priv->minutes_model,
+ &iter, COLUMN_INT, minutes, -1);
+ }
}
}
};
+/**
+ * HildonTimeSelectorFormatPolicy:
+ * @HILDON_TIME_SELECTOR_FORMAT_POLICY_AMPM: The time selector will use a AMPM time format
+ * @HILDON_TIME_SELECTOR_FORMAT_POLICY_24H: The time selector will use a 24H time format
+ * @HILDON_TIME_SELECTOR_FORMAT_POLICY_AUTOMATIC: The time selector will use AMPM or 24H depending
+ * on the current environment
+ *
+ * Describes the time format used at #HildonTimeSelector
+ **/
+typedef enum {
+ HILDON_TIME_SELECTOR_FORMAT_POLICY_AMPM,
+ HILDON_TIME_SELECTOR_FORMAT_POLICY_24H,
+ HILDON_TIME_SELECTOR_FORMAT_POLICY_AUTOMATIC
+} HildonTimeSelectorFormatPolicy;
+
/* construction */
GType
hildon_time_selector_get_type (void) G_GNUC_CONST;
--- /dev/null
+/*
+ * This file is a part of hildon
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ *
+ * Contact: Rodrigo Novo <rodrigo.novo@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version. or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __HILDON_TOUCH_SELECTOR_PRIVATE_H__
+#define __HILDON_TOUCH_SELECTOR_PRIVATE_H__
+
+
+G_BEGIN_DECLS
+
+void G_GNUC_INTERNAL
+hildon_touch_selector_block_changed (HildonTouchSelector *selector);
+
+void G_GNUC_INTERNAL
+hildon_touch_selector_unblock_changed (HildonTouchSelector *selector);
+
+G_END_DECLS
+
+#endif
#include "hildon-pannable-area.h"
#include "hildon-touch-selector.h"
+#include "hildon-touch-selector-private.h"
#define HILDON_TOUCH_SELECTOR_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_TOUCH_SELECTOR, HildonTouchSelectorPrivate))
GtkWidget *hbox; /* the container for the selector's columns */
gboolean initial_scroll; /* whether initial fancy scrolling to selection */
+ gboolean changed_blocked;
+
HildonTouchSelectorPrintFunc print_func;
gpointer print_user_data;
GDestroyNotify print_destroy_func;
static gboolean
_hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector);
+static void
+hildon_touch_selector_emit_value_changed (HildonTouchSelector *selector,
+ gint column);
+
/* GtkCellLayout implementation (HildonTouchSelectorColumn)*/
static void hildon_touch_selector_column_cell_layout_init (GtkCellLayoutIface *iface);
selector->priv->initial_scroll = TRUE;
selector->priv->hbox = gtk_hbox_new (FALSE, 0);
+ selector->priv->changed_blocked = FALSE;
+
gtk_box_pack_end (GTK_BOX (selector), selector->priv->hbox,
TRUE, TRUE, 0);
gtk_widget_show (selector->priv->hbox);
}
/* ------------------------------ PRIVATE METHODS ---------------------------- */
+void
+hildon_touch_selector_block_changed (HildonTouchSelector *selector)
+{
+ selector->priv->changed_blocked = TRUE;
+}
+
+void
+hildon_touch_selector_unblock_changed (HildonTouchSelector *selector)
+{
+ selector->priv->changed_blocked = FALSE;
+}
+
+static void
+hildon_touch_selector_emit_value_changed (HildonTouchSelector *selector,
+ gint column)
+{
+ if (!selector->priv->changed_blocked) {
+ g_signal_emit (selector, hildon_touch_selector_signals[CHANGED], 0, column);
+ }
+}
+
/**
* default_print_func:
* @selector: a #HildonTouchSelector
num_column = g_slist_index (selector->priv->columns, column);
- g_signal_emit (selector, hildon_touch_selector_signals[CHANGED], 0, num_column);
+ hildon_touch_selector_emit_value_changed (selector, num_column);
}
g_signal_emit (selector, hildon_touch_selector_signals[COLUMNS_CHANGED], 0);
if (emit_changed) {
colnum = g_slist_length (selector->priv->columns);
- g_signal_emit (selector, hildon_touch_selector_signals[CHANGED], 0, colnum);
+ hildon_touch_selector_emit_value_changed (selector, colnum);
}
return new_column;
gtk_tree_selection_unselect_all (selection);
gtk_tree_selection_select_iter (selection, &iter);
- g_signal_emit (selector, hildon_touch_selector_signals[CHANGED], 0, column);
+ /* the column changed was the first one */
+ hildon_touch_selector_emit_value_changed (selector, 0);
}
}
if (index != -1)
gtk_tree_selection_select_path (selection, path);
- g_signal_emit (selector, hildon_touch_selector_signals[CHANGED], 0, column);
+ hildon_touch_selector_emit_value_changed (selector, column);
gtk_tree_path_free (path);
}
hildon_touch_selector_scroll_to (current_column, tv, path);
}
- g_signal_emit (selector, hildon_touch_selector_signals[CHANGED], 0, column);
+ hildon_touch_selector_emit_value_changed (selector, column);
gtk_tree_path_free (path);
}
selection = gtk_tree_view_get_selection (current_column->priv->tree_view);
gtk_tree_selection_unselect_iter (selection, iter);
- g_signal_emit (selector, hildon_touch_selector_signals[CHANGED], 0, column);
+ hildon_touch_selector_emit_value_changed (selector, column);
}
/**
selection = gtk_tree_view_get_selection (current_column->priv->tree_view);
gtk_tree_selection_unselect_all (selection);
- g_signal_emit (selector, hildon_touch_selector_signals[CHANGED], 0, column);
+ hildon_touch_selector_emit_value_changed (selector, column);
}
/**