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. You can use the
423 * method hildon_touch_selector_get_last_activated_row() to get it. When
424 * %HILDON_UI_MODE_EDIT is set, selections can be made according to the
425 * setting of the mode on GtkTreeSelection.
427 * Toggling this property will cause the tree view to select an
428 * appropriate selection mode if not already done.
432 g_object_class_install_property (gobject_class,
434 g_param_spec_enum ("hildon-ui-mode",
436 "The Hildon UI mode according "
437 "to which the touch selector "
442 /* style properties */
443 /* We need to ensure fremantle mode for the treeview in order to work
444 properly. This is not about the appearance, this is about behaviour */
445 gtk_rc_parse_string ("style \"fremantle-htst\" {\n"
446 " GtkWidget::hildon-mode = 1\n"
447 "} widget \"*.fremantle-htst\" style \"fremantle-htst\""
448 "widget_class \"*<HildonPannableArea>.GtkTreeView\" style :highest \"fremantle-htst\"");
450 g_type_class_add_private (object_class, sizeof (HildonTouchSelectorPrivate));
454 hildon_touch_selector_get_property (GObject * object,
456 GValue * value, GParamSpec * pspec)
458 HildonTouchSelectorPrivate *priv = HILDON_TOUCH_SELECTOR (object)->priv;
461 case PROP_HAS_MULTIPLE_SELECTION:
462 g_value_set_boolean (value,
463 hildon_touch_selector_has_multiple_selection (HILDON_TOUCH_SELECTOR (object)));
465 case PROP_INITIAL_SCROLL:
466 g_value_set_boolean (value, priv->initial_scroll);
468 case PROP_HILDON_UI_MODE:
469 g_value_set_enum (value, priv->hildon_ui_mode);
472 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
478 hildon_touch_selector_set_property (GObject *object, guint prop_id,
479 const GValue *value, GParamSpec *pspec)
481 HildonTouchSelectorPrivate *priv = HILDON_TOUCH_SELECTOR (object)->priv;
484 case PROP_INITIAL_SCROLL:
485 priv->initial_scroll = g_value_get_boolean (value);
487 case PROP_HILDON_UI_MODE:
488 hildon_touch_selector_set_hildon_ui_mode (HILDON_TOUCH_SELECTOR (object),
489 g_value_get_enum (value));
492 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
499 hildon_touch_selector_init (HildonTouchSelector * selector)
501 selector->priv = HILDON_TOUCH_SELECTOR_GET_PRIVATE (selector);
503 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (selector), GTK_NO_WINDOW);
504 gtk_widget_set_redraw_on_allocate (GTK_WIDGET (selector), FALSE);
506 selector->priv->columns = NULL;
508 selector->priv->print_func = NULL;
509 selector->priv->print_user_data = NULL;
510 selector->priv->print_destroy_func = NULL;
511 selector->priv->initial_scroll = TRUE;
512 selector->priv->hbox = gtk_hbox_new (FALSE, 0);
514 selector->priv->changed_blocked = FALSE;
516 selector->priv->hildon_ui_mode = HILDON_UI_MODE_EDIT;
518 gtk_box_pack_end (GTK_BOX (selector), selector->priv->hbox,
520 gtk_widget_show (selector->priv->hbox);
524 hildon_touch_selector_dispose (GObject * object)
526 GObjectClass *gobject_class;
528 hildon_touch_selector_set_print_func_full (HILDON_TOUCH_SELECTOR (object),
531 gobject_class = G_OBJECT_CLASS (hildon_touch_selector_parent_class);
533 if (gobject_class->dispose)
534 (* gobject_class->dispose) (object);
538 clean_column (HildonTouchSelectorColumn *col,
539 HildonTouchSelector *selector)
541 g_signal_handlers_disconnect_by_func (col->priv->model,
542 on_row_changed, selector);
544 if (col->priv->last_activated != NULL) {
545 gtk_tree_row_reference_free (col->priv->last_activated);
546 col->priv->last_activated = NULL;
551 * IMPLEMENTATION NOTES:
552 * Some people sent questions regarding the fact that the dispose/finalize functions
553 * doesn't clean the internal widgets that could lead to leak memory, so we will
554 * clarify this topic.
556 * This is not required as #HildonTouchSelector extends #GtkContainer. When the
557 * widget is freed, the #GtkContainer freeing memory functions are called. This
558 * process includes remove each widget individually, so all the widgets are
561 * In the same way, this widget redefines gtk_container->remove function, in
562 * order to free the column related information if it is required.
564 * Please take a look to hildon_touch_selector_remove for more information.
567 /*------------------------------ GtkContainer ------------------------------ */
570 * Required in order to free the column at the columns list
573 hildon_touch_selector_remove (GtkContainer * container, GtkWidget * widget)
575 HildonTouchSelector *selector = NULL;
577 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (container));
578 selector = HILDON_TOUCH_SELECTOR (container);
580 /* Remove the extra data related to the columns, if required. */
581 if (widget == selector->priv->hbox) {
582 g_slist_foreach (selector->priv->columns, (GFunc) clean_column, selector);
583 g_slist_foreach (selector->priv->columns, (GFunc) g_object_unref, NULL);
585 g_slist_free (selector->priv->columns);
587 selector->priv->columns = NULL;
589 g_debug ("Freeing a widget outside the columns logic");
592 /* Now remove the widget itself from the container */
593 GTK_CONTAINER_CLASS (hildon_touch_selector_parent_class)->remove (container, widget);
596 /* ------------------------------ PRIVATE METHODS ---------------------------- */
598 hildon_touch_selector_block_changed (HildonTouchSelector *selector)
600 selector->priv->changed_blocked = TRUE;
604 hildon_touch_selector_unblock_changed (HildonTouchSelector *selector)
606 selector->priv->changed_blocked = FALSE;
610 hildon_touch_selector_emit_value_changed (HildonTouchSelector *selector,
613 /* FIXME: it could be good to emit too the GtkTreePath of the element
614 selected, as now it is required to connect to the signal and then ask
615 for the element selected. We can't do this API change, in order to avoid
617 if (!selector->priv->changed_blocked) {
618 g_signal_emit (selector, hildon_touch_selector_signals[CHANGED], 0, column);
623 hildon_touch_selector_check_ui_mode_coherence (HildonTouchSelector *selector)
625 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
627 if (hildon_touch_selector_get_num_columns (selector) > 1) {
628 hildon_touch_selector_set_hildon_ui_mode (selector, HILDON_UI_MODE_EDIT);
633 * default_print_func:
634 * @selector: a #HildonTouchSelector
636 * Default print function
638 * Returns: a new string that represents the selected items
643 _default_print_func (HildonTouchSelector * selector, gpointer user_data)
645 gchar *result = NULL;
647 gint num_columns = 0;
649 GtkTreeModel *model = NULL;
650 gchar *current_string = NULL;
652 HildonTouchSelectorSelectionMode mode;
654 GtkTreePath *current_path = NULL;
655 GList *selected_rows = NULL;
656 gint initial_value = 0;
657 gint text_column = -1;
658 HildonTouchSelectorColumn *column = NULL;
660 num_columns = hildon_touch_selector_get_num_columns (selector);
662 mode = hildon_touch_selector_get_column_selection_mode (selector);
664 if ((mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE)
665 && (num_columns > 0)) {
666 /* In this case we get the first column first */
667 selected_rows = hildon_touch_selector_get_selected_rows (selector, 0);
668 model = hildon_touch_selector_get_model (selector, 0);
669 column = hildon_touch_selector_get_column (selector, 0);
670 text_column = hildon_touch_selector_column_get_text_column (column);
672 result = g_strdup_printf ("(");
674 for (item = selected_rows; item; item = g_list_next (item)) {
675 current_path = item->data;
676 gtk_tree_model_get_iter (model, &iter, current_path);
678 if (text_column != -1) {
679 gtk_tree_model_get (model, &iter, text_column, ¤t_string, -1);
682 if (i < g_list_length (selected_rows) - 1) {
683 aux = g_strconcat (result, current_string, ",", NULL);
687 aux = g_strconcat (result, current_string, NULL);
692 if (current_string) {
693 g_free (current_string);
694 current_string = NULL;
700 aux = g_strconcat (result, ")", NULL);
704 g_list_foreach (selected_rows, (GFunc) (gtk_tree_path_free), NULL);
705 g_list_free (selected_rows);
711 for (i = initial_value; i < num_columns; i++) {
712 model = hildon_touch_selector_get_model (selector, i);
713 column = hildon_touch_selector_get_column (selector, i);
714 text_column = hildon_touch_selector_column_get_text_column (column);
716 if (hildon_touch_selector_get_selected (selector, i, &iter)) {
717 if (text_column == -1 ) {
718 g_warning ("Trying to use the default print function in HildonTouchSelector, but "
719 "\"text-column\" property is not set for HildonTouchSelectorColumn %p.", column);
720 current_string = NULL;
722 gtk_tree_model_get (model, &iter, text_column, ¤t_string, -1);
726 result = current_string;
728 aux = g_strconcat (result, ":", current_string, NULL);
730 g_free (current_string);
731 current_string = NULL;
741 hildon_touch_selector_row_activated_cb (GtkTreeView *tree_view,
743 GtkTreeViewColumn *column,
746 HildonTouchSelectorColumn *selector_column = NULL;
747 GtkTreeModel *model = NULL;
749 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (user_data));
750 selector_column = HILDON_TOUCH_SELECTOR_COLUMN (user_data);
752 model = selector_column->priv->model;
754 if (selector_column->priv->last_activated != NULL) {
755 gtk_tree_row_reference_free (selector_column->priv->last_activated);
758 selector_column->priv->last_activated = gtk_tree_row_reference_new (model, path);
762 _row_tapped_cb (GtkTreeView * tree_view, GtkTreePath * path, gpointer user_data)
764 HildonTouchSelector *selector = NULL;
765 HildonTouchSelectorColumn *column = NULL;
766 gint num_column = -1;
768 column = HILDON_TOUCH_SELECTOR_COLUMN (user_data);
769 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (column->priv->parent));
771 selector = column->priv->parent;
773 num_column = g_slist_index (selector->priv->columns, column);
775 hildon_touch_selector_emit_value_changed (selector, num_column);
779 static HildonTouchSelectorColumn *
780 _create_new_column (HildonTouchSelector * selector,
781 GtkTreeModel * model,
782 gboolean *emit_changed,
783 GtkCellRenderer * renderer, va_list args)
785 HildonTouchSelectorColumn *new_column = NULL;
786 GtkTreeViewColumn *tree_column = NULL;
787 GtkTreeView *tv = NULL;
788 GtkWidget *panarea = NULL;
789 GtkTreeSelection *selection = NULL;
794 tree_column = gtk_tree_view_column_new ();
796 if (renderer != NULL) {
797 gtk_tree_view_column_pack_start (tree_column, renderer, TRUE);
799 attribute = va_arg (args, gchar *);
800 while (attribute != NULL) {
801 value = va_arg (args, gint);
802 gtk_tree_view_column_add_attribute (tree_column, renderer, attribute,
804 attribute = va_arg (args, gchar *);
809 tv = GTK_TREE_VIEW (hildon_gtk_tree_view_new (selector->priv->hildon_ui_mode));
811 tv = GTK_TREE_VIEW (gtk_tree_view_new ());
812 #endif /* MAEMO_GTK */
814 gtk_tree_view_set_enable_search (tv, FALSE);
815 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (tv), GTK_CAN_FOCUS);
817 gtk_tree_view_set_model (tv, model);
818 g_signal_connect (model, "row-changed",
819 G_CALLBACK (on_row_changed), selector);
820 gtk_tree_view_set_rules_hint (tv, TRUE);
822 gtk_tree_view_append_column (GTK_TREE_VIEW (tv), tree_column);
824 new_column = g_object_new (HILDON_TYPE_TOUCH_SELECTOR_COLUMN, NULL);
825 new_column->priv->parent = selector;
827 panarea = hildon_pannable_area_new ();
829 g_object_set (G_OBJECT (panarea),
830 "initial-hint", FALSE, NULL);
832 gtk_container_add (GTK_CONTAINER (panarea), GTK_WIDGET (tv));
834 new_column->priv->model = model;
835 new_column->priv->tree_view = tv;
836 new_column->priv->panarea = panarea;
837 new_column->priv->realize_handler = 0;
838 new_column->priv->initial_path = NULL;
840 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
841 gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
843 /* select the first item */
844 *emit_changed = FALSE;
845 if ((gtk_tree_model_get_iter_first (model, &iter))&&
846 (selector->priv->hildon_ui_mode == HILDON_UI_MODE_EDIT)) {
847 gtk_tree_selection_select_iter (selection, &iter);
848 *emit_changed = TRUE;
851 gtk_widget_grab_focus (GTK_WIDGET (tv));
853 /* connect to the hildon-row-tapped signal connection */
854 g_signal_connect (G_OBJECT (tv), "hildon-row-tapped",
855 G_CALLBACK (_row_tapped_cb), new_column);
857 g_signal_connect (G_OBJECT (tv), "row-activated",
858 G_CALLBACK (hildon_touch_selector_row_activated_cb), new_column);
864 /* ------------------------ HildonTouchSelectorColumn implementation ---------------------- */
865 G_DEFINE_TYPE_WITH_CODE (HildonTouchSelectorColumn, hildon_touch_selector_column, G_TYPE_OBJECT,
866 G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
867 hildon_touch_selector_column_cell_layout_init))
875 hildon_touch_selector_column_class_init (HildonTouchSelectorColumnClass *klass);
878 hildon_touch_selector_column_get_property (GObject *object, guint property_id,
879 GValue *value, GParamSpec *pspec);
882 hildon_touch_selector_column_set_property (GObject *object, guint property_id,
883 const GValue *value, GParamSpec *pspec);
887 hildon_touch_selector_column_class_init (HildonTouchSelectorColumnClass *klass)
889 GObjectClass *gobject_class = NULL;
891 gobject_class = G_OBJECT_CLASS (klass);
893 g_type_class_add_private (gobject_class, sizeof (HildonTouchSelectorColumnPrivate));
896 gobject_class->get_property = hildon_touch_selector_column_get_property;
897 gobject_class->set_property = hildon_touch_selector_column_set_property;
900 * HildonTouchSelectorColumn:text-column:
902 * A column in the data source model to get the strings from.
906 g_object_class_install_property (G_OBJECT_CLASS(klass),
908 g_param_spec_int ("text-column",
910 "A column in the data source model to get the strings from.",
918 hildon_touch_selector_column_init (HildonTouchSelectorColumn *column)
920 column->priv = G_TYPE_INSTANCE_GET_PRIVATE (column, HILDON_TYPE_TOUCH_SELECTOR_COLUMN,
921 HildonTouchSelectorColumnPrivate);
922 column->priv->text_column = -1;
923 column->priv->last_activated = NULL;
927 * hildon_touch_selector_column_set_text_column:
928 * @column: A #HildonTouchSelectorColumn
929 * @text_column: the index of a model column in the model for @column.
931 * Sets the model column to be displayed in @column. @text_column must point to a
932 * column in the model used with type %G_TYPE_STRING. Initially, this property
933 * is unset. You should set it before using the #HildonTouchSelector that uses
939 hildon_touch_selector_column_set_text_column (HildonTouchSelectorColumn *column,
942 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (column));
943 g_return_if_fail (text_column >= -1);
945 column->priv->text_column = text_column;
947 g_object_notify (G_OBJECT (column), "text-column");
951 * hildon_touch_selector_column_get_text_column:
952 * @column: a #HildonTouchSelectorColumn
954 * Gets the model column set as the text source for @column.
956 * Returns: the index of the text column for @column, or -1 if unset.
961 hildon_touch_selector_column_get_text_column (HildonTouchSelectorColumn *column)
963 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (column), -1);
965 return column->priv->text_column;
969 hildon_touch_selector_column_get_property (GObject *object, guint property_id,
970 GValue *value, GParamSpec *pspec)
972 switch (property_id) {
973 case PROP_TEXT_COLUMN:
974 g_value_set_int (value,
975 hildon_touch_selector_column_get_text_column (HILDON_TOUCH_SELECTOR_COLUMN (object)));
978 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
983 hildon_touch_selector_column_set_property (GObject *object, guint property_id,
984 const GValue *value, GParamSpec *pspec)
986 switch (property_id) {
987 case PROP_TEXT_COLUMN:
988 hildon_touch_selector_column_set_text_column (HILDON_TOUCH_SELECTOR_COLUMN (object),
989 g_value_get_int (value));
992 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
996 /* ------------------------ GtkCellLayout implementation -------------------- */
998 hildon_touch_selector_column_cell_layout_init (GtkCellLayoutIface *iface)
1000 iface->pack_start = hildon_touch_selector_column_cell_layout_pack_start;
1001 iface->pack_end = hildon_touch_selector_column_cell_layout_pack_end;
1002 iface->clear = hildon_touch_selector_column_cell_layout_clear;
1003 iface->add_attribute = hildon_touch_selector_column_cell_layout_add_attribute;
1004 iface->set_cell_data_func = hildon_touch_selector_column_cell_layout_set_cell_data_func;
1005 iface->clear_attributes = hildon_touch_selector_column_cell_layout_clear_attributes;
1006 iface->reorder = hildon_touch_selector_column_cell_layout_reorder;
1007 iface->get_cells = hildon_touch_selector_column_cell_layout_get_cells;
1011 hildon_touch_selector_column_cell_layout_pack_start (GtkCellLayout *cell_layout,
1012 GtkCellRenderer *cell,
1015 HildonTouchSelectorColumn *sel_column = NULL;
1016 GtkTreeViewColumn *view_column = NULL;
1018 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1019 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1021 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1023 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(view_column), cell, expand);
1028 hildon_touch_selector_column_cell_layout_pack_end (GtkCellLayout *cell_layout,
1029 GtkCellRenderer *cell,
1032 HildonTouchSelectorColumn *sel_column = NULL;
1033 GtkTreeViewColumn *view_column = NULL;
1035 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1036 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1038 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1040 gtk_cell_layout_pack_end (GTK_CELL_LAYOUT(view_column), cell, expand);
1044 hildon_touch_selector_column_cell_layout_clear (GtkCellLayout *cell_layout)
1046 HildonTouchSelectorColumn *sel_column = NULL;
1047 GtkTreeViewColumn *view_column = NULL;
1049 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1050 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1052 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1054 gtk_cell_layout_clear (GTK_CELL_LAYOUT(view_column));
1058 hildon_touch_selector_column_cell_layout_add_attribute (GtkCellLayout *cell_layout,
1059 GtkCellRenderer *cell,
1060 const gchar *attribute,
1063 HildonTouchSelectorColumn *sel_column = NULL;
1064 GtkTreeViewColumn *view_column = NULL;
1066 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1067 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1069 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1071 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(view_column), cell, attribute, column);
1076 hildon_touch_selector_column_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout,
1077 GtkCellRenderer *cell,
1078 GtkCellLayoutDataFunc func,
1080 GDestroyNotify destroy)
1082 HildonTouchSelectorColumn *sel_column = NULL;
1083 GtkTreeViewColumn *view_column = NULL;
1085 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1086 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1088 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1090 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT(view_column), cell, func,
1091 func_data, destroy);
1095 hildon_touch_selector_column_cell_layout_clear_attributes (GtkCellLayout *cell_layout,
1096 GtkCellRenderer *cell)
1098 HildonTouchSelectorColumn *sel_column = NULL;
1099 GtkTreeViewColumn *view_column = NULL;
1101 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1102 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1104 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1106 gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (view_column), cell);
1110 hildon_touch_selector_column_cell_layout_reorder (GtkCellLayout *cell_layout,
1111 GtkCellRenderer *cell,
1114 HildonTouchSelectorColumn *sel_column = NULL;
1115 GtkTreeViewColumn *view_column = NULL;
1117 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
1118 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1120 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1122 gtk_cell_layout_reorder (GTK_CELL_LAYOUT(view_column), cell, position);
1126 hildon_touch_selector_column_cell_layout_get_cells (GtkCellLayout *cell_layout)
1128 HildonTouchSelectorColumn *sel_column = NULL;
1129 GtkTreeViewColumn *view_column = NULL;
1131 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout), NULL);
1132 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
1134 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
1136 return gtk_cell_layout_get_cells (GTK_CELL_LAYOUT(view_column));
1139 /* ------------------------------ PUBLIC METHODS ---------------------------- */
1142 * hildon_touch_selector_new:
1144 * Creates a new empty #HildonTouchSelector.
1146 * Returns: a new #HildonTouchSelector.
1151 hildon_touch_selector_new (void)
1153 return g_object_new (HILDON_TYPE_TOUCH_SELECTOR, NULL);
1157 * hildon_touch_selector_new_text:
1159 * Creates a #HildonTouchSelector with a single text column that
1160 * can be populated conveniently through hildon_touch_selector_append_text(),
1161 * hildon_touch_selector_prepend_text(), hildon_touch_selector_insert_text().
1163 * Returns: A new #HildonTouchSelector
1168 hildon_touch_selector_new_text (void)
1170 GtkWidget *selector;
1171 GtkListStore *store;
1172 HildonTouchSelectorColumn *column = NULL;
1174 selector = hildon_touch_selector_new ();
1175 store = gtk_list_store_new (1, G_TYPE_STRING);
1177 column = hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
1178 GTK_TREE_MODEL (store), TRUE);
1180 hildon_touch_selector_column_set_text_column (column, 0);
1186 * hildon_touch_selector_append_text:
1187 * @selector: A #HildonTouchSelector.
1188 * @text: a non %NULL text string.
1190 * Appends a new entry in a #HildonTouchSelector created with
1191 * hildon_touch_selector_new_text().
1196 hildon_touch_selector_append_text (HildonTouchSelector * selector,
1200 GtkTreeModel *model;
1202 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1203 g_return_if_fail (text != NULL);
1205 model = hildon_touch_selector_get_model (HILDON_TOUCH_SELECTOR (selector), 0);
1207 g_return_if_fail (GTK_IS_LIST_STORE (model));
1209 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
1210 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, text, -1);
1214 * hildon_touch_selector_prepend_text:
1215 * @selector: A #HildonTouchSelector.
1216 * @text: a non %NULL text string.
1218 * Prepends a new entry in a #HildonTouchSelector created with
1219 * hildon_touch_selector_new_text().
1224 hildon_touch_selector_prepend_text (HildonTouchSelector * selector,
1228 GtkTreeModel *model;
1230 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1231 g_return_if_fail (text != NULL);
1233 model = hildon_touch_selector_get_model (HILDON_TOUCH_SELECTOR (selector), 0);
1235 g_return_if_fail (GTK_IS_LIST_STORE (model));
1237 gtk_list_store_prepend (GTK_LIST_STORE (model), &iter);
1238 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, text, -1);
1242 * hildon_touch_selector_insert_text:
1243 * @selector: a #HildonTouchSelector.
1244 * @position: the position to insert @text.
1245 * @text: A non %NULL text string.
1247 * Inserts a new entry in a particular position of a
1248 * #HildonTouchSelector created with hildon_touch_selector_new_text().
1253 hildon_touch_selector_insert_text (HildonTouchSelector * selector,
1254 gint position, const gchar * text)
1257 GtkTreeModel *model;
1259 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1260 g_return_if_fail (text != NULL);
1261 g_return_if_fail (position >= 0);
1263 model = hildon_touch_selector_get_model (HILDON_TOUCH_SELECTOR (selector), 0);
1265 g_return_if_fail (GTK_IS_LIST_STORE (model));
1267 gtk_list_store_insert (GTK_LIST_STORE (model), &iter, position);
1268 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, text, -1);
1272 * hildon_touch_selector_append_column
1273 * @selector: a #HildonTouchSelector
1274 * @model: the #GtkTreeModel with the data of the column
1275 * @cell_renderer: The #GtkCellRenderer where to draw each row contents.
1276 * @Varargs: a %NULL-terminated pair of attributes and column numbers.
1278 * This functions adds a new column to the widget, whose data will
1279 * be obtained from the model. Only widgets added this way should used on
1280 * the selection logic, the print function, the #HildonTouchSelector::changed
1281 * signal, etc. Internally, a #GtkTreeView will be added to the widget, using
1282 * @model as the data source.
1284 * You can optionally pass a #GtkCellRenderer in @cell_renderer,
1285 * together with a %NULL-terminated list of pairs property/value, in
1286 * the same way you would use gtk_tree_view_column_set_attributes().
1287 * This will pack @cell_renderer at the start of the column, expanded
1288 * by default. If you prefer not to add it this way, you can simply
1289 * pass %NULL to @cell_renderer and use the #GtkCellLayout interface
1290 * on the returned #HildonTouchSelectorColumn to set your
1291 * renderers. Please note that the returned #HildonTouchSelectorColumn
1292 * is owned by @selector, you shouldn't unref it after setting it
1295 * Initially, the returned #HildonTouchSelectorColumn will have its
1296 * #HildonTouchSelectorColumn:text-column property unset. You should set
1297 * it to a column in @model with type %G_TYPE_STRING. See
1298 * hildon_touch_selector_column_set_text_column().
1300 * This method could change the current #HildonTouchSelector:hildon-ui-mode.
1301 * %HILDON_UI_MODE_NORMAL is only allowed with one column, so if the selector
1302 * is in this mode, and a additional column is added,
1303 * #HildonTouchSelector:hildon-ui-mode will change to %HILDON_UI_MODE_EDIT.
1305 * Returns: the new column added added, %NULL otherwise.
1310 HildonTouchSelectorColumn*
1311 hildon_touch_selector_append_column (HildonTouchSelector * selector,
1312 GtkTreeModel * model,
1313 GtkCellRenderer * cell_renderer, ...)
1316 HildonTouchSelectorColumn *new_column = NULL;
1317 gboolean emit_changed = FALSE;
1320 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1321 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
1323 if (model != NULL) {
1325 va_start (args, cell_renderer);
1326 new_column = _create_new_column (selector, model, &emit_changed, cell_renderer, args);
1329 selector->priv->columns = g_slist_append (selector->priv->columns,
1331 gtk_box_pack_start (GTK_BOX (selector->priv->hbox),
1332 new_column->priv->panarea,
1335 gtk_widget_show_all (new_column->priv->panarea);
1337 if (selector->priv->initial_scroll) {
1338 _hildon_touch_selector_center_on_selected_items (selector, new_column);
1345 g_signal_emit (selector, hildon_touch_selector_signals[COLUMNS_CHANGED], 0);
1347 colnum = g_slist_length (selector->priv->columns);
1348 hildon_touch_selector_emit_value_changed (selector, colnum);
1351 hildon_touch_selector_check_ui_mode_coherence (selector);
1357 * hildon_touch_selector_append_text_column
1358 * @selector: a #HildonTouchSelector
1359 * @model: a #GtkTreeModel with data for the column
1360 * @center: whether to center the text on the column
1362 * Equivalent to hildon_touch_selector_append_column(), but using a
1363 * default text cell renderer. This is the most common use case of the
1366 * Returns: the new column added, NULL otherwise.
1370 HildonTouchSelectorColumn*
1371 hildon_touch_selector_append_text_column (HildonTouchSelector * selector,
1372 GtkTreeModel * model, gboolean center)
1374 gfloat xalign = center ? 0.5 : 0.0;
1375 GtkCellRenderer *renderer;
1377 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1378 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
1380 renderer = gtk_cell_renderer_text_new ();
1382 g_object_set (renderer,
1387 return hildon_touch_selector_append_column (selector, model, renderer,
1392 * hildon_touch_selector_remove_column:
1393 * @selector: a #HildonTouchSelector
1394 * @column: the position of the column to be removed
1396 * Removes a column from @selector.
1398 * Returns: %TRUE if the column was removed, %FALSE otherwise
1403 hildon_touch_selector_remove_column (HildonTouchSelector * selector, gint column)
1405 HildonTouchSelectorColumn *current_column = NULL;
1406 HildonTouchSelectorPrivate *priv;
1408 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
1409 g_return_val_if_fail (column <
1410 hildon_touch_selector_get_num_columns (selector), FALSE);
1412 priv = HILDON_TOUCH_SELECTOR_GET_PRIVATE (selector);
1413 current_column = g_slist_nth_data (priv->columns, column);
1415 gtk_container_remove (GTK_CONTAINER (priv->hbox), current_column->priv->panarea);
1416 priv->columns = g_slist_remove (priv->columns, current_column);
1417 g_object_unref (current_column);
1419 g_signal_emit (selector, hildon_touch_selector_signals[COLUMNS_CHANGED], 0);
1425 * hildon_touch_selector_set_column_attributes:
1426 * @selector: a #HildonTouchSelector
1427 * @num_column: the number of the column whose attributes we're setting
1428 * @cell_renderer: the #GtkCellRendere we're setting the attributes of
1429 * @Varargs: A %NULL-terminated list of attributes.
1431 * Sets the attributes for the given column. The attributes must be given
1432 * in attribute/column pairs, just like in gtk_tree_view_column_set_attributes().
1433 * All existing attributes are removed and replaced with the new ones.
1435 * Deprecated: #HildonTouchSelectorColumn implements #GtkCellLayout, use this
1436 * interface instead. See
1437 * hildon_touch_selector_get_column().
1442 hildon_touch_selector_set_column_attributes (HildonTouchSelector * selector,
1444 GtkCellRenderer * cell_renderer,
1448 GtkTreeViewColumn *tree_column = NULL;
1449 HildonTouchSelectorColumn *current_column = NULL;
1450 gchar *attribute = NULL;
1453 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1454 g_return_if_fail (num_column <
1455 hildon_touch_selector_get_num_columns (selector));
1457 current_column = g_slist_nth_data (selector->priv->columns, num_column);
1459 tree_column = gtk_tree_view_get_column (current_column->priv->tree_view, 0);
1460 gtk_tree_view_remove_column (current_column->priv->tree_view, tree_column);
1462 tree_column = gtk_tree_view_column_new ();
1463 gtk_tree_view_column_pack_start (tree_column, cell_renderer, TRUE);
1465 va_start (args, cell_renderer);
1466 attribute = va_arg (args, gchar *);
1468 gtk_tree_view_column_clear_attributes (tree_column, cell_renderer);
1470 while (attribute != NULL) {
1471 value = va_arg (args, gint);
1472 gtk_tree_view_column_add_attribute (tree_column, cell_renderer,
1474 attribute = va_arg (args, gchar *);
1479 gtk_tree_view_append_column (current_column->priv->tree_view, tree_column);
1483 * hildon_touch_selector_get_num_columns:
1484 * @selector: a #HildonTouchSelector
1486 * Gets the number of columns in the #HildonTouchSelector.
1488 * Returns: the number of columns in @selector.
1493 hildon_touch_selector_get_num_columns (HildonTouchSelector * selector)
1495 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), -1);
1497 return g_slist_length (selector->priv->columns);
1501 * hildon_touch_selector_get_column_selection_mode:
1502 * @selector: a #HildonTouchSelector
1504 * Gets the selection mode of @selector.
1506 * Returns: one of #HildonTouchSelectorSelectionMode
1510 HildonTouchSelectorSelectionMode
1511 hildon_touch_selector_get_column_selection_mode (HildonTouchSelector * selector)
1513 HildonTouchSelectorSelectionMode result =
1514 HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE;
1515 GtkSelectionMode treeview_mode = GTK_SELECTION_BROWSE;
1516 HildonTouchSelectorColumn *column = NULL;
1517 GtkTreeSelection *selection = NULL;
1519 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), result);
1520 g_return_val_if_fail (hildon_touch_selector_get_num_columns (selector) > 0,
1523 column = HILDON_TOUCH_SELECTOR_COLUMN (selector->priv->columns->data);
1525 selection = gtk_tree_view_get_selection (column->priv->tree_view);
1526 treeview_mode = gtk_tree_selection_get_mode (selection);
1529 if (treeview_mode == GTK_SELECTION_MULTIPLE) {
1530 result = HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE;
1532 result = HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE;
1539 * hildon_touch_selector_set_column_selection_mode:
1540 * @selector: a #HildonTouchSelector
1541 * @mode: the #HildonTouchSelectorMode for @selector
1543 * Sets the selection mode for @selector. See #HildonTouchSelectorSelectionMode.
1545 * The new @mode will be set, but take into into account that the
1546 * #HildonTouchSelectorSelectionMode is ignored if the @selector
1547 * #HildonTouchSelector:hildon-ui-mode property is set to %HILDON_UI_MODE_NORMAL
1552 hildon_touch_selector_set_column_selection_mode (HildonTouchSelector * selector,
1553 HildonTouchSelectorSelectionMode mode)
1555 GtkTreeView *tv = NULL;
1556 HildonTouchSelectorColumn *column = NULL;
1557 GtkTreeSelection *selection = NULL;
1558 GtkSelectionMode treeview_mode = GTK_SELECTION_MULTIPLE;
1560 HildonTouchSelectorSelectionMode current_mode;
1562 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1563 g_return_if_fail (hildon_touch_selector_get_num_columns (selector) > 0);
1565 current_mode = hildon_touch_selector_get_column_selection_mode (selector);
1567 if (current_mode == mode) {
1571 column = HILDON_TOUCH_SELECTOR_COLUMN ((g_slist_nth (selector->priv->columns, 0))->data);
1572 tv = column->priv->tree_view;
1576 case HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE:
1577 treeview_mode = GTK_SELECTION_BROWSE;
1579 case HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE:
1580 treeview_mode = GTK_SELECTION_MULTIPLE;
1584 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
1585 gtk_tree_selection_set_mode (selection, treeview_mode);
1587 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
1588 gtk_tree_model_get_iter_first (column->priv->model, &iter);
1589 gtk_tree_selection_unselect_all (selection);
1590 gtk_tree_selection_select_iter (selection, &iter);
1592 /* the column changed was the first one */
1593 hildon_touch_selector_emit_value_changed (selector, 0);
1599 * hildon_touch_selector_set_print_func:
1600 * @selector: a #HildonTouchSelector
1601 * @func: a #HildonTouchSelectorPrintFunc function
1603 * Sets the function to be used by hildon_touch_selector_get_current_text().
1604 * See hildon_touch_selector_set_print_func_full().
1609 hildon_touch_selector_set_print_func (HildonTouchSelector * selector,
1610 HildonTouchSelectorPrintFunc func)
1612 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1614 hildon_touch_selector_set_print_func_full (selector, func, NULL, NULL);
1618 * hildon_touch_selector_set_print_func_full:
1619 * @selector: a #HildonTouchSelector
1620 * @func: a #HildonTouchSelectorPrintFunc function
1621 * @user_data: a pointer to user data or %NULL
1622 * @destroy_func: a callback for freeing the user data or %NULL
1624 * Sets the function to be used by hildon_touch_selector_get_current_text()
1625 * to produce a text representation of the currently selected items in @selector.
1626 * The default function will return a concatenation of comma separated items
1627 * selected in each column in @selector. Use this to override this method if you
1628 * need a particular representation for your application.
1633 hildon_touch_selector_set_print_func_full (HildonTouchSelector *selector,
1634 HildonTouchSelectorPrintFunc func,
1636 GDestroyNotify destroy_func)
1638 gpointer old_user_data;
1639 GDestroyNotify old_destroy_func;
1641 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1643 old_user_data = selector->priv->print_user_data;
1644 old_destroy_func = selector->priv->print_destroy_func;
1646 selector->priv->print_func = func;
1647 selector->priv->print_user_data = user_data;
1648 selector->priv->print_destroy_func = destroy_func;
1650 if (old_destroy_func && old_user_data != user_data)
1651 (*old_destroy_func) (old_user_data);
1655 * hildon_touch_selector_get_print_func:
1656 * @selector: a #HildonTouchSelector
1658 * Gets the #HildonTouchSelectorPrintFunc currently used. See
1659 * hildon_touch_selector_set_print_func().
1661 * Returns: a #HildonTouchSelectorPrintFunc or %NULL if the default
1662 * one is currently used.
1664 HildonTouchSelectorPrintFunc
1665 hildon_touch_selector_get_print_func (HildonTouchSelector * selector)
1667 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1669 return selector->priv->print_func;
1673 * hildon_touch_selector_set_active:
1674 * @selector: a #HildonTouchSelector
1675 * @column: column number
1676 * @index: the index of the item to select, or -1 to have no active item
1678 * Sets the active item of the #HildonTouchSelector to @index. The
1679 * column number is taken from @column.
1681 * @selector must be in %HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE
1686 hildon_touch_selector_set_active (HildonTouchSelector *selector,
1690 GtkTreeSelection *selection = NULL;
1691 HildonTouchSelectorColumn *current_column = NULL;
1692 HildonTouchSelectorSelectionMode mode;
1695 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1696 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
1697 mode = hildon_touch_selector_get_column_selection_mode (selector);
1698 g_return_if_fail (mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE);
1700 current_column = g_slist_nth_data (selector->priv->columns, column);
1702 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (current_column->priv->tree_view));
1703 path = gtk_tree_path_new_from_indices (index, -1);
1704 gtk_tree_selection_unselect_all (selection);
1706 gtk_tree_selection_select_path (selection, path);
1708 hildon_touch_selector_emit_value_changed (selector, column);
1710 gtk_tree_path_free (path);
1714 * hildon_touch_selector_get_active:
1715 * @selector: a #HildonTouchSelector
1716 * @column: column number
1718 * Returns the index of the currently active item in column number
1719 * @column, or -1 if there's no active item.
1721 * @selector must be in %HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE
1723 * Returns: an integer which is the index of the currently active
1724 * item, or -1 if there's no active item.
1729 hildon_touch_selector_get_active (HildonTouchSelector *selector,
1732 GtkTreeSelection *selection = NULL;
1733 HildonTouchSelectorColumn *current_column = NULL;
1734 HildonTouchSelectorSelectionMode mode;
1735 GtkTreeModel *model;
1740 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), -1);
1741 g_return_val_if_fail (column < hildon_touch_selector_get_num_columns (selector), -1);
1742 mode = hildon_touch_selector_get_column_selection_mode (selector);
1743 g_return_val_if_fail (mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE, -1);
1745 current_column = g_slist_nth_data (selector->priv->columns, column);
1747 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (current_column->priv->tree_view));
1748 g_return_val_if_fail (gtk_tree_selection_get_selected (selection, NULL, &iter), -1);
1750 model = gtk_tree_view_get_model (GTK_TREE_VIEW (current_column->priv->tree_view));
1751 path = gtk_tree_model_get_path (model, &iter);
1752 index = (gtk_tree_path_get_indices (path))[0];
1754 gtk_tree_path_free (path);
1760 * hildon_touch_selector_get_selected:
1761 * @selector: a #HildonTouchSelector
1762 * @column: the column number we want to get the element
1763 * @iter: #GtkTreeIter currently selected
1765 * Sets @iter to the currently selected node on the nth-column, if selection is
1766 * set to %HILDON_TOUCH_SELECTOR_SINGLE or %HILDON_TOUCH_SELECTOR_MULTIPLE with
1767 * a column different that the first one. @iter may be %NULL if you just want to
1768 * test if selection has any selected items.
1770 * This function will not work if selection is in
1771 * %HILDON_TOUCH_SELECTOR_MULTIPLE mode and the column is the first one.
1773 * See gtk_tree_selection_get_selected() for more information.
1775 * Returns: %TRUE if @iter was correctly set, %FALSE otherwise
1780 hildon_touch_selector_get_selected (HildonTouchSelector * selector,
1781 gint column, GtkTreeIter * iter)
1783 GtkTreeSelection *selection = NULL;
1784 HildonTouchSelectorColumn *current_column = NULL;
1785 HildonTouchSelectorSelectionMode mode;
1787 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
1788 g_return_val_if_fail (column < hildon_touch_selector_get_num_columns (selector),
1790 mode = hildon_touch_selector_get_column_selection_mode (selector);
1791 g_return_val_if_fail
1792 ((mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE) ||
1793 ((mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE)&&(column>0)),
1796 current_column = g_slist_nth_data (selector->priv->columns, column);
1799 gtk_tree_view_get_selection (GTK_TREE_VIEW (current_column->priv->tree_view));
1801 return gtk_tree_selection_get_selected (selection, NULL, iter);
1805 * hildon_touch_selector_select_iter
1806 * @selector: a #HildonTouchSelector
1807 * @column: the column to selects
1808 * @iter: the #GtkTreeIter to be selected
1809 * @scroll_to: whether to smoothly scroll to the item
1811 * Sets the currently selected item in the column @column to the one pointed by @iter,
1812 * optionally smoothly scrolling to it.
1817 hildon_touch_selector_select_iter (HildonTouchSelector * selector,
1818 gint column, GtkTreeIter * iter,
1822 GtkTreeModel *model;
1823 HildonTouchSelectorColumn *current_column = NULL;
1824 GtkTreeView *tv = NULL;
1825 GtkTreeSelection *selection = NULL;
1827 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1828 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
1830 current_column = g_slist_nth_data (selector->priv->columns, column);
1832 tv = current_column->priv->tree_view;
1833 selection = gtk_tree_view_get_selection (tv);
1834 model = gtk_tree_view_get_model (tv);
1835 path = gtk_tree_model_get_path (model, iter);
1837 gtk_tree_selection_select_iter (selection, iter);
1840 hildon_touch_selector_scroll_to (current_column, tv, path);
1843 hildon_touch_selector_emit_value_changed (selector, column);
1845 gtk_tree_path_free (path);
1849 * hildon_touch_selector_unselect_iter
1850 * @selector: a #HildonTouchSelector
1851 * @column: the column to unselects from
1852 * @iter: the #GtkTreeIter to be unselected
1854 * Unselect the item pointed by @iter in the column @column
1859 void hildon_touch_selector_unselect_iter (HildonTouchSelector * selector,
1863 HildonTouchSelectorColumn *current_column = NULL;
1864 GtkTreeSelection *selection = NULL;
1866 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1867 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
1869 current_column = g_slist_nth_data (selector->priv->columns, column);
1870 selection = gtk_tree_view_get_selection (current_column->priv->tree_view);
1871 gtk_tree_selection_unselect_iter (selection, iter);
1873 hildon_touch_selector_emit_value_changed (selector, column);
1877 * hildon_touch_selector_unselect_all:
1878 * @selector: a #HildonTouchSelector
1879 * @column: the position of the column to get the selected rows from
1881 * Unselects all the selected items in the column @column.
1886 hildon_touch_selector_unselect_all (HildonTouchSelector * selector,
1889 HildonTouchSelectorColumn *current_column = NULL;
1890 GtkTreeSelection *selection = NULL;
1892 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1893 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
1895 current_column = g_slist_nth_data (selector->priv->columns, column);
1896 selection = gtk_tree_view_get_selection (current_column->priv->tree_view);
1897 gtk_tree_selection_unselect_all (selection);
1899 hildon_touch_selector_emit_value_changed (selector, column);
1903 * hildon_touch_selector_get_selected_rows:
1904 * @selector: a #HildonTouchSelector
1905 * @column: the position of the column to get the selected rows from
1907 * Creates a list of #GtkTreePath<!-- -->s of all selected rows in a column. Additionally,
1908 * if you to plan to modify the model after calling this function, you may
1909 * want to convert the returned list into a list of GtkTreeRowReferences. To do this,
1910 * you can use gtk_tree_row_reference_new().
1912 * See gtk_tree_selection_get_selected_rows() for more information.
1914 * Returns: A new #GList containing a #GtkTreePath for each selected row in the column @column.
1919 hildon_touch_selector_get_selected_rows (HildonTouchSelector * selector,
1922 GList *result = NULL;
1923 HildonTouchSelectorColumn *current_column = NULL;
1924 GtkTreeSelection *selection = NULL;
1926 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1927 g_return_val_if_fail (column < hildon_touch_selector_get_num_columns (selector),
1930 current_column = g_slist_nth_data (selector->priv->columns, column);
1931 selection = gtk_tree_view_get_selection (current_column->priv->tree_view);
1933 result = gtk_tree_selection_get_selected_rows (selection, NULL);
1939 * hildon_touch_selector_get_model:
1940 * @selector: a #HildonTouchSelector
1941 * @column: the position of the column in @selector
1943 * Gets the model of a column of @selector.
1945 * Returns: the #GtkTreeModel for the column @column of @selector.
1950 hildon_touch_selector_get_model (HildonTouchSelector * selector, gint column)
1952 HildonTouchSelectorColumn *current_column = NULL;
1954 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1955 g_return_val_if_fail (column < hildon_touch_selector_get_num_columns (selector),
1958 current_column = g_slist_nth_data (selector->priv->columns, column);
1960 return current_column->priv->model;
1964 on_row_changed (GtkTreeModel *model,
1969 HildonTouchSelector *selector;
1970 HildonTouchSelectorColumn *current_column;
1975 selector = HILDON_TOUCH_SELECTOR (userdata);
1977 for (col = selector->priv->columns; col != NULL; col = col->next) {
1978 current_column = HILDON_TOUCH_SELECTOR_COLUMN (col->data);
1979 if (current_column->priv->model == model &&
1980 gtk_tree_selection_path_is_selected (gtk_tree_view_get_selection (current_column->priv->tree_view),
1982 hildon_touch_selector_emit_value_changed (selector, column);
1989 _hildon_touch_selector_set_model (HildonTouchSelector * selector,
1990 gint column, GtkTreeModel * model)
1992 HildonTouchSelectorColumn *current_column = NULL;
1995 HILDON_TOUCH_SELECTOR_COLUMN (g_slist_nth_data (selector->priv->columns, column));
1997 if (current_column->priv->model) {
1998 g_signal_handlers_disconnect_by_func (current_column->priv->model,
1999 on_row_changed, selector);
2001 current_column->priv->model = model;
2002 gtk_tree_view_set_model (current_column->priv->tree_view,
2003 current_column->priv->model);
2004 g_signal_connect (model, "row-changed",
2005 G_CALLBACK (on_row_changed), selector);
2009 * hildon_touch_selector_set_model:
2010 * @selector: a #HildonTouchSelector
2011 * @column: the position of the column to set the model to
2012 * @model: a #GtkTreeModel
2014 * Sets the #GtkTreeModel for a particular column in @model.
2019 hildon_touch_selector_set_model (HildonTouchSelector * selector,
2020 gint column, GtkTreeModel * model)
2022 g_return_if_fail (HILDON_TOUCH_SELECTOR (selector));
2023 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
2025 HILDON_TOUCH_SELECTOR_GET_CLASS (selector)->set_model (selector, column, model);
2029 * hildon_touch_selector_get_current_text:
2030 * @selector: a #HildonTouchSelector
2032 * Returns a string representing the currently selected items for
2033 * each column of @selector. See hildon_touch_selector_set_print_func().
2035 * Returns: a newly allocated string.
2040 hildon_touch_selector_get_current_text (HildonTouchSelector * selector)
2042 gchar *result = NULL;
2043 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
2045 if (selector->priv->print_func) {
2046 result = (*selector->priv->print_func) (selector, selector->priv->print_user_data);
2048 result = _default_print_func (selector, NULL);
2055 search_nearest_element (HildonPannableArea *panarea,
2057 GList *selected_rows,
2058 GtkTreePath **nearest_path)
2060 GtkAdjustment *adj = NULL;
2061 gdouble target_value = 0;
2064 GtkTreePath *path = NULL;
2066 gdouble nearest_distance = -1;
2067 gdouble current_distance = -1;
2068 GtkTreePath *result_path = NULL;
2070 g_assert (nearest_path != NULL);
2072 if (selected_rows == NULL) {
2073 *nearest_path = NULL;
2077 adj = hildon_pannable_area_get_vadjustment (panarea);
2078 g_return_if_fail (adj != NULL);
2080 /* we add this in order to check the nearest to the center of
2082 target_value = gtk_adjustment_get_value (adj) + adj->page_size/2;
2084 path = result_path = selected_rows->data;
2085 gtk_tree_view_get_background_area (tv, path, NULL, &rect);
2086 gtk_tree_view_convert_bin_window_to_tree_coords (tv, 0, rect.y, NULL, &y);
2087 nearest_distance = abs (target_value - y);
2089 for (iter = selected_rows->next; iter; iter = g_list_next (iter)) {
2090 gtk_tree_view_get_background_area (tv, path, NULL, &rect);
2091 gtk_tree_view_convert_bin_window_to_tree_coords (tv, 0, rect.y, NULL, &y);
2092 current_distance = abs (target_value - y);
2093 if (current_distance < nearest_distance) {
2094 nearest_distance = current_distance;
2099 *nearest_path = result_path;
2103 on_realize_cb (GtkWidget *widget,
2106 HildonTouchSelectorColumn *column = NULL;
2110 column = HILDON_TOUCH_SELECTOR_COLUMN (data);
2112 if (column->priv->initial_path) {
2113 gtk_tree_view_get_background_area (GTK_TREE_VIEW (column->priv->tree_view),
2114 column->priv->initial_path, NULL, &rect);
2115 gtk_tree_view_convert_bin_window_to_tree_coords
2116 (GTK_TREE_VIEW (column->priv->tree_view),
2117 0, rect.y, NULL, &y);
2119 hildon_pannable_area_scroll_to (HILDON_PANNABLE_AREA (column->priv->panarea),
2122 gtk_tree_path_free (column->priv->initial_path);
2124 column->priv->initial_path = NULL;
2128 g_signal_handler_disconnect (column->priv->panarea,
2129 column->priv->realize_handler);
2135 hildon_touch_selector_scroll_to (HildonTouchSelectorColumn *column,
2139 if (GTK_WIDGET_REALIZED (column->priv->panarea)) {
2143 gtk_tree_view_get_background_area (tv,
2145 gtk_tree_view_convert_bin_window_to_tree_coords (tv,
2146 0, rect.y, NULL, &y);
2148 hildon_pannable_area_scroll_to (HILDON_PANNABLE_AREA
2149 (column->priv->panarea), -1, y);
2151 if (column->priv->realize_handler != 0) {
2153 if (column->priv->initial_path) {
2154 gtk_tree_path_free (column->priv->initial_path);
2155 column->priv->initial_path = NULL;
2158 g_signal_handler_disconnect (column->priv->panarea,
2159 column->priv->realize_handler);
2160 column->priv->realize_handler = 0;
2163 column->priv->initial_path = gtk_tree_path_copy (path);
2164 column->priv->realize_handler =
2165 g_signal_connect_after (G_OBJECT (column->priv->panarea), "realize",
2166 G_CALLBACK (on_realize_cb),
2173 * Center on the selected item of a concrete column
2175 * Returns: TRUE if was able to do that
2179 _hildon_touch_selector_center_on_selected_items (HildonTouchSelector *selector,
2180 HildonTouchSelectorColumn *column)
2182 GtkTreePath *path = NULL;
2183 GList *selected_rows = NULL;
2184 gint num_column = -1;
2186 num_column = g_slist_index (selector->priv->columns, column);
2188 selected_rows = hildon_touch_selector_get_selected_rows (selector, num_column);
2189 if (selected_rows) {
2190 search_nearest_element (HILDON_PANNABLE_AREA (column->priv->panarea),
2191 GTK_TREE_VIEW (column->priv->tree_view),
2196 hildon_touch_selector_scroll_to (column,
2197 GTK_TREE_VIEW (column->priv->tree_view),
2203 g_list_foreach (selected_rows, (GFunc) (gtk_tree_path_free), NULL);
2204 g_list_free (selected_rows);
2211 _hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector)
2213 HildonTouchSelectorSelectionMode mode;
2216 n_columns = hildon_touch_selector_get_num_columns (selector);
2217 mode = hildon_touch_selector_get_column_selection_mode (selector);
2219 return ((n_columns > 1) || (mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE));
2223 * hildon_touch_selector_has_multiple_selection:
2224 * @selector: A #HildonTouchSelector
2226 * Determines whether @selector is complex enough to actually require an
2227 * extra selection step than only picking an item. This is normally %TRUE
2228 * if @selector has multiple columns, multiple selection, or when it is a
2229 * more complex widget, like #HildonTouchSelectorEntry.
2231 * This information is useful for widgets containing a #HildonTouchSelector,
2232 * like #HildonPickerDialog, that could need a "Done" button, in case that
2233 * its internal #HildonTouchSelector has multiple columns, for instance.
2235 * Returns: %TRUE if @selector requires multiple selection steps.
2240 hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector)
2242 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
2244 return HILDON_TOUCH_SELECTOR_GET_CLASS (selector)->has_multiple_selection (selector);
2249 * hildon_touch_selector_get_column:
2250 * @selector: A #HildonTouchSelector
2251 * @column: a column number
2253 * Use this method to retrieve a #HildonTouchSelectorColumn. Then, you can use
2254 * the #GtkCellLayout interface to set up the layout of the column.
2256 * Returns: the @column<!-- -->-th #HildonTouchSelectorColumn in @selector
2260 HildonTouchSelectorColumn *
2261 hildon_touch_selector_get_column (HildonTouchSelector * selector,
2264 gint num_columns = -1;
2266 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
2267 num_columns = hildon_touch_selector_get_num_columns (selector);
2268 g_return_val_if_fail (column < num_columns && column >= 0, NULL);
2270 return g_slist_nth_data (selector->priv->columns, column);
2275 * hildon_touch_selector_center_on_selected:
2276 * @selector: a #HildonTouchSelector
2278 * Ensures all the columns in a #HildonTouchSelector show a selected
2279 * item. If one of the columns is in
2280 * %HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE mode, that column
2281 * will be scrolled to ensure the selected item that is closest to the
2282 * currently visible area is shown.
2284 * The #HildonTouchSelector:initial-scroll property configure the widget
2285 * in order to use this function at the first show.
2287 * Take into account that the element is not centered until the widget is
2288 * realized. If the widget is not realized when the function is called, it
2289 * will be postponed. If you call this functions several times before the
2290 * widgets is realized, only the last one will be used.
2292 * This behaviour includes any call to hildon_touch_selector_center_on_index(),
2293 * so take care calling this functions, or with the
2294 * #HildonTouchSelector:initial-scroll property in order to get centered on the
2300 hildon_touch_selector_center_on_selected (HildonTouchSelector *selector)
2302 GSList *iter = NULL;
2304 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
2306 for (iter = selector->priv->columns; iter; iter = g_slist_next (iter)) {
2307 _hildon_touch_selector_center_on_selected_items (selector,
2308 HILDON_TOUCH_SELECTOR_COLUMN (iter->data));
2313 * hildon_touch_selector_optimal_size_request
2314 * @selector: a #HildonTouchSelector
2315 * @requisition: a #GtkRequisition
2317 * Gets the optimal size request of the touch selector. This function is mostly
2318 * intended for dialog implementations that include a #HildonTouchSelector and
2319 * want to optimize the screen real state, for example, when you want a dialog
2320 * to show as much of the selector, avoiding any extra empty space below the
2323 * See #HildonPickerDialog implementation for an example.
2325 * This function is oriented to be used in the size_request of a dialog or window,
2326 * if you are not sure do not use it.
2328 * There is a precondition to this function: Since this function does not
2329 * call the "size_request" method, it can only be used when you know that
2330 * gtk_widget_size_request() has been called since the last time a resize was
2336 hildon_touch_selector_optimal_size_request (HildonTouchSelector *selector,
2337 GtkRequisition *requisition)
2339 GSList *iter = NULL;
2341 gint base_height = 0;
2343 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
2345 iter = selector->priv->columns;
2347 /* Default optimal values are the current ones */
2348 gtk_widget_get_child_requisition (GTK_WIDGET (selector),
2352 height = requisition->height;
2354 /* we use the normal requisition as base, as the touch selector can has
2355 extra widgets, not only the columns (ie: HildonTouchSelectorEntry) */
2356 base_height = requisition->height;
2359 /* Compute optimal height for the columns */
2361 HildonTouchSelectorColumn *column;
2363 GtkRequisition child_requisition = {0};
2365 column = HILDON_TOUCH_SELECTOR_COLUMN (iter->data);
2366 child = GTK_WIDGET (column->priv->tree_view);
2368 gtk_widget_get_child_requisition (child, &child_requisition);
2370 height = MAX (height, child_requisition.height);
2372 iter = g_slist_next (iter);
2375 requisition->height = base_height + height;
2381 * hildon_touch_selector_get_hildon_ui_mode
2382 * @selector: a #HildonTouchSelector
2384 * Gets the current hildon-ui-mode, see #HildonUIMode for more information
2386 * Returns: the current hildon-ui-mode
2391 hildon_touch_selector_get_hildon_ui_mode (HildonTouchSelector *selector)
2393 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), HILDON_UI_MODE_EDIT);
2395 return selector->priv->hildon_ui_mode;
2399 * hildon_touch_selector_set_hildon_ui_mode
2400 * @selector: a #HildonTouchSelector
2401 * @mode: a #HildonUIMode
2403 * Sets the value of the property #HildonTouchSelector:hildon-ui-mode to be @mode,
2404 * see #HildonUIMode for more information
2406 * Note that the %HILDON_UI_MODE_NORMAL can be only used when the selector has
2407 * one column, use the return value to check if the change was effective.
2409 * Returns: %TRUE if #HildonTouchSelector:hildon-ui-mode was changed
2415 hildon_touch_selector_set_hildon_ui_mode (HildonTouchSelector *selector,
2419 GSList *iter = NULL;
2420 HildonTouchSelectorColumn *column = NULL;
2421 GtkTreeView *tree_view = NULL;
2423 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
2424 num = hildon_touch_selector_get_num_columns (selector);
2425 g_return_val_if_fail ((mode == HILDON_UI_MODE_EDIT) || (num == 1), FALSE);
2427 if (mode == selector->priv->hildon_ui_mode) {
2431 for (iter = selector->priv->columns; iter; iter = g_slist_next (iter)) {
2432 column = HILDON_TOUCH_SELECTOR_COLUMN (iter->data);
2433 tree_view = column->priv->tree_view;
2435 hildon_tree_view_set_hildon_ui_mode (tree_view, mode);
2437 /* looking at the code of hildon_tree_view_set_hildon_ui_mode, it seems
2438 that it call the unselect_all, but it is required anyway */
2439 if (mode == HILDON_UI_MODE_NORMAL) {
2440 GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
2442 gtk_tree_selection_unselect_all (selection);
2446 selector->priv->hildon_ui_mode = mode;
2452 * hildon_touch_selector_get_last_activated_row
2453 * @selector: a #HildonTouchSelector
2454 * @column: column number
2456 * Gets a #GtkTreePath of the last row activated in a column (the last row that
2457 * emitted a #GtkTreeView::row-activated signal). This is mainly useful if the
2458 * @selector #HildonTouchSelector:hildon-ui-mode in set to %HILDON_UI_MODE_NORMAL,
2459 * as using this state there is no real selection, so a method like
2460 * hildon_touch_selector_get_selected_rows() will return always a empty
2463 * Anyway, this method works as well on %HILDON_UI_MODE_EDIT, but in this case
2464 * is better, and more useful, to get the current selection.
2466 * Returns: a newly allocated #GtkTreePath pointing to the last activated row
2467 * NULL if no row were activated.
2472 hildon_touch_selector_get_last_activated_row (HildonTouchSelector *selector,
2475 HildonTouchSelectorColumn *selector_column = NULL;
2477 /* this method with check selector and that the column number is correct*/
2478 selector_column = hildon_touch_selector_get_column (selector, column);
2480 if (selector_column == NULL) {
2484 if (selector_column->priv->last_activated != NULL) {
2485 return gtk_tree_row_reference_get_path (selector_column->priv->last_activated);
2493 * hildon_touch_selector_center_on_index:
2494 * @selector: a #HildonTouchSelector
2495 * @column: column number
2496 * @index: the index of the item to center on
2498 * Ensures that the column number @column shows the element @index
2500 * This is similar to hildon_touch_selector_center_on_selected() but with the
2501 * difference that allows to center on a column item not selected.
2503 * Take into account that the element is not centered until the widget is
2504 * realized. If the widget is not realized when the function is called, it will
2505 * be postponed. If you call this function several times before the widget is
2506 * realized, only the last one will be used.
2508 * This behaviour includes any call to hildon_touch_selector_center_on_selected().
2509 * Check this function for more tips.
2514 hildon_touch_selector_center_on_index (HildonTouchSelector *selector,
2518 HildonTouchSelectorColumn *current_column = NULL;
2519 GtkTreePath *path = NULL;
2521 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
2522 g_return_if_fail ((column >= 0) && (column < hildon_touch_selector_get_num_columns (selector)));
2523 g_return_if_fail (index >= 0);
2525 current_column = g_slist_nth_data (selector->priv->columns, column);
2527 path = gtk_tree_path_new_from_indices (index, -1);
2529 hildon_touch_selector_scroll_to (current_column,
2530 current_column->priv->tree_view,
2532 gtk_tree_path_free (path);