2 * This file is a part of hildon
4 * Copyright (C) 2005, 2008 Nokia Corporation.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * SECTION:hildon-touch-selector
23 * @short_description: A selector widget with several columns.
25 * #HildonTouchSelector is a selector widget, that allows users to
26 * select items from one to many predefined lists. It is very similar
27 * to #GtkComboBox, but with several individual pannable
28 * columns. #HildonTouchSelector does not need to be placed in a
29 * #HildonPannableArea (in fact, doing so will prevent panning).
31 * Normally, you would use #HildonTouchSelector together with a
32 * #HildonPickerDialog activated from a button. For the most common
33 * cases, you should use #HildonPickerButton.
35 * The contents of each #HildonTouchSelector column are stored in a
36 * #GtkTreeModel. To add a new column to a #HildonTouchSelector, use
37 * hildon_touch_selector_append_column(). If you want to add a
38 * text-only column, without special attributes, use
39 * hildon_touch_selector_append_text_column().
41 * It is highly recommended that you use only one column
42 * #HildonTouchSelector<!-- -->s.
43 * If you only need a text only, one column selector, you can create it with
44 * hildon_touch_selector_new_text() and populate with
45 * hildon_touch_selector_append_text(), hildon_touch_selector_prepend_text(),
46 * and hildon_touch_selector_insert_text().
48 * If you need a selector widget that also accepts user inputs, you
49 * can use #HildonTouchSelectorEntry.
51 * The current selection has a string representation. In the most common cases,
52 * each column model will contain a text column. You can configure
53 * which column in particular using the #HildonTouchSelectorColumn property
54 * #HildonTouchSelectorColumn:text-column
56 * You can get this string representation using
57 * hildon_touch_selector_get_current_text().
58 * You can configure how the selection is printed with
59 * hildon_touch_selector_set_print_func(), that sets the current hildon touch
60 * selector print function. The widget has a default print function, that
61 * uses the #HildonTouchSelectorColumn:text-column property on each
62 * #HildonTouchSelectorColumn to compose the final representation.
64 * If you create the selector using hildon_touch_selector_new_text() you
65 * don't need to take care of this property, as the model is created internally.
66 * If you create the selector using hildon_touch_selector_new(), you
67 * need to specify properly the property for your custom model in order to get a
68 * non-empty string representation, or define your custom print function.
71 * <title>Creating a HildonTouchSelector</title>
74 * selection_changed (HildonTouchSelector * selector,
75 * gpointer *user_data)
77 * gchar *current_selection = NULL;
79 * current_selection = hildon_touch_selector_get_current_text (selector);
80 * g_debug ("Current selection : %s", current_selection);
84 * create_customized_selector ()
86 * GtkWidget *selector = NULL;
87 * GSList *icon_list = NULL;
88 * GtkListStore *store_icons = NULL;
89 * GSList *item = NULL;
90 * GtkCellRenderer *renderer = NULL;
91 * HildonTouchSelectorColumn *column = NULL;
93 * selector = hildon_touch_selector_new ();
95 * icon_list = gtk_stock_list_ids ();
97 * store_icons = gtk_list_store_new (1, G_TYPE_STRING);
98 * for (item = icon_list; item; item = g_slist_next (item)) {
100 * gchar *label = item->data;
102 * gtk_list_store_append (store_icons, &iter);
103 * gtk_list_store_set (store_icons, &iter, 0, label, -1);
106 * g_slist_free (icon_list);
108 * renderer = gtk_cell_renderer_pixbuf_new ();
109 * gtk_cell_renderer_set_fixed_size (renderer, -1, 100);
111 * column = hildon_touch_selector_append_column (HILDON_TOUCH_SELECTOR (selector),
112 * GTK_TREE_MODEL (store_icons),
113 * renderer, "stock-id", 0, NULL);
115 * hildon_touch_selector_column_set_text_column (column, 0);
117 * hildon_touch_selector_set_column_selection_mode (HILDON_TOUCH_SELECTOR (selector),
118 * HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE);
120 * g_signal_connect (G_OBJECT (selector), "changed",
121 * G_CALLBACK (selection_changed), NULL);
127 * create_simple_selector ()
129 * GtkWidget *selector = NULL;
132 * selector = hildon_touch_selector_new_text ();
133 * hildon_touch_selector_set_column_selection_mode (HILDON_TOUCH_SELECTOR (selector),
134 * HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE);
136 * g_signal_connect (G_OBJECT (selector), "changed",
137 * G_CALLBACK (selection_changed), NULL);
139 * for (i = 1; i <= 10 ; i++) {
140 * gchar *label = g_strdup_printf ("Item &percnt;d", i);
142 * hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector),
155 * SECTION:hildon-touch-selector-column
156 * @short_description: A visible column in a #HildonTouchSelector
157 * @see_also: #HildonTouchSelector
159 * A #HildonTouchSelectorColumn is a column in a
160 * #HildonTouchSelector. This class implements the #GtkCellLayout interface, allowing
161 * a flexible management of the cellrenderers in each #HildonTouchSelector column.
164 #undef HILDON_DISABLE_DEPRECATED
173 #include "hildon-gtk.h"
175 #include "hildon-pannable-area.h"
176 #include "hildon-touch-selector.h"
177 #include "hildon-touch-selector-private.h"
179 #define HILDON_TOUCH_SELECTOR_GET_PRIVATE(obj) \
180 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_TOUCH_SELECTOR, HildonTouchSelectorPrivate))
182 G_DEFINE_TYPE (HildonTouchSelector, hildon_touch_selector, GTK_TYPE_VBOX)
185 * IMPLEMENTATION NOTES:
186 * Struct to maintain the data of each column. The columns are the elements
187 * of the widget that belongs properly to the selection behaviour. Although
188 * internally the columns are arranged in a private #GtkHBox, as the selector
189 * itself is a #GtkVBox, you can add more widgets, like buttons etc., so
190 * you finally could have a widget with more elements that the columns, but
191 * this doesn't belongs to the selection logic
193 struct _HildonTouchSelectorColumnPrivate
195 HildonTouchSelector *parent; /* the selector that contains this column */
198 GtkTreeView *tree_view;
199 gulong realize_handler;
200 GtkTreePath *initial_path;
202 GtkWidget *panarea; /* the pannable widget */
203 GtkTreeRowReference *last_activated;
206 struct _HildonTouchSelectorPrivate
208 GSList *columns; /* the selection columns */
209 GtkWidget *hbox; /* the container for the selector's columns */
210 gboolean initial_scroll; /* whether initial fancy scrolling to selection */
212 gboolean changed_blocked;
214 HildonTouchSelectorPrintFunc print_func;
215 gpointer print_user_data;
216 GDestroyNotify print_destroy_func;
218 HildonUIMode hildon_ui_mode;
223 PROP_HAS_MULTIPLE_SELECTION = 1,
235 static gint hildon_touch_selector_signals[LAST_SIGNAL] = { 0 };
238 hildon_touch_selector_dispose (GObject * object);
241 hildon_touch_selector_get_property (GObject * object,
246 hildon_touch_selector_set_property (GObject *object,
253 static void hildon_touch_selector_remove (GtkContainer * container,
255 /* private functions */
256 static void _row_tapped_cb (GtkTreeView * tree_view,
260 hildon_touch_selector_row_activated_cb (GtkTreeView *tree_view,
262 GtkTreeViewColumn *column,
265 static gchar *_default_print_func (HildonTouchSelector * selector,
268 static HildonTouchSelectorColumn *_create_new_column (HildonTouchSelector * selector,
269 GtkTreeModel * model,
270 gboolean *emit_changed,
271 GtkCellRenderer * renderer,
274 on_realize_cb (GtkWidget *widget,
277 on_row_changed (GtkTreeModel *model,
283 hildon_touch_selector_scroll_to (HildonTouchSelectorColumn *column,
287 _hildon_touch_selector_center_on_selected_items (HildonTouchSelector *selector,
288 HildonTouchSelectorColumn *column);
290 _hildon_touch_selector_set_model (HildonTouchSelector * selector,
292 GtkTreeModel * model);
294 _hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector);
297 hildon_touch_selector_emit_value_changed (HildonTouchSelector *selector,
300 /* GtkCellLayout implementation (HildonTouchSelectorColumn)*/
301 static void hildon_touch_selector_column_cell_layout_init (GtkCellLayoutIface *iface);
303 static void hildon_touch_selector_column_cell_layout_pack_start (GtkCellLayout *cell_layout,
304 GtkCellRenderer *cell,
306 static void hildon_touch_selector_column_cell_layout_pack_end (GtkCellLayout *cell_layout,
307 GtkCellRenderer *cell,
309 static void hildon_touch_selector_column_cell_layout_clear (GtkCellLayout *cell_layout);
310 static void hildon_touch_selector_column_cell_layout_add_attribute(GtkCellLayout *cell_layout,
311 GtkCellRenderer *cell,
312 const gchar *attribute,
314 static void hildon_touch_selector_column_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout,
315 GtkCellRenderer *cell,
316 GtkCellLayoutDataFunc func,
318 GDestroyNotify destroy);
319 static void hildon_touch_selector_column_cell_layout_clear_attributes (GtkCellLayout *cell_layout,
320 GtkCellRenderer *cell);
321 static void hildon_touch_selector_column_cell_layout_reorder (GtkCellLayout *cell_layout,
322 GtkCellRenderer *cell,
324 static GList *hildon_touch_selector_column_cell_layout_get_cells (GtkCellLayout *cell_layout);
327 hildon_touch_selector_check_ui_mode_coherence (HildonTouchSelector *selector);
330 hildon_touch_selector_class_init (HildonTouchSelectorClass * class)
332 GObjectClass *gobject_class;
333 GtkObjectClass *object_class;
334 GtkContainerClass *container_class;
336 gobject_class = G_OBJECT_CLASS (class);
337 object_class = GTK_OBJECT_CLASS (class);
338 container_class = GTK_CONTAINER_CLASS (class);
341 gobject_class->dispose = hildon_touch_selector_dispose;
342 gobject_class->get_property = hildon_touch_selector_get_property;
343 gobject_class->set_property = hildon_touch_selector_set_property;
348 container_class->remove = hildon_touch_selector_remove;
350 /* HildonTouchSelector */
351 class->changed = NULL;
352 class->set_model = _hildon_touch_selector_set_model;
354 class->has_multiple_selection = _hildon_touch_selector_has_multiple_selection;
358 * HildonTouchSelector::changed:
359 * @widget: the object which received the signal
360 * @column: the number of the column that has changed
362 * The "changed" signal is emitted when the active item on any column is changed.
363 * This can be due to the user selecting a different item from the list, or
364 * due to a call to hildon_touch_selector_select_iter() on one of the columns.
368 hildon_touch_selector_signals[CHANGED] =
369 g_signal_new ("changed",
370 G_OBJECT_CLASS_TYPE (class),
372 G_STRUCT_OFFSET (HildonTouchSelectorClass, changed),
374 g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
377 * HildonTouchSelector::columns-changed:
378 * @selector: the object which received the signal
380 * The "columns-changed" signal is emitted when the number
381 * of columns in the #HildonTouchSelector change.
385 hildon_touch_selector_signals[COLUMNS_CHANGED] =
386 g_signal_new ("columns-changed",
387 G_OBJECT_CLASS_TYPE (class),
388 G_SIGNAL_RUN_LAST, 0,
390 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
394 g_object_class_install_property (gobject_class, PROP_HAS_MULTIPLE_SELECTION,
395 g_param_spec_boolean ("has-multiple-selection",
396 "has multiple selection",
397 "Whether the widget has multiple "
398 "selection (like multiple columns, "
399 "multiselection mode, or multiple "
400 "internal widgets) and therefore "
401 "it may need a confirmation button, "
406 g_object_class_install_property (G_OBJECT_CLASS (gobject_class),
408 g_param_spec_boolean ("initial-scroll",
410 "Whether to scroll to the"
411 "current selection when"
412 "the selector is first"
415 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
418 * HildonTouchSelector:hildon-ui-mode:
420 * Specifies which UI mode to use in the internal treeviews. A setting
421 * of %HILDON_UI_MODE_NORMAL will cause these tree view to disable selections
422 * and emit row-activated as soon as a row is pressed (unless it is pressed
423 * to drag the pannable area where the treeview is). You can use the
424 * method hildon_touch_selector_get_last_activated_row() to get it. When
425 * %HILDON_UI_MODE_EDIT is set, selections can be made according to the
426 * setting of the mode on GtkTreeSelection.
428 * Toggling this property will cause the tree view to select an
429 * appropriate selection mode if not already done.
433 g_object_class_install_property (gobject_class,
435 g_param_spec_enum ("hildon-ui-mode",
437 "The Hildon UI mode according "
438 "to which the touch selector "
443 /* style properties */
444 /* We need to ensure fremantle mode for the treeview in order to work
445 properly. This is not about the appearance, this is about behaviour */
446 gtk_rc_parse_string ("style \"fremantle-htst\" {\n"
447 " GtkWidget::hildon-mode = 1\n"
448 "} widget \"*.fremantle-htst\" style \"fremantle-htst\""
449 "widget_class \"*<HildonPannableArea>.GtkTreeView\" style :highest \"fremantle-htst\"");
451 g_type_class_add_private (object_class, sizeof (HildonTouchSelectorPrivate));
455 hildon_touch_selector_get_property (GObject * object,
457 GValue * value, GParamSpec * pspec)
459 HildonTouchSelectorPrivate *priv = HILDON_TOUCH_SELECTOR (object)->priv;
462 case PROP_HAS_MULTIPLE_SELECTION:
463 g_value_set_boolean (value,
464 hildon_touch_selector_has_multiple_selection (HILDON_TOUCH_SELECTOR (object)));
466 case PROP_INITIAL_SCROLL:
467 g_value_set_boolean (value, priv->initial_scroll);
469 case PROP_HILDON_UI_MODE:
470 g_value_set_enum (value, priv->hildon_ui_mode);
473 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
479 hildon_touch_selector_set_property (GObject *object, guint prop_id,
480 const GValue *value, GParamSpec *pspec)
482 HildonTouchSelectorPrivate *priv = HILDON_TOUCH_SELECTOR (object)->priv;
485 case PROP_INITIAL_SCROLL:
486 priv->initial_scroll = g_value_get_boolean (value);
488 case PROP_HILDON_UI_MODE:
489 hildon_touch_selector_set_hildon_ui_mode (HILDON_TOUCH_SELECTOR (object),
490 g_value_get_enum (value));
493 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
500 hildon_touch_selector_init (HildonTouchSelector * selector)
502 selector->priv = HILDON_TOUCH_SELECTOR_GET_PRIVATE (selector);
504 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (selector), GTK_NO_WINDOW);
505 gtk_widget_set_redraw_on_allocate (GTK_WIDGET (selector), FALSE);
507 selector->priv->columns = NULL;
509 selector->priv->print_func = NULL;
510 selector->priv->print_user_data = NULL;
511 selector->priv->print_destroy_func = NULL;
512 selector->priv->initial_scroll = TRUE;
513 selector->priv->hbox = gtk_hbox_new (FALSE, 0);
515 selector->priv->changed_blocked = FALSE;
517 selector->priv->hildon_ui_mode = HILDON_UI_MODE_EDIT;
519 gtk_box_pack_end (GTK_BOX (selector), selector->priv->hbox,
521 gtk_widget_show (selector->priv->hbox);
525 hildon_touch_selector_dispose (GObject * object)
527 GObjectClass *gobject_class;
529 hildon_touch_selector_set_print_func_full (HILDON_TOUCH_SELECTOR (object),
532 gobject_class = G_OBJECT_CLASS (hildon_touch_selector_parent_class);
534 if (gobject_class->dispose)
535 (* gobject_class->dispose) (object);
539 clean_column (HildonTouchSelectorColumn *col,
540 HildonTouchSelector *selector)
542 g_signal_handlers_disconnect_by_func (col->priv->model,
543 on_row_changed, selector);
545 if (col->priv->last_activated != NULL) {
546 gtk_tree_row_reference_free (col->priv->last_activated);
547 col->priv->last_activated = NULL;
552 * IMPLEMENTATION NOTES:
553 * Some people sent questions regarding the fact that the dispose/finalize functions
554 * doesn't clean the internal widgets that could lead to leak memory, so we will
555 * clarify this topic.
557 * This is not required as #HildonTouchSelector extends #GtkContainer. When the
558 * widget is freed, the #GtkContainer freeing memory functions are called. This
559 * process includes remove each widget individually, so all the widgets are
562 * In the same way, this widget redefines gtk_container->remove function, in
563 * order to free the column related information if it is required.
565 * Please take a look to hildon_touch_selector_remove for more information.
568 /*------------------------------ GtkContainer ------------------------------ */
571 * Required in order to free the column at the columns list
574 hildon_touch_selector_remove (GtkContainer * container, GtkWidget * widget)
576 HildonTouchSelector *selector = NULL;
578 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (container));
579 selector = HILDON_TOUCH_SELECTOR (container);
581 /* Remove the extra data related to the columns, if required. */
582 if (widget == selector->priv->hbox) {
583 g_slist_foreach (selector->priv->columns, (GFunc) clean_column, selector);
584 g_slist_foreach (selector->priv->columns, (GFunc) g_object_unref, NULL);
586 g_slist_free (selector->priv->columns);
588 selector->priv->columns = NULL;
590 g_debug ("Freeing a widget outside the columns logic");
593 /* Now remove the widget itself from the container */
594 GTK_CONTAINER_CLASS (hildon_touch_selector_parent_class)->remove (container, widget);
597 /* ------------------------------ PRIVATE METHODS ---------------------------- */
599 hildon_touch_selector_block_changed (HildonTouchSelector *selector)
601 selector->priv->changed_blocked = TRUE;
605 hildon_touch_selector_unblock_changed (HildonTouchSelector *selector)
607 selector->priv->changed_blocked = FALSE;
611 hildon_touch_selector_emit_value_changed (HildonTouchSelector *selector,
614 /* FIXME: it could be good to emit too the GtkTreePath of the element
615 selected, as now it is required to connect to the signal and then ask
616 for the element selected. We can't do this API change, in order to avoid
618 if (!selector->priv->changed_blocked) {
619 g_signal_emit (selector, hildon_touch_selector_signals[CHANGED], 0, column);
624 hildon_touch_selector_check_ui_mode_coherence (HildonTouchSelector *selector)
626 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
628 if (hildon_touch_selector_get_num_columns (selector) > 1) {
629 hildon_touch_selector_set_hildon_ui_mode (selector, HILDON_UI_MODE_EDIT);
634 * default_print_func:
635 * @selector: a #HildonTouchSelector
637 * Default print function
639 * Returns: a new string that represents the selected items
644 _default_print_func (HildonTouchSelector * selector, gpointer user_data)
646 gchar *result = NULL;
648 gint num_columns = 0;
650 GtkTreeModel *model = NULL;
651 gchar *current_string = NULL;
653 HildonTouchSelectorSelectionMode mode;
655 GtkTreePath *current_path = NULL;
656 GList *selected_rows = NULL;
657 gint initial_value = 0;
658 gint text_column = -1;
659 HildonTouchSelectorColumn *column = NULL;
661 num_columns = hildon_touch_selector_get_num_columns (selector);
663 mode = hildon_touch_selector_get_column_selection_mode (selector);
665 if ((mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE)
666 && (num_columns > 0)) {
667 /* In this case we get the first column first */
668 selected_rows = hildon_touch_selector_get_selected_rows (selector, 0);
669 model = hildon_touch_selector_get_model (selector, 0);
670 column = hildon_touch_selector_get_column (selector, 0);
671 text_column = hildon_touch_selector_column_get_text_column (column);
673 result = g_strdup_printf ("(");
675 for (item = selected_rows; item; item = g_list_next (item)) {
676 current_path = item->data;
677 gtk_tree_model_get_iter (model, &iter, current_path);
679 if (text_column != -1) {
680 gtk_tree_model_get (model, &iter, text_column, ¤t_string, -1);
683 if (i < g_list_length (selected_rows) - 1) {
684 aux = g_strconcat (result, current_string, ",", NULL);
688 aux = g_strconcat (result, current_string, NULL);
693 if (current_string) {
694 g_free (current_string);
695 current_string = NULL;
701 aux = g_strconcat (result, ")", NULL);
705 g_list_foreach (selected_rows, (GFunc) (gtk_tree_path_free), NULL);
706 g_list_free (selected_rows);
712 for (i = initial_value; i < num_columns; i++) {
713 model = hildon_touch_selector_get_model (selector, i);
714 column = hildon_touch_selector_get_column (selector, i);
715 text_column = hildon_touch_selector_column_get_text_column (column);
717 if (hildon_touch_selector_get_selected (selector, i, &iter)) {
718 if (text_column == -1 ) {
719 g_warning ("Trying to use the default print function in HildonTouchSelector, but "
720 "\"text-column\" property is not set for HildonTouchSelectorColumn %p.", column);
721 current_string = NULL;
723 gtk_tree_model_get (model, &iter, text_column, ¤t_string, -1);
727 result = current_string;
729 aux = g_strconcat (result, ":", current_string, NULL);
731 g_free (current_string);
732 current_string = NULL;
742 hildon_touch_selector_row_activated_cb (GtkTreeView *tree_view,
744 GtkTreeViewColumn *column,
747 HildonTouchSelectorColumn *selector_column = NULL;
748 GtkTreeModel *model = NULL;
750 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (user_data));
751 selector_column = HILDON_TOUCH_SELECTOR_COLUMN (user_data);
753 model = selector_column->priv->model;
755 if (selector_column->priv->last_activated != NULL) {
756 gtk_tree_row_reference_free (selector_column->priv->last_activated);
759 selector_column->priv->last_activated = gtk_tree_row_reference_new (model, path);
763 _row_tapped_cb (GtkTreeView * tree_view, GtkTreePath * path, gpointer user_data)
765 HildonTouchSelector *selector = NULL;
766 HildonTouchSelectorColumn *column = NULL;
767 gint num_column = -1;
769 column = HILDON_TOUCH_SELECTOR_COLUMN (user_data);
770 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (column->priv->parent));
772 selector = column->priv->parent;
774 num_column = g_slist_index (selector->priv->columns, column);
776 hildon_touch_selector_emit_value_changed (selector, num_column);
780 static HildonTouchSelectorColumn *
781 _create_new_column (HildonTouchSelector * selector,
782 GtkTreeModel * model,
783 gboolean *emit_changed,
784 GtkCellRenderer * renderer, va_list args)
786 HildonTouchSelectorColumn *new_column = NULL;
787 GtkTreeViewColumn *tree_column = NULL;
788 GtkTreeView *tv = NULL;
789 GtkWidget *panarea = NULL;
790 GtkTreeSelection *selection = NULL;
795 tree_column = gtk_tree_view_column_new ();
797 if (renderer != NULL) {
798 gtk_tree_view_column_pack_start (tree_column, renderer, TRUE);
800 attribute = va_arg (args, gchar *);
801 while (attribute != NULL) {
802 value = va_arg (args, gint);
803 gtk_tree_view_column_add_attribute (tree_column, renderer, attribute,
805 attribute = va_arg (args, gchar *);
810 tv = GTK_TREE_VIEW (hildon_gtk_tree_view_new (selector->priv->hildon_ui_mode));
812 tv = GTK_TREE_VIEW (gtk_tree_view_new ());
813 #endif /* MAEMO_GTK */
815 gtk_tree_view_set_enable_search (tv, FALSE);
816 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (tv), GTK_CAN_FOCUS);
818 gtk_tree_view_set_model (tv, model);
819 g_signal_connect (model, "row-changed",
820 G_CALLBACK (on_row_changed), selector);
821 gtk_tree_view_set_rules_hint (tv, TRUE);
823 gtk_tree_view_append_column (GTK_TREE_VIEW (tv), tree_column);
825 new_column = g_object_new (HILDON_TYPE_TOUCH_SELECTOR_COLUMN, NULL);
826 new_column->priv->parent = selector;
828 panarea = hildon_pannable_area_new ();
830 g_object_set (G_OBJECT (panarea),
831 "initial-hint", FALSE, NULL);
833 gtk_container_add (GTK_CONTAINER (panarea), GTK_WIDGET (tv));
835 new_column->priv->model = model;
836 new_column->priv->tree_view = tv;
837 new_column->priv->panarea = panarea;
838 new_column->priv->realize_handler = 0;
839 new_column->priv->initial_path = NULL;
841 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
842 gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
844 /* select the first item */
845 *emit_changed = FALSE;
846 if ((gtk_tree_model_get_iter_first (model, &iter))&&
847 (selector->priv->hildon_ui_mode == HILDON_UI_MODE_EDIT)) {
848 gtk_tree_selection_select_iter (selection, &iter);
849 *emit_changed = TRUE;
852 gtk_widget_grab_focus (GTK_WIDGET (tv));
854 /* connect to the hildon-row-tapped signal connection */
855 g_signal_connect (G_OBJECT (tv), "hildon-row-tapped",
856 G_CALLBACK (_row_tapped_cb), new_column);
858 g_signal_connect (G_OBJECT (tv), "row-activated",
859 G_CALLBACK (hildon_touch_selector_row_activated_cb), new_column);
865 /* ------------------------ HildonTouchSelectorColumn implementation ---------------------- */
866 G_DEFINE_TYPE_WITH_CODE (HildonTouchSelectorColumn, hildon_touch_selector_column, G_TYPE_OBJECT,
867 G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
868 hildon_touch_selector_column_cell_layout_init))
876 hildon_touch_selector_column_class_init (HildonTouchSelectorColumnClass *klass);
879 hildon_touch_selector_column_get_property (GObject *object, guint property_id,
880 GValue *value, GParamSpec *pspec);
883 hildon_touch_selector_column_set_property (GObject *object, guint property_id,
884 const GValue *value, GParamSpec *pspec);
888 hildon_touch_selector_column_class_init (HildonTouchSelectorColumnClass *klass)
890 GObjectClass *gobject_class = NULL;
892 gobject_class = G_OBJECT_CLASS (klass);
894 g_type_class_add_private (gobject_class, sizeof (HildonTouchSelectorColumnPrivate));
897 gobject_class->get_property = hildon_touch_selector_column_get_property;
898 gobject_class->set_property = hildon_touch_selector_column_set_property;
901 * HildonTouchSelectorColumn:text-column:
903 * A column in the data source model to get the strings from.
907 g_object_class_install_property (G_OBJECT_CLASS(klass),
909 g_param_spec_int ("text-column",
911 "A column in the data source model to get the strings from.",
919 hildon_touch_selector_column_init (HildonTouchSelectorColumn *column)
921 column->priv = G_TYPE_INSTANCE_GET_PRIVATE (column, HILDON_TYPE_TOUCH_SELECTOR_COLUMN,
922 HildonTouchSelectorColumnPrivate);
923 column->priv->text_column = -1;
924 column->priv->last_activated = NULL;
928 * hildon_touch_selector_column_set_text_column:
929 * @column: A #HildonTouchSelectorColumn
930 * @text_column: the index of a model column in the model for @column.
932 * Sets the model column to be displayed in @column. @text_column must point to a
933 * column in the model used with type %G_TYPE_STRING. Initially, this property
934 * is unset. You should set it before using the #HildonTouchSelector that uses
940 hildon_touch_selector_column_set_text_column (HildonTouchSelectorColumn *column,
943 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (column));
944 g_return_if_fail (text_column >= -1);
946 column->priv->text_column = text_column;
948 g_object_notify (G_OBJECT (column), "text-column");
952 * hildon_touch_selector_column_get_text_column:
953 * @column: a #HildonTouchSelectorColumn
955 * Gets the model column set as the text source for @column.
957 * Returns: the index of the text column for @column, or -1 if unset.
962 hildon_touch_selector_column_get_text_column (HildonTouchSelectorColumn *column)
964 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (column), -1);
966 return column->priv->text_column;
970 hildon_touch_selector_column_get_property (GObject *object, guint property_id,
971 GValue *value, GParamSpec *pspec)
973 switch (property_id) {
974 case PROP_TEXT_COLUMN:
975 g_value_set_int (value,
976 hildon_touch_selector_column_get_text_column (HILDON_TOUCH_SELECTOR_COLUMN (object)));
979 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
984 hildon_touch_selector_column_set_property (GObject *object, guint property_id,
985 const GValue *value, GParamSpec *pspec)
987 switch (property_id) {
988 case PROP_TEXT_COLUMN:
989 hildon_touch_selector_column_set_text_column (HILDON_TOUCH_SELECTOR_COLUMN (object),
990 g_value_get_int (value));
993 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
997 /* ------------------------ GtkCellLayout implementation -------------------- */
999 hildon_touch_selector_column_cell_layout_init (GtkCellLayoutIface *iface)
1001 iface->pack_start = hildon_touch_selector_column_cell_layout_pack_start;
1002 iface->pack_end = hildon_touch_selector_column_cell_layout_pack_end;
1003 iface->clear = hildon_touch_selector_column_cell_layout_clear;
1004 iface->add_attribute = hildon_touch_selector_column_cell_layout_add_attribute;
1005 iface->set_cell_data_func = hildon_touch_selector_column_cell_layout_set_cell_data_func;
1006 iface->clear_attributes = hildon_touch_selector_column_cell_layout_clear_attributes;
1007 iface->reorder = hildon_touch_selector_column_cell_layout_reorder;
1008 iface->get_cells = hildon_touch_selector_column_cell_layout_get_cells;
1012 hildon_touch_selector_column_cell_layout_pack_start (GtkCellLayout *cell_layout,
1013 GtkCellRenderer *cell,
1016 HildonTouchSelectorColumn *sel_column = NULL;
1017 GtkTreeViewColumn *view_column = NULL;
1019 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1020 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1022 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1024 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(view_column), cell, expand);
1029 hildon_touch_selector_column_cell_layout_pack_end (GtkCellLayout *cell_layout,
1030 GtkCellRenderer *cell,
1033 HildonTouchSelectorColumn *sel_column = NULL;
1034 GtkTreeViewColumn *view_column = NULL;
1036 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1037 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1039 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1041 gtk_cell_layout_pack_end (GTK_CELL_LAYOUT(view_column), cell, expand);
1045 hildon_touch_selector_column_cell_layout_clear (GtkCellLayout *cell_layout)
1047 HildonTouchSelectorColumn *sel_column = NULL;
1048 GtkTreeViewColumn *view_column = NULL;
1050 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1051 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1053 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1055 gtk_cell_layout_clear (GTK_CELL_LAYOUT(view_column));
1059 hildon_touch_selector_column_cell_layout_add_attribute (GtkCellLayout *cell_layout,
1060 GtkCellRenderer *cell,
1061 const gchar *attribute,
1064 HildonTouchSelectorColumn *sel_column = NULL;
1065 GtkTreeViewColumn *view_column = NULL;
1067 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1068 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1070 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1072 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(view_column), cell, attribute, column);
1077 hildon_touch_selector_column_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout,
1078 GtkCellRenderer *cell,
1079 GtkCellLayoutDataFunc func,
1081 GDestroyNotify destroy)
1083 HildonTouchSelectorColumn *sel_column = NULL;
1084 GtkTreeViewColumn *view_column = NULL;
1086 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1087 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1089 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1091 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT(view_column), cell, func,
1092 func_data, destroy);
1096 hildon_touch_selector_column_cell_layout_clear_attributes (GtkCellLayout *cell_layout,
1097 GtkCellRenderer *cell)
1099 HildonTouchSelectorColumn *sel_column = NULL;
1100 GtkTreeViewColumn *view_column = NULL;
1102 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1103 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1105 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1107 gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (view_column), cell);
1111 hildon_touch_selector_column_cell_layout_reorder (GtkCellLayout *cell_layout,
1112 GtkCellRenderer *cell,
1115 HildonTouchSelectorColumn *sel_column = NULL;
1116 GtkTreeViewColumn *view_column = NULL;
1118 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1119 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1121 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1123 gtk_cell_layout_reorder (GTK_CELL_LAYOUT(view_column), cell, position);
1127 hildon_touch_selector_column_cell_layout_get_cells (GtkCellLayout *cell_layout)
1129 HildonTouchSelectorColumn *sel_column = NULL;
1130 GtkTreeViewColumn *view_column = NULL;
1132 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout), NULL);
1133 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1135 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1137 return gtk_cell_layout_get_cells (GTK_CELL_LAYOUT(view_column));
1140 /* ------------------------------ PUBLIC METHODS ---------------------------- */
1143 * hildon_touch_selector_new:
1145 * Creates a new empty #HildonTouchSelector.
1147 * Returns: a new #HildonTouchSelector.
1152 hildon_touch_selector_new (void)
1154 return g_object_new (HILDON_TYPE_TOUCH_SELECTOR, NULL);
1158 * hildon_touch_selector_new_text:
1160 * Creates a #HildonTouchSelector with a single text column that
1161 * can be populated conveniently through hildon_touch_selector_append_text(),
1162 * hildon_touch_selector_prepend_text(), hildon_touch_selector_insert_text().
1164 * Returns: A new #HildonTouchSelector
1169 hildon_touch_selector_new_text (void)
1171 GtkWidget *selector;
1172 GtkListStore *store;
1173 HildonTouchSelectorColumn *column = NULL;
1175 selector = hildon_touch_selector_new ();
1176 store = gtk_list_store_new (1, G_TYPE_STRING);
1178 column = hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
1179 GTK_TREE_MODEL (store), TRUE);
1181 hildon_touch_selector_column_set_text_column (column, 0);
1187 * hildon_touch_selector_append_text:
1188 * @selector: A #HildonTouchSelector.
1189 * @text: a non %NULL text string.
1191 * Appends a new entry in a #HildonTouchSelector created with
1192 * hildon_touch_selector_new_text().
1197 hildon_touch_selector_append_text (HildonTouchSelector * selector,
1201 GtkTreeModel *model;
1203 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1204 g_return_if_fail (text != NULL);
1206 model = hildon_touch_selector_get_model (HILDON_TOUCH_SELECTOR (selector), 0);
1208 g_return_if_fail (GTK_IS_LIST_STORE (model));
1210 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
1211 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, text, -1);
1215 * hildon_touch_selector_prepend_text:
1216 * @selector: A #HildonTouchSelector.
1217 * @text: a non %NULL text string.
1219 * Prepends a new entry in a #HildonTouchSelector created with
1220 * hildon_touch_selector_new_text().
1225 hildon_touch_selector_prepend_text (HildonTouchSelector * selector,
1229 GtkTreeModel *model;
1231 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1232 g_return_if_fail (text != NULL);
1234 model = hildon_touch_selector_get_model (HILDON_TOUCH_SELECTOR (selector), 0);
1236 g_return_if_fail (GTK_IS_LIST_STORE (model));
1238 gtk_list_store_prepend (GTK_LIST_STORE (model), &iter);
1239 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, text, -1);
1243 * hildon_touch_selector_insert_text:
1244 * @selector: a #HildonTouchSelector.
1245 * @position: the position to insert @text.
1246 * @text: A non %NULL text string.
1248 * Inserts a new entry in a particular position of a
1249 * #HildonTouchSelector created with hildon_touch_selector_new_text().
1254 hildon_touch_selector_insert_text (HildonTouchSelector * selector,
1255 gint position, const gchar * text)
1258 GtkTreeModel *model;
1260 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1261 g_return_if_fail (text != NULL);
1262 g_return_if_fail (position >= 0);
1264 model = hildon_touch_selector_get_model (HILDON_TOUCH_SELECTOR (selector), 0);
1266 g_return_if_fail (GTK_IS_LIST_STORE (model));
1268 gtk_list_store_insert (GTK_LIST_STORE (model), &iter, position);
1269 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, text, -1);
1273 * hildon_touch_selector_append_column
1274 * @selector: a #HildonTouchSelector
1275 * @model: the #GtkTreeModel with the data of the column
1276 * @cell_renderer: The #GtkCellRenderer where to draw each row contents.
1277 * @Varargs: a %NULL-terminated pair of attributes and column numbers.
1279 * This functions adds a new column to the widget, whose data will
1280 * be obtained from the model. Only widgets added this way should used on
1281 * the selection logic, the print function, the #HildonTouchSelector::changed
1282 * signal, etc. Internally, a #GtkTreeView will be added to the widget, using
1283 * @model as the data source.
1285 * You can optionally pass a #GtkCellRenderer in @cell_renderer,
1286 * together with a %NULL-terminated list of pairs property/value, in
1287 * the same way you would use gtk_tree_view_column_set_attributes().
1288 * This will pack @cell_renderer at the start of the column, expanded
1289 * by default. If you prefer not to add it this way, you can simply
1290 * pass %NULL to @cell_renderer and use the #GtkCellLayout interface
1291 * on the returned #HildonTouchSelectorColumn to set your
1292 * renderers. Please note that the returned #HildonTouchSelectorColumn
1293 * is owned by @selector, you shouldn't unref it after setting it
1296 * Initially, the returned #HildonTouchSelectorColumn will have its
1297 * #HildonTouchSelectorColumn:text-column property unset. You should set
1298 * it to a column in @model with type %G_TYPE_STRING. See
1299 * hildon_touch_selector_column_set_text_column().
1301 * This method could change the current #HildonTouchSelector:hildon-ui-mode.
1302 * %HILDON_UI_MODE_NORMAL is only allowed with one column, so if the selector
1303 * is in this mode, and a additional column is added,
1304 * #HildonTouchSelector:hildon-ui-mode will change to %HILDON_UI_MODE_EDIT.
1306 * Returns: the new column added added, %NULL otherwise.
1311 HildonTouchSelectorColumn*
1312 hildon_touch_selector_append_column (HildonTouchSelector * selector,
1313 GtkTreeModel * model,
1314 GtkCellRenderer * cell_renderer, ...)
1317 HildonTouchSelectorColumn *new_column = NULL;
1318 gboolean emit_changed = FALSE;
1321 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1322 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
1324 if (model != NULL) {
1326 va_start (args, cell_renderer);
1327 new_column = _create_new_column (selector, model, &emit_changed, cell_renderer, args);
1330 selector->priv->columns = g_slist_append (selector->priv->columns,
1332 gtk_box_pack_start (GTK_BOX (selector->priv->hbox),
1333 new_column->priv->panarea,
1336 gtk_widget_show_all (new_column->priv->panarea);
1338 if (selector->priv->initial_scroll) {
1339 _hildon_touch_selector_center_on_selected_items (selector, new_column);
1346 g_signal_emit (selector, hildon_touch_selector_signals[COLUMNS_CHANGED], 0);
1348 colnum = g_slist_length (selector->priv->columns);
1349 hildon_touch_selector_emit_value_changed (selector, colnum);
1352 hildon_touch_selector_check_ui_mode_coherence (selector);
1358 * hildon_touch_selector_append_text_column
1359 * @selector: a #HildonTouchSelector
1360 * @model: a #GtkTreeModel with data for the column
1361 * @center: whether to center the text on the column
1363 * Equivalent to hildon_touch_selector_append_column(), but using a
1364 * default text cell renderer. This is the most common use case of the
1367 * Returns: the new column added, NULL otherwise.
1371 HildonTouchSelectorColumn*
1372 hildon_touch_selector_append_text_column (HildonTouchSelector * selector,
1373 GtkTreeModel * model, gboolean center)
1375 gfloat xalign = center ? 0.5 : 0.0;
1376 GtkCellRenderer *renderer;
1378 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1379 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
1381 renderer = gtk_cell_renderer_text_new ();
1383 g_object_set (renderer,
1388 return hildon_touch_selector_append_column (selector, model, renderer,
1393 * hildon_touch_selector_remove_column:
1394 * @selector: a #HildonTouchSelector
1395 * @column: the position of the column to be removed
1397 * Removes a column from @selector.
1399 * Returns: %TRUE if the column was removed, %FALSE otherwise
1404 hildon_touch_selector_remove_column (HildonTouchSelector * selector, gint column)
1406 HildonTouchSelectorColumn *current_column = NULL;
1407 HildonTouchSelectorPrivate *priv;
1409 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
1410 g_return_val_if_fail (column <
1411 hildon_touch_selector_get_num_columns (selector), FALSE);
1413 priv = HILDON_TOUCH_SELECTOR_GET_PRIVATE (selector);
1414 current_column = g_slist_nth_data (priv->columns, column);
1416 gtk_container_remove (GTK_CONTAINER (priv->hbox), current_column->priv->panarea);
1417 priv->columns = g_slist_remove (priv->columns, current_column);
1418 g_object_unref (current_column);
1420 g_signal_emit (selector, hildon_touch_selector_signals[COLUMNS_CHANGED], 0);
1426 * hildon_touch_selector_set_column_attributes:
1427 * @selector: a #HildonTouchSelector
1428 * @num_column: the number of the column whose attributes we're setting
1429 * @cell_renderer: the #GtkCellRendere we're setting the attributes of
1430 * @Varargs: A %NULL-terminated list of attributes.
1432 * Sets the attributes for the given column. The attributes must be given
1433 * in attribute/column pairs, just like in gtk_tree_view_column_set_attributes().
1434 * All existing attributes are removed and replaced with the new ones.
1436 * Deprecated: #HildonTouchSelectorColumn implements #GtkCellLayout, use this
1437 * interface instead. See
1438 * hildon_touch_selector_get_column().
1443 hildon_touch_selector_set_column_attributes (HildonTouchSelector * selector,
1445 GtkCellRenderer * cell_renderer,
1449 GtkTreeViewColumn *tree_column = NULL;
1450 HildonTouchSelectorColumn *current_column = NULL;
1451 gchar *attribute = NULL;
1454 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1455 g_return_if_fail (num_column <
1456 hildon_touch_selector_get_num_columns (selector));
1458 current_column = g_slist_nth_data (selector->priv->columns, num_column);
1460 tree_column = gtk_tree_view_get_column (current_column->priv->tree_view, 0);
1461 gtk_tree_view_remove_column (current_column->priv->tree_view, tree_column);
1463 tree_column = gtk_tree_view_column_new ();
1464 gtk_tree_view_column_pack_start (tree_column, cell_renderer, TRUE);
1466 va_start (args, cell_renderer);
1467 attribute = va_arg (args, gchar *);
1469 gtk_tree_view_column_clear_attributes (tree_column, cell_renderer);
1471 while (attribute != NULL) {
1472 value = va_arg (args, gint);
1473 gtk_tree_view_column_add_attribute (tree_column, cell_renderer,
1475 attribute = va_arg (args, gchar *);
1480 gtk_tree_view_append_column (current_column->priv->tree_view, tree_column);
1484 * hildon_touch_selector_get_num_columns:
1485 * @selector: a #HildonTouchSelector
1487 * Gets the number of columns in the #HildonTouchSelector.
1489 * Returns: the number of columns in @selector.
1494 hildon_touch_selector_get_num_columns (HildonTouchSelector * selector)
1496 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), -1);
1498 return g_slist_length (selector->priv->columns);
1502 * hildon_touch_selector_get_column_selection_mode:
1503 * @selector: a #HildonTouchSelector
1505 * Gets the selection mode of @selector.
1507 * Returns: one of #HildonTouchSelectorSelectionMode
1511 HildonTouchSelectorSelectionMode
1512 hildon_touch_selector_get_column_selection_mode (HildonTouchSelector * selector)
1514 HildonTouchSelectorSelectionMode result =
1515 HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE;
1516 GtkSelectionMode treeview_mode = GTK_SELECTION_BROWSE;
1517 HildonTouchSelectorColumn *column = NULL;
1518 GtkTreeSelection *selection = NULL;
1520 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), result);
1521 g_return_val_if_fail (hildon_touch_selector_get_num_columns (selector) > 0,
1524 column = HILDON_TOUCH_SELECTOR_COLUMN (selector->priv->columns->data);
1526 selection = gtk_tree_view_get_selection (column->priv->tree_view);
1527 treeview_mode = gtk_tree_selection_get_mode (selection);
1530 if (treeview_mode == GTK_SELECTION_MULTIPLE) {
1531 result = HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE;
1533 result = HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE;
1540 * hildon_touch_selector_set_column_selection_mode:
1541 * @selector: a #HildonTouchSelector
1542 * @mode: the #HildonTouchSelectorMode for @selector
1544 * Sets the selection mode for @selector. See #HildonTouchSelectorSelectionMode.
1546 * The new @mode will be set, but take into into account that the
1547 * #HildonTouchSelectorSelectionMode is ignored if the @selector
1548 * #HildonTouchSelector:hildon-ui-mode property is set to %HILDON_UI_MODE_NORMAL
1553 hildon_touch_selector_set_column_selection_mode (HildonTouchSelector * selector,
1554 HildonTouchSelectorSelectionMode mode)
1556 GtkTreeView *tv = NULL;
1557 HildonTouchSelectorColumn *column = NULL;
1558 GtkTreeSelection *selection = NULL;
1559 GtkSelectionMode treeview_mode = GTK_SELECTION_MULTIPLE;
1561 HildonTouchSelectorSelectionMode current_mode;
1563 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1564 g_return_if_fail (hildon_touch_selector_get_num_columns (selector) > 0);
1566 current_mode = hildon_touch_selector_get_column_selection_mode (selector);
1568 if (current_mode == mode) {
1572 column = HILDON_TOUCH_SELECTOR_COLUMN ((g_slist_nth (selector->priv->columns, 0))->data);
1573 tv = column->priv->tree_view;
1577 case HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE:
1578 treeview_mode = GTK_SELECTION_BROWSE;
1580 case HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE:
1581 treeview_mode = GTK_SELECTION_MULTIPLE;
1585 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
1586 gtk_tree_selection_set_mode (selection, treeview_mode);
1588 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
1589 gtk_tree_model_get_iter_first (column->priv->model, &iter);
1590 gtk_tree_selection_unselect_all (selection);
1591 gtk_tree_selection_select_iter (selection, &iter);
1593 /* the column changed was the first one */
1594 hildon_touch_selector_emit_value_changed (selector, 0);
1600 * hildon_touch_selector_set_print_func:
1601 * @selector: a #HildonTouchSelector
1602 * @func: a #HildonTouchSelectorPrintFunc function
1604 * Sets the function to be used by hildon_touch_selector_get_current_text().
1605 * See hildon_touch_selector_set_print_func_full().
1610 hildon_touch_selector_set_print_func (HildonTouchSelector * selector,
1611 HildonTouchSelectorPrintFunc func)
1613 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1615 hildon_touch_selector_set_print_func_full (selector, func, NULL, NULL);
1619 * hildon_touch_selector_set_print_func_full:
1620 * @selector: a #HildonTouchSelector
1621 * @func: a #HildonTouchSelectorPrintFunc function
1622 * @user_data: a pointer to user data or %NULL
1623 * @destroy_func: a callback for freeing the user data or %NULL
1625 * Sets the function to be used by hildon_touch_selector_get_current_text()
1626 * to produce a text representation of the currently selected items in @selector.
1627 * The default function will return a concatenation of comma separated items
1628 * selected in each column in @selector. Use this to override this method if you
1629 * need a particular representation for your application.
1634 hildon_touch_selector_set_print_func_full (HildonTouchSelector *selector,
1635 HildonTouchSelectorPrintFunc func,
1637 GDestroyNotify destroy_func)
1639 gpointer old_user_data;
1640 GDestroyNotify old_destroy_func;
1642 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1644 old_user_data = selector->priv->print_user_data;
1645 old_destroy_func = selector->priv->print_destroy_func;
1647 selector->priv->print_func = func;
1648 selector->priv->print_user_data = user_data;
1649 selector->priv->print_destroy_func = destroy_func;
1651 if (old_destroy_func && old_user_data != user_data)
1652 (*old_destroy_func) (old_user_data);
1656 * hildon_touch_selector_get_print_func:
1657 * @selector: a #HildonTouchSelector
1659 * Gets the #HildonTouchSelectorPrintFunc currently used. See
1660 * hildon_touch_selector_set_print_func().
1662 * Returns: a #HildonTouchSelectorPrintFunc or %NULL if the default
1663 * one is currently used.
1665 HildonTouchSelectorPrintFunc
1666 hildon_touch_selector_get_print_func (HildonTouchSelector * selector)
1668 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1670 return selector->priv->print_func;
1674 * hildon_touch_selector_set_active:
1675 * @selector: a #HildonTouchSelector
1676 * @column: column number
1677 * @index: the index of the item to select, or -1 to have no active item
1679 * Sets the active item of the #HildonTouchSelector to @index. The
1680 * column number is taken from @column.
1682 * @selector must be in %HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE
1687 hildon_touch_selector_set_active (HildonTouchSelector *selector,
1691 GtkTreeSelection *selection = NULL;
1692 HildonTouchSelectorColumn *current_column = NULL;
1693 HildonTouchSelectorSelectionMode mode;
1696 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1697 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
1698 mode = hildon_touch_selector_get_column_selection_mode (selector);
1699 g_return_if_fail (mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE);
1701 current_column = g_slist_nth_data (selector->priv->columns, column);
1703 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (current_column->priv->tree_view));
1704 path = gtk_tree_path_new_from_indices (index, -1);
1705 gtk_tree_selection_unselect_all (selection);
1707 gtk_tree_selection_select_path (selection, path);
1709 hildon_touch_selector_emit_value_changed (selector, column);
1711 gtk_tree_path_free (path);
1715 * hildon_touch_selector_get_active:
1716 * @selector: a #HildonTouchSelector
1717 * @column: column number
1719 * Returns the index of the currently active item in column number
1720 * @column, or -1 if there's no active item.
1722 * @selector must be in %HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE
1724 * Returns: an integer which is the index of the currently active
1725 * item, or -1 if there's no active item.
1730 hildon_touch_selector_get_active (HildonTouchSelector *selector,
1733 GtkTreeSelection *selection = NULL;
1734 HildonTouchSelectorColumn *current_column = NULL;
1735 HildonTouchSelectorSelectionMode mode;
1736 GtkTreeModel *model;
1741 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), -1);
1742 g_return_val_if_fail (column < hildon_touch_selector_get_num_columns (selector), -1);
1743 mode = hildon_touch_selector_get_column_selection_mode (selector);
1744 g_return_val_if_fail (mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE, -1);
1746 current_column = g_slist_nth_data (selector->priv->columns, column);
1748 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (current_column->priv->tree_view));
1749 g_return_val_if_fail (gtk_tree_selection_get_selected (selection, NULL, &iter), -1);
1751 model = gtk_tree_view_get_model (GTK_TREE_VIEW (current_column->priv->tree_view));
1752 path = gtk_tree_model_get_path (model, &iter);
1753 index = (gtk_tree_path_get_indices (path))[0];
1755 gtk_tree_path_free (path);
1761 * hildon_touch_selector_get_selected:
1762 * @selector: a #HildonTouchSelector
1763 * @column: the column number we want to get the element
1764 * @iter: #GtkTreeIter currently selected
1766 * Sets @iter to the currently selected node on the nth-column, if selection is
1767 * set to %HILDON_TOUCH_SELECTOR_SINGLE or %HILDON_TOUCH_SELECTOR_MULTIPLE with
1768 * a column different that the first one. @iter may be %NULL if you just want to
1769 * test if selection has any selected items.
1771 * This function will not work if selection is in
1772 * %HILDON_TOUCH_SELECTOR_MULTIPLE mode and the column is the first one.
1774 * See gtk_tree_selection_get_selected() for more information.
1776 * Returns: %TRUE if @iter was correctly set, %FALSE otherwise
1781 hildon_touch_selector_get_selected (HildonTouchSelector * selector,
1782 gint column, GtkTreeIter * iter)
1784 GtkTreeSelection *selection = NULL;
1785 HildonTouchSelectorColumn *current_column = NULL;
1786 HildonTouchSelectorSelectionMode mode;
1788 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
1789 g_return_val_if_fail (column < hildon_touch_selector_get_num_columns (selector),
1791 mode = hildon_touch_selector_get_column_selection_mode (selector);
1792 g_return_val_if_fail
1793 ((mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE) ||
1794 ((mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE)&&(column>0)),
1797 current_column = g_slist_nth_data (selector->priv->columns, column);
1800 gtk_tree_view_get_selection (GTK_TREE_VIEW (current_column->priv->tree_view));
1802 return gtk_tree_selection_get_selected (selection, NULL, iter);
1806 * hildon_touch_selector_select_iter
1807 * @selector: a #HildonTouchSelector
1808 * @column: the column to selects
1809 * @iter: the #GtkTreeIter to be selected
1810 * @scroll_to: whether to smoothly scroll to the item
1812 * Sets the currently selected item in the column @column to the one pointed by @iter,
1813 * optionally smoothly scrolling to it.
1818 hildon_touch_selector_select_iter (HildonTouchSelector * selector,
1819 gint column, GtkTreeIter * iter,
1823 GtkTreeModel *model;
1824 HildonTouchSelectorColumn *current_column = NULL;
1825 GtkTreeView *tv = NULL;
1826 GtkTreeSelection *selection = NULL;
1828 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1829 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
1831 current_column = g_slist_nth_data (selector->priv->columns, column);
1833 tv = current_column->priv->tree_view;
1834 selection = gtk_tree_view_get_selection (tv);
1835 model = gtk_tree_view_get_model (tv);
1836 path = gtk_tree_model_get_path (model, iter);
1838 gtk_tree_selection_select_iter (selection, iter);
1841 hildon_touch_selector_scroll_to (current_column, tv, path);
1844 hildon_touch_selector_emit_value_changed (selector, column);
1846 gtk_tree_path_free (path);
1850 * hildon_touch_selector_unselect_iter
1851 * @selector: a #HildonTouchSelector
1852 * @column: the column to unselects from
1853 * @iter: the #GtkTreeIter to be unselected
1855 * Unselect the item pointed by @iter in the column @column
1860 void hildon_touch_selector_unselect_iter (HildonTouchSelector * selector,
1864 HildonTouchSelectorColumn *current_column = NULL;
1865 GtkTreeSelection *selection = NULL;
1867 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1868 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
1870 current_column = g_slist_nth_data (selector->priv->columns, column);
1871 selection = gtk_tree_view_get_selection (current_column->priv->tree_view);
1872 gtk_tree_selection_unselect_iter (selection, iter);
1874 hildon_touch_selector_emit_value_changed (selector, column);
1878 * hildon_touch_selector_unselect_all:
1879 * @selector: a #HildonTouchSelector
1880 * @column: the position of the column to get the selected rows from
1882 * Unselects all the selected items in the column @column.
1887 hildon_touch_selector_unselect_all (HildonTouchSelector * selector,
1890 HildonTouchSelectorColumn *current_column = NULL;
1891 GtkTreeSelection *selection = NULL;
1893 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1894 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
1896 current_column = g_slist_nth_data (selector->priv->columns, column);
1897 selection = gtk_tree_view_get_selection (current_column->priv->tree_view);
1898 gtk_tree_selection_unselect_all (selection);
1900 hildon_touch_selector_emit_value_changed (selector, column);
1904 * hildon_touch_selector_get_selected_rows:
1905 * @selector: a #HildonTouchSelector
1906 * @column: the position of the column to get the selected rows from
1908 * Creates a list of #GtkTreePath<!-- -->s of all selected rows in a column. Additionally,
1909 * if you to plan to modify the model after calling this function, you may
1910 * want to convert the returned list into a list of GtkTreeRowReferences. To do this,
1911 * you can use gtk_tree_row_reference_new().
1913 * See gtk_tree_selection_get_selected_rows() for more information.
1915 * Returns: A new #GList containing a #GtkTreePath for each selected row in the column @column.
1920 hildon_touch_selector_get_selected_rows (HildonTouchSelector * selector,
1923 GList *result = NULL;
1924 HildonTouchSelectorColumn *current_column = NULL;
1925 GtkTreeSelection *selection = NULL;
1927 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1928 g_return_val_if_fail (column < hildon_touch_selector_get_num_columns (selector),
1931 current_column = g_slist_nth_data (selector->priv->columns, column);
1932 selection = gtk_tree_view_get_selection (current_column->priv->tree_view);
1934 result = gtk_tree_selection_get_selected_rows (selection, NULL);
1940 * hildon_touch_selector_get_model:
1941 * @selector: a #HildonTouchSelector
1942 * @column: the position of the column in @selector
1944 * Gets the model of a column of @selector.
1946 * Returns: the #GtkTreeModel for the column @column of @selector.
1951 hildon_touch_selector_get_model (HildonTouchSelector * selector, gint column)
1953 HildonTouchSelectorColumn *current_column = NULL;
1955 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1956 g_return_val_if_fail (column < hildon_touch_selector_get_num_columns (selector),
1959 current_column = g_slist_nth_data (selector->priv->columns, column);
1961 return current_column->priv->model;
1965 on_row_changed (GtkTreeModel *model,
1970 HildonTouchSelector *selector;
1971 HildonTouchSelectorColumn *current_column;
1976 selector = HILDON_TOUCH_SELECTOR (userdata);
1978 for (col = selector->priv->columns; col != NULL; col = col->next) {
1979 current_column = HILDON_TOUCH_SELECTOR_COLUMN (col->data);
1980 if (current_column->priv->model == model &&
1981 gtk_tree_selection_path_is_selected (gtk_tree_view_get_selection (current_column->priv->tree_view),
1983 hildon_touch_selector_emit_value_changed (selector, column);
1990 _hildon_touch_selector_set_model (HildonTouchSelector * selector,
1991 gint column, GtkTreeModel * model)
1993 HildonTouchSelectorColumn *current_column = NULL;
1996 HILDON_TOUCH_SELECTOR_COLUMN (g_slist_nth_data (selector->priv->columns, column));
1998 if (current_column->priv->model) {
1999 g_signal_handlers_disconnect_by_func (current_column->priv->model,
2000 on_row_changed, selector);
2002 current_column->priv->model = model;
2003 gtk_tree_view_set_model (current_column->priv->tree_view,
2004 current_column->priv->model);
2005 g_signal_connect (model, "row-changed",
2006 G_CALLBACK (on_row_changed), selector);
2010 * hildon_touch_selector_set_model:
2011 * @selector: a #HildonTouchSelector
2012 * @column: the position of the column to set the model to
2013 * @model: a #GtkTreeModel
2015 * Sets the #GtkTreeModel for a particular column in @model.
2020 hildon_touch_selector_set_model (HildonTouchSelector * selector,
2021 gint column, GtkTreeModel * model)
2023 g_return_if_fail (HILDON_TOUCH_SELECTOR (selector));
2024 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
2026 HILDON_TOUCH_SELECTOR_GET_CLASS (selector)->set_model (selector, column, model);
2030 * hildon_touch_selector_get_current_text:
2031 * @selector: a #HildonTouchSelector
2033 * Returns a string representing the currently selected items for
2034 * each column of @selector. See hildon_touch_selector_set_print_func().
2036 * Returns: a newly allocated string.
2041 hildon_touch_selector_get_current_text (HildonTouchSelector * selector)
2043 gchar *result = NULL;
2044 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
2046 if (selector->priv->print_func) {
2047 result = (*selector->priv->print_func) (selector, selector->priv->print_user_data);
2049 result = _default_print_func (selector, NULL);
2056 search_nearest_element (HildonPannableArea *panarea,
2058 GList *selected_rows,
2059 GtkTreePath **nearest_path)
2061 GtkAdjustment *adj = NULL;
2062 gdouble target_value = 0;
2065 GtkTreePath *path = NULL;
2067 gdouble nearest_distance = -1;
2068 gdouble current_distance = -1;
2069 GtkTreePath *result_path = NULL;
2071 g_assert (nearest_path != NULL);
2073 if (selected_rows == NULL) {
2074 *nearest_path = NULL;
2078 adj = hildon_pannable_area_get_vadjustment (panarea);
2079 g_return_if_fail (adj != NULL);
2081 /* we add this in order to check the nearest to the center of
2083 target_value = gtk_adjustment_get_value (adj) + adj->page_size/2;
2085 path = result_path = selected_rows->data;
2086 gtk_tree_view_get_background_area (tv, path, NULL, &rect);
2087 gtk_tree_view_convert_bin_window_to_tree_coords (tv, 0, rect.y, NULL, &y);
2088 nearest_distance = abs (target_value - y);
2090 for (iter = selected_rows->next; iter; iter = g_list_next (iter)) {
2091 gtk_tree_view_get_background_area (tv, path, NULL, &rect);
2092 gtk_tree_view_convert_bin_window_to_tree_coords (tv, 0, rect.y, NULL, &y);
2093 current_distance = abs (target_value - y);
2094 if (current_distance < nearest_distance) {
2095 nearest_distance = current_distance;
2100 *nearest_path = result_path;
2104 on_realize_cb (GtkWidget *widget,
2107 HildonTouchSelectorColumn *column = NULL;
2111 column = HILDON_TOUCH_SELECTOR_COLUMN (data);
2113 if (column->priv->initial_path) {
2114 gtk_tree_view_get_background_area (GTK_TREE_VIEW (column->priv->tree_view),
2115 column->priv->initial_path, NULL, &rect);
2116 gtk_tree_view_convert_bin_window_to_tree_coords
2117 (GTK_TREE_VIEW (column->priv->tree_view),
2118 0, rect.y, NULL, &y);
2120 hildon_pannable_area_scroll_to (HILDON_PANNABLE_AREA (column->priv->panarea),
2123 gtk_tree_path_free (column->priv->initial_path);
2125 column->priv->initial_path = NULL;
2129 g_signal_handler_disconnect (column->priv->panarea,
2130 column->priv->realize_handler);
2136 hildon_touch_selector_scroll_to (HildonTouchSelectorColumn *column,
2140 if (GTK_WIDGET_REALIZED (column->priv->panarea)) {
2144 gtk_tree_view_get_background_area (tv,
2146 gtk_tree_view_convert_bin_window_to_tree_coords (tv,
2147 0, rect.y, NULL, &y);
2149 hildon_pannable_area_scroll_to (HILDON_PANNABLE_AREA
2150 (column->priv->panarea), -1, y);
2152 if (column->priv->realize_handler != 0) {
2154 if (column->priv->initial_path) {
2155 gtk_tree_path_free (column->priv->initial_path);
2156 column->priv->initial_path = NULL;
2159 g_signal_handler_disconnect (column->priv->panarea,
2160 column->priv->realize_handler);
2161 column->priv->realize_handler = 0;
2164 column->priv->initial_path = gtk_tree_path_copy (path);
2165 column->priv->realize_handler =
2166 g_signal_connect_after (G_OBJECT (column->priv->panarea), "realize",
2167 G_CALLBACK (on_realize_cb),
2174 * Center on the selected item of a concrete column
2176 * Returns: TRUE if was able to do that
2180 _hildon_touch_selector_center_on_selected_items (HildonTouchSelector *selector,
2181 HildonTouchSelectorColumn *column)
2183 GtkTreePath *path = NULL;
2184 GList *selected_rows = NULL;
2185 gint num_column = -1;
2187 num_column = g_slist_index (selector->priv->columns, column);
2189 selected_rows = hildon_touch_selector_get_selected_rows (selector, num_column);
2190 if (selected_rows) {
2191 search_nearest_element (HILDON_PANNABLE_AREA (column->priv->panarea),
2192 GTK_TREE_VIEW (column->priv->tree_view),
2197 hildon_touch_selector_scroll_to (column,
2198 GTK_TREE_VIEW (column->priv->tree_view),
2204 g_list_foreach (selected_rows, (GFunc) (gtk_tree_path_free), NULL);
2205 g_list_free (selected_rows);
2212 _hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector)
2214 HildonTouchSelectorSelectionMode mode;
2217 n_columns = hildon_touch_selector_get_num_columns (selector);
2218 mode = hildon_touch_selector_get_column_selection_mode (selector);
2220 return ((n_columns > 1) || (mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE));
2224 * hildon_touch_selector_has_multiple_selection:
2225 * @selector: A #HildonTouchSelector
2227 * Determines whether @selector is complex enough to actually require an
2228 * extra selection step than only picking an item. This is normally %TRUE
2229 * if @selector has multiple columns, multiple selection, or when it is a
2230 * more complex widget, like #HildonTouchSelectorEntry.
2232 * This information is useful for widgets containing a #HildonTouchSelector,
2233 * like #HildonPickerDialog, that could need a "Done" button, in case that
2234 * its internal #HildonTouchSelector has multiple columns, for instance.
2236 * Returns: %TRUE if @selector requires multiple selection steps.
2241 hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector)
2243 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
2245 return HILDON_TOUCH_SELECTOR_GET_CLASS (selector)->has_multiple_selection (selector);
2250 * hildon_touch_selector_get_column:
2251 * @selector: A #HildonTouchSelector
2252 * @column: a column number
2254 * Use this method to retrieve a #HildonTouchSelectorColumn. Then, you can use
2255 * the #GtkCellLayout interface to set up the layout of the column.
2257 * Returns: the @column<!-- -->-th #HildonTouchSelectorColumn in @selector
2261 HildonTouchSelectorColumn *
2262 hildon_touch_selector_get_column (HildonTouchSelector * selector,
2265 gint num_columns = -1;
2267 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
2268 num_columns = hildon_touch_selector_get_num_columns (selector);
2269 g_return_val_if_fail (column < num_columns && column >= 0, NULL);
2271 return g_slist_nth_data (selector->priv->columns, column);
2276 * hildon_touch_selector_center_on_selected:
2277 * @selector: a #HildonTouchSelector
2279 * Ensures all the columns in a #HildonTouchSelector show a selected
2280 * item. If one of the columns is in
2281 * %HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE mode, that column
2282 * will be scrolled to ensure the selected item that is closest to the
2283 * currently visible area is shown.
2285 * The #HildonTouchSelector:initial-scroll property configure the widget
2286 * in order to use this function at the first show.
2288 * Take into account that the element is not centered until the widget is
2289 * realized. If the widget is not realized when the function is called, it
2290 * will be postponed. If you call this functions several times before the
2291 * widgets is realized, only the last one will be used.
2293 * This behaviour includes any call to hildon_touch_selector_center_on_index(),
2294 * so take care calling this functions, or with the
2295 * #HildonTouchSelector:initial-scroll property in order to get centered on the
2301 hildon_touch_selector_center_on_selected (HildonTouchSelector *selector)
2303 GSList *iter = NULL;
2305 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
2307 for (iter = selector->priv->columns; iter; iter = g_slist_next (iter)) {
2308 _hildon_touch_selector_center_on_selected_items (selector,
2309 HILDON_TOUCH_SELECTOR_COLUMN (iter->data));
2314 * hildon_touch_selector_optimal_size_request
2315 * @selector: a #HildonTouchSelector
2316 * @requisition: a #GtkRequisition
2318 * Gets the optimal size request of the touch selector. This function is mostly
2319 * intended for dialog implementations that include a #HildonTouchSelector and
2320 * want to optimize the screen real state, for example, when you want a dialog
2321 * to show as much of the selector, avoiding any extra empty space below the
2324 * See #HildonPickerDialog implementation for an example.
2326 * This function is oriented to be used in the size_request of a dialog or window,
2327 * if you are not sure do not use it.
2329 * There is a precondition to this function: Since this function does not
2330 * call the "size_request" method, it can only be used when you know that
2331 * gtk_widget_size_request() has been called since the last time a resize was
2337 hildon_touch_selector_optimal_size_request (HildonTouchSelector *selector,
2338 GtkRequisition *requisition)
2340 GSList *iter = NULL;
2342 gint base_height = 0;
2344 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
2346 iter = selector->priv->columns;
2348 /* Default optimal values are the current ones */
2349 gtk_widget_get_child_requisition (GTK_WIDGET (selector),
2353 height = requisition->height;
2355 /* we use the normal requisition as base, as the touch selector can has
2356 extra widgets, not only the columns (ie: HildonTouchSelectorEntry) */
2357 base_height = requisition->height;
2360 /* Compute optimal height for the columns */
2362 HildonTouchSelectorColumn *column;
2364 GtkRequisition child_requisition = {0};
2366 column = HILDON_TOUCH_SELECTOR_COLUMN (iter->data);
2367 child = GTK_WIDGET (column->priv->tree_view);
2369 gtk_widget_get_child_requisition (child, &child_requisition);
2371 height = MAX (height, child_requisition.height);
2373 iter = g_slist_next (iter);
2376 requisition->height = base_height + height;
2382 * hildon_touch_selector_get_hildon_ui_mode
2383 * @selector: a #HildonTouchSelector
2385 * Gets the current hildon-ui-mode, see #HildonUIMode for more information
2387 * Returns: the current hildon-ui-mode
2392 hildon_touch_selector_get_hildon_ui_mode (HildonTouchSelector *selector)
2394 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), HILDON_UI_MODE_EDIT);
2396 return selector->priv->hildon_ui_mode;
2400 * hildon_touch_selector_set_hildon_ui_mode
2401 * @selector: a #HildonTouchSelector
2402 * @mode: a #HildonUIMode
2404 * Sets the value of the property #HildonTouchSelector:hildon-ui-mode to be @mode,
2405 * see #HildonUIMode for more information
2407 * Note that the %HILDON_UI_MODE_NORMAL can be only used when the selector has
2408 * one column, use the return value to check if the change was effective.
2410 * Returns: %TRUE if #HildonTouchSelector:hildon-ui-mode was changed
2416 hildon_touch_selector_set_hildon_ui_mode (HildonTouchSelector *selector,
2420 GSList *iter = NULL;
2421 HildonTouchSelectorColumn *column = NULL;
2422 GtkTreeView *tree_view = NULL;
2424 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
2425 num = hildon_touch_selector_get_num_columns (selector);
2426 g_return_val_if_fail ((mode == HILDON_UI_MODE_EDIT) || (num == 1), FALSE);
2428 if (mode == selector->priv->hildon_ui_mode) {
2432 for (iter = selector->priv->columns; iter; iter = g_slist_next (iter)) {
2433 column = HILDON_TOUCH_SELECTOR_COLUMN (iter->data);
2434 tree_view = column->priv->tree_view;
2436 hildon_tree_view_set_hildon_ui_mode (tree_view, mode);
2438 /* looking at the code of hildon_tree_view_set_hildon_ui_mode, it seems
2439 that it call the unselect_all, but it is required anyway */
2440 if (mode == HILDON_UI_MODE_NORMAL) {
2441 GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
2443 gtk_tree_selection_unselect_all (selection);
2447 selector->priv->hildon_ui_mode = mode;
2453 * hildon_touch_selector_get_last_activated_row
2454 * @selector: a #HildonTouchSelector
2455 * @column: column number
2457 * Gets a #GtkTreePath of the last row activated in a column (the last row that
2458 * emitted a #GtkTreeView::row-activated signal). This is mainly useful if the
2459 * @selector #HildonTouchSelector:hildon-ui-mode in set to %HILDON_UI_MODE_NORMAL,
2460 * as using this state there is no real selection, so a method like
2461 * hildon_touch_selector_get_selected_rows() will return always a empty
2464 * Anyway, this method works as well on %HILDON_UI_MODE_EDIT, but in this case
2465 * is better, and more useful, to get the current selection.
2467 * Returns: a newly allocated #GtkTreePath pointing to the last activated row
2468 * NULL if no row were activated.
2473 hildon_touch_selector_get_last_activated_row (HildonTouchSelector *selector,
2476 HildonTouchSelectorColumn *selector_column = NULL;
2478 /* this method with check selector and that the column number is correct*/
2479 selector_column = hildon_touch_selector_get_column (selector, column);
2481 if (selector_column == NULL) {
2485 if (selector_column->priv->last_activated != NULL) {
2486 return gtk_tree_row_reference_get_path (selector_column->priv->last_activated);
2494 * hildon_touch_selector_center_on_index:
2495 * @selector: a #HildonTouchSelector
2496 * @column: column number
2497 * @index: the index of the item to center on
2499 * Ensures that the column number @column shows the element @index
2501 * This is similar to hildon_touch_selector_center_on_selected() but with the
2502 * difference that allows to center on a column item not selected.
2504 * Take into account that the element is not centered until the widget is
2505 * realized. If the widget is not realized when the function is called, it will
2506 * be postponed. If you call this function several times before the widget is
2507 * realized, only the last one will be used.
2509 * This behaviour includes any call to hildon_touch_selector_center_on_selected().
2510 * Check this function for more tips.
2515 hildon_touch_selector_center_on_index (HildonTouchSelector *selector,
2519 HildonTouchSelectorColumn *current_column = NULL;
2520 GtkTreePath *path = NULL;
2522 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
2523 g_return_if_fail ((column >= 0) && (column < hildon_touch_selector_get_num_columns (selector)));
2524 g_return_if_fail (index >= 0);
2526 current_column = g_slist_nth_data (selector->priv->columns, column);
2528 path = gtk_tree_path_new_from_indices (index, -1);
2530 hildon_touch_selector_scroll_to (current_column,
2531 current_column->priv->tree_view,
2533 gtk_tree_path_free (path);