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 columns.
29 * Normally, you would use #HildonTouchSelector together with a
30 * #HildonPickerDialog activated from a button. For the most common
31 * cases, you should use #HildonPickerButton.
33 * The composition of each column in the selector is represented by a
34 * #GtkTreeModel. To add a new column to a #HildonTouchSelector, use
35 * hildon_touch_selector_append_column(). If you want to add a
36 * text-only column, without special attributes, use
37 * hildon_touch_selector_append_text_column().
39 * It is highly recommended that you use only one column
40 * #HildonTouchSelector<!-- -->s.
41 * If you only need a text only, one column selector, you can create it with
42 * hildon_touch_selector_new_text() and populate with
43 * hildon_touch_selector_append_text(), hildon_touch_selector_prepend_text(),
44 * and hildon_touch_selector_insert_text().
46 * If you need a selector widget that also accepts user inputs, you
47 * can use #HildonTouchSelectorEntry.
49 * The current selection has a string representation. In the most common cases,
50 * each column model will contain a text column. You can configure
51 * which column in particular using the #HildonTouchSelectorColumn property
52 * #HildonTouchSelectorColumn:text-column
54 * You can get this string representation using
55 * hildon_touch_selector_get_current_text().
56 * You can configure how the selection is printed with
57 * hildon_touch_selector_set_print_func(), that sets the current hildon touch
58 * selector print function. The widget has a default print function, that
59 * uses the #HildonTouchSelectorColumn:text-column property on each
60 * #HildonTouchSelectorColumn to compose the final representation.
62 * If you create the selector using hildon_touch_selector_new_text() you
63 * don't need to take care of this property, as the model is created internally.
64 * If you create the selector using hildon_touch_selector_new(), you
65 * need to specify properly the property for your custom model in order to get a
66 * non-empty string representation, or define your custom print function.
71 * SECTION:hildon-touch-selector-column
72 * @short_description: A visible column in a #HildonTouchSelector
74 * #HildonTouchSelectorColumn object represents a visible column in
75 * #HildonTouchSelector. It allows to manage the cell renderers related to each
79 #undef HILDON_DISABLE_DEPRECATED
88 #include "hildon-gtk.h"
90 #include "hildon-pannable-area.h"
91 #include "hildon-touch-selector.h"
93 #define HILDON_TOUCH_SELECTOR_GET_PRIVATE(obj) \
94 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_TOUCH_SELECTOR, HildonTouchSelectorPrivate))
96 G_DEFINE_TYPE (HildonTouchSelector, hildon_touch_selector, GTK_TYPE_VBOX)
99 * IMPLEMENTATION NOTES:
100 * Struct to maintain the data of each column. The columns are the elements
101 * of the widget that belongs properly to the selection behaviour. Although
102 * internally the columns are arranged in a private #GtkHBox, as the selector
103 * itself is a #GtkVBox, you can add more widgets, like buttons etc., so
104 * you finally could have a widget with more elements that the columns, but
105 * this doesn't belongs to the selection logic
107 struct _HildonTouchSelectorColumnPrivate
109 HildonTouchSelector *parent; /* the selector that contains this column */
112 GtkTreeView *tree_view;
114 GtkWidget *panarea; /* the pannable widget */
117 struct _HildonTouchSelectorPrivate
119 GSList *columns; /* the selection columns */
120 GtkWidget *hbox; /* the container for the selector's columns */
121 gboolean initial_scroll; /* whether initial fancy scrolling to selection */
123 HildonTouchSelectorPrintFunc print_func;
128 PROP_HAS_MULTIPLE_SELECTION = 1,
139 static gint hildon_touch_selector_signals[LAST_SIGNAL] = { 0 };
142 hildon_touch_selector_get_property (GObject * object,
147 hildon_touch_selector_set_property (GObject *object,
154 static void hildon_touch_selector_remove (GtkContainer * container,
156 /* private functions */
157 static void _selection_changed_cb (GtkTreeSelection * selection,
159 static gchar *_default_print_func (HildonTouchSelector * selector);
161 static HildonTouchSelectorColumn *_create_new_column (HildonTouchSelector * selector,
162 GtkTreeModel * model,
163 GtkCellRenderer * renderer,
166 _hildon_touch_selector_center_on_selected_items (GtkWidget *widget,
170 _hildon_touch_selector_set_model (HildonTouchSelector * selector,
172 GtkTreeModel * model);
174 _hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector);
176 /* GtkCellLayout implementation (HildonTouchSelectorColumn)*/
177 static void hildon_touch_selector_column_cell_layout_init (GtkCellLayoutIface *iface);
179 static void hildon_touch_selector_column_cell_layout_pack_start (GtkCellLayout *cell_layout,
180 GtkCellRenderer *cell,
182 static void hildon_touch_selector_column_cell_layout_pack_end (GtkCellLayout *cell_layout,
183 GtkCellRenderer *cell,
185 static void hildon_touch_selector_column_cell_layout_clear (GtkCellLayout *cell_layout);
186 static void hildon_touch_selector_column_cell_layout_add_attribute(GtkCellLayout *cell_layout,
187 GtkCellRenderer *cell,
188 const gchar *attribute,
190 static void hildon_touch_selector_column_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout,
191 GtkCellRenderer *cell,
192 GtkCellLayoutDataFunc func,
194 GDestroyNotify destroy);
195 static void hildon_touch_selector_column_cell_layout_clear_attributes (GtkCellLayout *cell_layout,
196 GtkCellRenderer *cell);
197 static void hildon_touch_selector_column_cell_layout_reorder (GtkCellLayout *cell_layout,
198 GtkCellRenderer *cell,
200 static GList *hildon_touch_selector_column_cell_layout_get_cells (GtkCellLayout *cell_layout);
204 hildon_touch_selector_class_init (HildonTouchSelectorClass * class)
206 GObjectClass *gobject_class;
207 GtkObjectClass *object_class;
208 GtkWidgetClass *widget_class;
209 GtkContainerClass *container_class;
211 gobject_class = G_OBJECT_CLASS (class);
212 object_class = GTK_OBJECT_CLASS (class);
213 widget_class = GTK_WIDGET_CLASS (class);
214 container_class = GTK_CONTAINER_CLASS (class);
217 gobject_class->get_property = hildon_touch_selector_get_property;
218 gobject_class->set_property = hildon_touch_selector_set_property;
223 container_class->remove = hildon_touch_selector_remove;
225 /* HildonTouchSelector */
226 class->changed = NULL;
227 class->set_model = _hildon_touch_selector_set_model;
229 class->has_multiple_selection = _hildon_touch_selector_has_multiple_selection;
233 * HildonTouchSelector::changed:
234 * @widget: the object which received the signal
235 * @column: the concrete column being modified
237 * The ::changed signal is emitted when the active item on any column is changed.
238 * This can be due to the user selecting a different item from the list, or
239 * due to a call to hildon_touch_selector_select_iter() on one of the columns.
242 hildon_touch_selector_signals[CHANGED] =
243 g_signal_new ("changed",
244 G_OBJECT_CLASS_TYPE (class),
246 G_STRUCT_OFFSET (HildonTouchSelectorClass, changed),
248 g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
251 * HildonTouchSelector::columns-changed:
252 * @selector: the object which received the signal
254 * The ::columns-changed signal is emitted when the number
255 * of columns in the #HildonTouchSelector change.
258 hildon_touch_selector_signals[COLUMNS_CHANGED] =
259 g_signal_new ("columns-changed",
260 G_OBJECT_CLASS_TYPE (class),
261 G_SIGNAL_RUN_LAST, 0,
263 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
267 g_object_class_install_property (gobject_class, PROP_HAS_MULTIPLE_SELECTION,
268 g_param_spec_boolean ("has-multiple-selection",
269 "has multiple selection",
270 "Whether the widget has multiple "
271 "selection (like multiple columns, "
272 "multiselection mode, or multiple "
273 "internal widgets) and therefore "
274 "it may need a confirmation button, "
279 g_object_class_install_property (G_OBJECT_CLASS (gobject_class),
281 g_param_spec_boolean ("initial-scroll",
283 "Whether to scroll to the"
284 "current selection when"
285 "the selector is first"
288 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
290 /* style properties */
291 /* We need to ensure fremantle mode for the treeview in order to work
292 properly. This is not about the appearance, this is about behaviour */
293 gtk_rc_parse_string ("style \"fremantle-htst\" {\n"
294 " GtkWidget::hildon-mode = 1\n"
295 "} widget \"*.fremantle-htst\" style \"fremantle-htst\""
296 "widget_class \"*<HildonPannableArea>.GtkTreeView\" style :highest \"fremantle-htst\"");
298 g_type_class_add_private (object_class, sizeof (HildonTouchSelectorPrivate));
302 hildon_touch_selector_get_property (GObject * object,
304 GValue * value, GParamSpec * pspec)
306 HildonTouchSelectorPrivate *priv = HILDON_TOUCH_SELECTOR (object)->priv;
309 case PROP_HAS_MULTIPLE_SELECTION:
310 g_value_set_boolean (value,
311 hildon_touch_selector_has_multiple_selection (HILDON_TOUCH_SELECTOR (object)));
313 case PROP_INITIAL_SCROLL:
314 g_value_set_boolean (value, priv->initial_scroll);
317 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
323 hildon_touch_selector_set_property (GObject *object, guint prop_id,
324 const GValue *value, GParamSpec *pspec)
326 HildonTouchSelectorPrivate *priv = HILDON_TOUCH_SELECTOR (object)->priv;
329 case PROP_INITIAL_SCROLL:
330 priv->initial_scroll = g_value_get_boolean (value);
333 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
340 hildon_touch_selector_init (HildonTouchSelector * selector)
342 selector->priv = HILDON_TOUCH_SELECTOR_GET_PRIVATE (selector);
344 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (selector), GTK_NO_WINDOW);
345 gtk_widget_set_redraw_on_allocate (GTK_WIDGET (selector), FALSE);
347 selector->priv->columns = NULL;
349 selector->priv->print_func = NULL;
350 selector->priv->initial_scroll = TRUE;
351 selector->priv->hbox = gtk_hbox_new (FALSE, 0);
353 gtk_box_pack_end (GTK_BOX (selector), selector->priv->hbox,
355 gtk_widget_show (selector->priv->hbox);
359 * IMPLEMENTATION NOTES:
360 * Some people sent questions regarding a missing dispose/finalize function on
361 * this widget that could lead to leak memory, so we will clarify this topic.
363 * This is not required as #HildonTouchSelector extends #GtkContainer. When the
364 * widget is freed, the #GtkContainer freeing memory functions are called. This
365 * process includes remove each widget individually, so all the widgets are
368 * In the same way, this widget redefines gtk_container->remove function, in
369 * order to free the column related information if it is required.
371 * Please take a look to hildon_touch_selector_remove for more information.
374 /*------------------------------ GtkContainer ------------------------------ */
377 * Required in order to free the column at the columns list
380 hildon_touch_selector_remove (GtkContainer * container, GtkWidget * widget)
382 HildonTouchSelector *selector = NULL;
384 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (container));
385 selector = HILDON_TOUCH_SELECTOR (container);
387 /* Remove the extra data related to the columns, if required. */
388 if (widget == selector->priv->hbox) {
389 g_slist_foreach (selector->priv->columns, (GFunc) g_object_unref, NULL);
391 g_slist_free (selector->priv->columns);
393 selector->priv->columns = NULL;
395 g_debug ("Freeing a widget outside the columns logic");
398 /* Now remove the widget itself from the container */
399 GTK_CONTAINER_CLASS (hildon_touch_selector_parent_class)->remove (container, widget);
402 /* ------------------------------ PRIVATE METHODS ---------------------------- */
404 * default_print_func:
405 * @selector: a #HildonTouchSelector
407 * Default print function
409 * Returns: a new string that represents the selected items
414 _default_print_func (HildonTouchSelector * selector)
416 gchar *result = NULL;
418 gint num_columns = 0;
420 GtkTreeModel *model = NULL;
421 gchar *current_string = NULL;
423 HildonTouchSelectorSelectionMode mode;
425 GtkTreePath *current_path = NULL;
426 GList *selected_rows = NULL;
427 gint initial_value = 0;
428 gint text_column = -1;
429 HildonTouchSelectorColumn *column = NULL;
431 num_columns = hildon_touch_selector_get_num_columns (selector);
433 mode = hildon_touch_selector_get_column_selection_mode (selector);
435 if ((mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE)
436 && (num_columns > 0)) {
437 /* In this case we get the first column first */
438 selected_rows = hildon_touch_selector_get_selected_rows (selector, 0);
439 model = hildon_touch_selector_get_model (selector, 0);
440 column = hildon_touch_selector_get_column (selector, 0);
441 g_object_get (G_OBJECT(column), "text-column", &text_column, NULL);
443 result = g_strdup_printf ("(");
445 for (item = selected_rows; item; item = g_list_next (item)) {
446 current_path = item->data;
447 gtk_tree_model_get_iter (model, &iter, current_path);
449 if (text_column != -1) {
450 gtk_tree_model_get (model, &iter, text_column, ¤t_string, -1);
453 if (i < g_list_length (selected_rows) - 1) {
454 aux = g_strconcat (result, current_string, ",", NULL);
458 aux = g_strconcat (result, current_string, NULL);
463 if (current_string) {
464 g_free (current_string);
465 current_string = NULL;
471 aux = g_strconcat (result, ")", NULL);
475 g_list_foreach (selected_rows, (GFunc) (gtk_tree_path_free), NULL);
476 g_list_free (selected_rows);
482 for (i = initial_value; i < num_columns; i++) {
483 model = hildon_touch_selector_get_model (selector, i);
484 column = hildon_touch_selector_get_column (selector, i);
485 g_object_get (G_OBJECT(column), "text-column", &text_column, NULL);
487 if (hildon_touch_selector_get_selected (selector, i, &iter)) {
488 if (text_column == -1 ) {
489 g_warning ("Trying to use the default print function in HildonTouchSelector, but "
490 "\"text-column\" property is not set for HildonTouchSelectorColumn %p.", column);
491 current_string = NULL;
493 gtk_tree_model_get (model, &iter, text_column, ¤t_string, -1);
497 aux = g_strconcat (result, ":", current_string, NULL);
501 result = current_string;
510 _selection_changed_cb (GtkTreeSelection * selection, gpointer user_data)
512 HildonTouchSelector *selector = NULL;
513 HildonTouchSelectorColumn *column = NULL;
514 gint num_column = -1;
516 column = HILDON_TOUCH_SELECTOR_COLUMN (user_data);
517 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (column->priv->parent));
519 selector = column->priv->parent;
521 num_column = g_slist_index (selector->priv->columns, column);
523 g_signal_emit (selector, hildon_touch_selector_signals[CHANGED], 0, num_column);
527 static HildonTouchSelectorColumn *
528 _create_new_column (HildonTouchSelector * selector,
529 GtkTreeModel * model,
530 GtkCellRenderer * renderer, va_list args)
532 HildonTouchSelectorColumn *new_column = NULL;
533 GtkTreeViewColumn *tree_column = NULL;
534 GtkTreeView *tv = NULL;
535 GtkWidget *panarea = NULL;
536 GtkTreeSelection *selection = NULL;
541 tree_column = gtk_tree_view_column_new ();
543 if (renderer != NULL) {
544 gtk_tree_view_column_pack_start (tree_column, renderer, TRUE);
546 attribute = va_arg (args, gchar *);
547 while (attribute != NULL) {
548 value = va_arg (args, gint);
549 gtk_tree_view_column_add_attribute (tree_column, renderer, attribute,
551 attribute = va_arg (args, gchar *);
556 tv = GTK_TREE_VIEW (hildon_gtk_tree_view_new (HILDON_UI_MODE_EDIT));
558 tv = GTK_TREE_VIEW (gtk_tree_view_new ());
559 #endif /* MAEMO_GTK */
561 gtk_tree_view_set_enable_search (tv, FALSE);
563 gtk_tree_view_set_model (tv, model);
564 gtk_tree_view_set_rules_hint (tv, TRUE);
566 gtk_tree_view_append_column (GTK_TREE_VIEW (tv), tree_column);
568 new_column = g_object_new (HILDON_TYPE_TOUCH_SELECTOR_COLUMN, NULL);
569 new_column->priv->parent = selector;
571 panarea = hildon_pannable_area_new ();
573 g_object_set (G_OBJECT (panarea),
574 "initial-hint", FALSE, NULL);
576 gtk_container_add (GTK_CONTAINER (panarea), GTK_WIDGET (tv));
578 new_column->priv->model = model;
579 new_column->priv->tree_view = tv;
580 new_column->priv->panarea = panarea;
582 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
583 gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
585 /* select the first item */
586 if (gtk_tree_model_get_iter_first (model, &iter)) {
587 gtk_tree_selection_select_iter (selection, &iter);
590 gtk_widget_grab_focus (GTK_WIDGET (tv));
592 /* connect to the changed signal connection */
593 g_signal_connect (G_OBJECT (selection), "changed",
594 G_CALLBACK (_selection_changed_cb), new_column);
596 g_signal_connect_after (G_OBJECT (panarea), "realize",
597 G_CALLBACK (_hildon_touch_selector_center_on_selected_items),
604 /* ------------------------ HildonTouchSelectorColumn implementation ---------------------- */
605 G_DEFINE_TYPE_WITH_CODE (HildonTouchSelectorColumn, hildon_touch_selector_column, G_TYPE_OBJECT,
606 G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
607 hildon_touch_selector_column_cell_layout_init))
615 hildon_touch_selector_column_class_init (HildonTouchSelectorColumnClass *klass);
618 hildon_touch_selector_column_get_property (GObject *object, guint property_id,
619 GValue *value, GParamSpec *pspec);
622 hildon_touch_selector_column_set_property (GObject *object, guint property_id,
623 const GValue *value, GParamSpec *pspec);
626 hildon_touch_selector_column_set_text_column (HildonTouchSelectorColumn *column,
629 hildon_touch_selector_column_get_text_column (HildonTouchSelectorColumn *column);
633 hildon_touch_selector_column_class_init (HildonTouchSelectorColumnClass *klass)
635 GObjectClass *gobject_class = NULL;
637 gobject_class = G_OBJECT_CLASS (klass);
639 g_type_class_add_private (gobject_class, sizeof (HildonTouchSelectorColumnPrivate));
642 gobject_class->get_property = hildon_touch_selector_column_get_property;
643 gobject_class->set_property = hildon_touch_selector_column_set_property;
645 g_object_class_install_property (G_OBJECT_CLASS(klass),
647 g_param_spec_int ("text-column",
649 "A column in the data source model to get the strings from.",
657 hildon_touch_selector_column_init (HildonTouchSelectorColumn *column)
659 column->priv = G_TYPE_INSTANCE_GET_PRIVATE (column, HILDON_TYPE_TOUCH_SELECTOR_COLUMN,
660 HildonTouchSelectorColumnPrivate);
661 column->priv->text_column = -1;
665 hildon_touch_selector_column_set_text_column (HildonTouchSelectorColumn *column,
668 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (column));
669 g_return_if_fail (text_column >= -1);
671 column->priv->text_column = text_column;
673 g_object_notify (G_OBJECT (column), "text-column");
677 hildon_touch_selector_column_get_text_column (HildonTouchSelectorColumn *column)
679 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (column), -1);
681 return column->priv->text_column;
685 hildon_touch_selector_column_get_property (GObject *object, guint property_id,
686 GValue *value, GParamSpec *pspec)
688 switch (property_id) {
689 case PROP_TEXT_COLUMN:
690 g_value_set_int (value,
691 hildon_touch_selector_column_get_text_column (HILDON_TOUCH_SELECTOR_COLUMN (object)));
694 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
699 hildon_touch_selector_column_set_property (GObject *object, guint property_id,
700 const GValue *value, GParamSpec *pspec)
702 switch (property_id) {
703 case PROP_TEXT_COLUMN:
704 hildon_touch_selector_column_set_text_column (HILDON_TOUCH_SELECTOR_COLUMN (object),
705 g_value_get_int (value));
708 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
712 /* ------------------------ GtkCellLayout implementation -------------------- */
714 hildon_touch_selector_column_cell_layout_init (GtkCellLayoutIface *iface)
716 iface->pack_start = hildon_touch_selector_column_cell_layout_pack_start;
717 iface->pack_end = hildon_touch_selector_column_cell_layout_pack_end;
718 iface->clear = hildon_touch_selector_column_cell_layout_clear;
719 iface->add_attribute = hildon_touch_selector_column_cell_layout_add_attribute;
720 iface->set_cell_data_func = hildon_touch_selector_column_cell_layout_set_cell_data_func;
721 iface->clear_attributes = hildon_touch_selector_column_cell_layout_clear_attributes;
722 iface->reorder = hildon_touch_selector_column_cell_layout_reorder;
723 iface->get_cells = hildon_touch_selector_column_cell_layout_get_cells;
727 hildon_touch_selector_column_cell_layout_pack_start (GtkCellLayout *cell_layout,
728 GtkCellRenderer *cell,
731 HildonTouchSelectorColumn *sel_column = NULL;
732 GtkTreeViewColumn *view_column = NULL;
734 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
735 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
737 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
739 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(view_column), cell, expand);
744 hildon_touch_selector_column_cell_layout_pack_end (GtkCellLayout *cell_layout,
745 GtkCellRenderer *cell,
748 HildonTouchSelectorColumn *sel_column = NULL;
749 GtkTreeViewColumn *view_column = NULL;
751 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
752 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
754 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
756 gtk_cell_layout_pack_end (GTK_CELL_LAYOUT(view_column), cell, expand);
760 hildon_touch_selector_column_cell_layout_clear (GtkCellLayout *cell_layout)
762 HildonTouchSelectorColumn *sel_column = NULL;
763 GtkTreeViewColumn *view_column = NULL;
765 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
766 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
768 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
770 gtk_cell_layout_clear (GTK_CELL_LAYOUT(view_column));
774 hildon_touch_selector_column_cell_layout_add_attribute (GtkCellLayout *cell_layout,
775 GtkCellRenderer *cell,
776 const gchar *attribute,
779 HildonTouchSelectorColumn *sel_column = NULL;
780 GtkTreeViewColumn *view_column = NULL;
782 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
783 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
785 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
787 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(view_column), cell, attribute, column);
792 hildon_touch_selector_column_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout,
793 GtkCellRenderer *cell,
794 GtkCellLayoutDataFunc func,
796 GDestroyNotify destroy)
798 HildonTouchSelectorColumn *sel_column = NULL;
799 GtkTreeViewColumn *view_column = NULL;
801 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
802 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
804 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
806 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT(view_column), cell, func,
811 hildon_touch_selector_column_cell_layout_clear_attributes (GtkCellLayout *cell_layout,
812 GtkCellRenderer *cell)
814 HildonTouchSelectorColumn *sel_column = NULL;
815 GtkTreeViewColumn *view_column = NULL;
817 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
818 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
820 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
822 gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (view_column), cell);
826 hildon_touch_selector_column_cell_layout_reorder (GtkCellLayout *cell_layout,
827 GtkCellRenderer *cell,
830 HildonTouchSelectorColumn *sel_column = NULL;
831 GtkTreeViewColumn *view_column = NULL;
833 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout));
834 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
836 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
838 gtk_cell_layout_reorder (GTK_CELL_LAYOUT(view_column), cell, position);
842 hildon_touch_selector_column_cell_layout_get_cells (GtkCellLayout *cell_layout)
844 HildonTouchSelectorColumn *sel_column = NULL;
845 GtkTreeViewColumn *view_column = NULL;
847 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (cell_layout), NULL);
848 sel_column = HILDON_TOUCH_SELECTOR_COLUMN (cell_layout);
850 view_column = gtk_tree_view_get_column (sel_column->priv->tree_view, 0);
852 return gtk_cell_layout_get_cells (GTK_CELL_LAYOUT(view_column));
855 /* ------------------------------ PUBLIC METHODS ---------------------------- */
858 * hildon_touch_selector_new:
860 * Creates a new empty #HildonTouchSelector.
862 * Returns: a new #HildonTouchSelector.
867 hildon_touch_selector_new (void)
869 return g_object_new (HILDON_TYPE_TOUCH_SELECTOR, NULL);
873 * hildon_touch_selector_new_text:
875 * Creates a #HildonTouchSelector with a single text column that
876 * can be populated conveniently through hildon_touch_selector_append_text(),
877 * hildon_touch_selector_prepend_text(), hildon_touch_selector_insert_text().
879 * Returns: A new #HildonTouchSelector
884 hildon_touch_selector_new_text (void)
888 HildonTouchSelectorColumn *column = NULL;
890 selector = hildon_touch_selector_new ();
891 store = gtk_list_store_new (1, G_TYPE_STRING);
893 column = hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
894 GTK_TREE_MODEL (store), TRUE);
896 g_object_set (G_OBJECT (column), "text-column", 0, NULL);
902 * hildon_touch_selector_append_text:
903 * @selector: A #HildonTouchSelector.
904 * @text: a non %NULL text string.
906 * Appends a new entry in a #HildonTouchSelector created with
907 * hildon_touch_selector_new_text().
912 hildon_touch_selector_append_text (HildonTouchSelector * selector,
918 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
919 g_return_if_fail (text != NULL);
921 model = hildon_touch_selector_get_model (HILDON_TOUCH_SELECTOR (selector), 0);
923 g_return_if_fail (GTK_IS_LIST_STORE (model));
925 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
926 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, text, -1);
930 * hildon_touch_selector_prepend_text:
931 * @selector: A #HildonTouchSelector.
932 * @text: a non %NULL text string.
934 * Prepends a new entry in a #HildonTouchSelector created with
935 * hildon_touch_selector_new_text().
940 hildon_touch_selector_prepend_text (HildonTouchSelector * selector,
946 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
947 g_return_if_fail (text != NULL);
949 model = hildon_touch_selector_get_model (HILDON_TOUCH_SELECTOR (selector), 0);
951 g_return_if_fail (GTK_IS_LIST_STORE (model));
953 gtk_list_store_prepend (GTK_LIST_STORE (model), &iter);
954 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, text, -1);
958 * hildon_touch_selector_insert_text:
959 * @selector: a #HildonTouchSelector.
960 * @position: the position to insert @text.
961 * @text: A non %NULL text string.
963 * Inserts a new entry in particular position of a #HildoTouchSelector created
964 * with hildon_touch_selector_new_text().
969 hildon_touch_selector_insert_text (HildonTouchSelector * selector,
970 gint position, const gchar * text)
975 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
976 g_return_if_fail (text != NULL);
977 g_return_if_fail (position >= 0);
979 model = hildon_touch_selector_get_model (HILDON_TOUCH_SELECTOR (selector), 0);
981 g_return_if_fail (GTK_IS_LIST_STORE (model));
983 gtk_list_store_insert (GTK_LIST_STORE (model), &iter, position);
984 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, text, -1);
988 * hildon_touch_selector_append_column
989 * @selector: a #HildonTouchSelector
990 * @model: the #GtkTreeModel with the data of the column
991 * @cell_renderer: The #GtkCellRenderer where to draw each row contents.
992 * @Varargs: a %NULL-terminated pair of attributes and column numbers.
994 * This functions adds a new column to the widget, whose data will
995 * be obtained from the model. Only widgets added this way should used on
996 * the selection logic, i.e., the print function, the #HildonTouchPicker::changed
999 * You can optionally pass a #GtkCellRenderer in @cell_renderer,
1000 * together with a %NULL-terminated list of pairs property/value, in
1001 * the same way you would use gtk_tree_view_column_set_attributes().
1002 * This will pack @cell_renderer at the start of the column, expanded by default.
1003 * If you prefer not to add it this way, you can simply pass %NULL to @cell_renderer
1004 * and use the #GtkCellLayout interface on the returned #HildonTouchSelectorColumn
1005 * to set your renderers.
1007 * There is a prerequisite to be considered on models used: text data must
1008 * be in the first column.
1010 * This method basically adds a #GtkTreeView to the widget, using the model and
1011 * the data received.
1013 * Returns: the new column added added, %NULL otherwise.
1018 HildonTouchSelectorColumn*
1019 hildon_touch_selector_append_column (HildonTouchSelector * selector,
1020 GtkTreeModel * model,
1021 GtkCellRenderer * cell_renderer, ...)
1024 HildonTouchSelectorColumn *new_column = NULL;
1026 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1027 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
1029 if (model != NULL) {
1031 va_start (args, cell_renderer);
1032 new_column = _create_new_column (selector, model, cell_renderer, args);
1035 selector->priv->columns = g_slist_append (selector->priv->columns,
1037 gtk_box_pack_start (GTK_BOX (selector->priv->hbox),
1038 new_column->priv->panarea,
1041 gtk_widget_show_all (new_column->priv->panarea);
1046 g_signal_emit (selector, hildon_touch_selector_signals[COLUMNS_CHANGED], 0);
1052 * hildon_touch_selector_append_text_column
1053 * @selector: a #HildonTouchSelector
1054 * @model: a #GtkTreeModel with data for the column
1055 * @center: whether to center the text on the column
1057 * Equivalent to hildon_touch_selector_append_column(), but using a
1058 * default text cell renderer. This is the most common use case of the
1061 * Returns: the new column added, NULL otherwise.
1065 HildonTouchSelectorColumn*
1066 hildon_touch_selector_append_text_column (HildonTouchSelector * selector,
1067 GtkTreeModel * model, gboolean center)
1069 GtkCellRenderer *renderer = NULL;
1070 GValue val = { 0, };
1072 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1073 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
1075 if (model != NULL) {
1076 renderer = gtk_cell_renderer_text_new ();
1079 g_value_init (&val, G_TYPE_FLOAT);
1080 g_value_set_float (&val, 0.5);
1081 g_object_set_property (G_OBJECT (renderer), "xalign", &val);
1084 return hildon_touch_selector_append_column (selector, model, renderer,
1092 * hildon_touch_selector_remove_column:
1093 * @selector: a #HildonTouchSelector
1094 * @column: the position of the column to be removed
1096 * Removes a column from @selector.
1098 * Returns: %TRUE if the column was removed, %FALSE otherwise
1103 hildon_touch_selector_remove_column (HildonTouchSelector * selector, gint column)
1105 HildonTouchSelectorColumn *current_column = NULL;
1106 HildonTouchSelectorPrivate *priv;
1108 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
1109 g_return_val_if_fail (column <
1110 hildon_touch_selector_get_num_columns (selector), FALSE);
1112 priv = HILDON_TOUCH_SELECTOR_GET_PRIVATE (selector);
1113 current_column = g_slist_nth_data (priv->columns, column);
1115 gtk_container_remove (GTK_CONTAINER (priv->hbox), current_column->priv->panarea);
1116 priv->columns = g_slist_remove (priv->columns, current_column);
1117 g_object_unref (current_column);
1119 g_signal_emit (selector, hildon_touch_selector_signals[COLUMNS_CHANGED], 0);
1125 * hildon_touch_selector_set_column_attributes:
1126 * @selector: a #HildonTouchSelector
1127 * @num_column: the number of the column whose attributes we're setting
1128 * @cell_renderer: the #GtkCellRendere we're setting the attributes of
1129 * @Varargs: A %NULL-terminated list of attributes.
1131 * Sets the attributes for the given column. The attributes must be given
1132 * in attribute/column pairs, just like in gtk_tree_view_column_set_attributes().
1133 * All existing attributes are removed and replaced with the new ones.
1135 * Deprecated: #HildonTouchSelectorColumn implements #GtkCellLayout, use this
1136 * interface instead. See
1137 * hildon_touch_selector_get_column().
1142 hildon_touch_selector_set_column_attributes (HildonTouchSelector * selector,
1144 GtkCellRenderer * cell_renderer,
1148 GtkTreeViewColumn *tree_column = NULL;
1149 HildonTouchSelectorColumn *current_column = NULL;
1150 gchar *attribute = NULL;
1153 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1154 g_return_if_fail (num_column <
1155 hildon_touch_selector_get_num_columns (selector));
1157 current_column = g_slist_nth_data (selector->priv->columns, num_column);
1159 tree_column = gtk_tree_view_get_column (current_column->priv->tree_view, 0);
1160 gtk_tree_view_remove_column (current_column->priv->tree_view, tree_column);
1162 tree_column = gtk_tree_view_column_new ();
1163 gtk_tree_view_column_pack_start (tree_column, cell_renderer, TRUE);
1165 va_start (args, cell_renderer);
1166 attribute = va_arg (args, gchar *);
1168 gtk_tree_view_column_clear_attributes (tree_column, cell_renderer);
1170 while (attribute != NULL) {
1171 value = va_arg (args, gint);
1172 gtk_tree_view_column_add_attribute (tree_column, cell_renderer,
1174 attribute = va_arg (args, gchar *);
1179 gtk_tree_view_append_column (current_column->priv->tree_view, tree_column);
1183 * hildon_touch_selector_get_num_columns:
1184 * @selector: a #HildonTouchSelector
1186 * Gets the number of columns in the #HildonTouchSelector.
1188 * Returns: the number of columns in @selector.
1193 hildon_touch_selector_get_num_columns (HildonTouchSelector * selector)
1195 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), -1);
1197 return g_slist_length (selector->priv->columns);
1201 * hildon_touch_selector_get_column_selection_mode:
1202 * @selector: a #HildonTouchSelector
1204 * Gets the selection mode of @selector.
1206 * Returns: one of #HildonTouchSelectorSelectionMode
1210 HildonTouchSelectorSelectionMode
1211 hildon_touch_selector_get_column_selection_mode (HildonTouchSelector * selector)
1213 HildonTouchSelectorSelectionMode result =
1214 HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE;
1215 GtkSelectionMode treeview_mode = GTK_SELECTION_BROWSE;
1216 HildonTouchSelectorColumn *column = NULL;
1217 GtkTreeSelection *selection = NULL;
1219 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), result);
1220 g_return_val_if_fail (hildon_touch_selector_get_num_columns (selector) > 0,
1223 column = HILDON_TOUCH_SELECTOR_COLUMN (selector->priv->columns->data);
1225 selection = gtk_tree_view_get_selection (column->priv->tree_view);
1226 treeview_mode = gtk_tree_selection_get_mode (selection);
1229 if (treeview_mode == GTK_SELECTION_MULTIPLE) {
1230 result = HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE;
1232 result = HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE;
1239 * hildon_touch_selector_set_column_selection_mode:
1240 * @selector: a #HildonTouchSelector
1241 * @mode: the #HildonTouchSelectorMode for @selector
1243 * Sets the selection mode for @selector. See #HildonTouchSelectorSelectionMode.
1248 hildon_touch_selector_set_column_selection_mode (HildonTouchSelector * selector,
1249 HildonTouchSelectorSelectionMode mode)
1251 GtkTreeView *tv = NULL;
1252 HildonTouchSelectorColumn *column = NULL;
1253 GtkTreeSelection *selection = NULL;
1254 GtkSelectionMode treeview_mode = GTK_SELECTION_MULTIPLE;
1256 HildonTouchSelectorSelectionMode current_mode;
1258 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1259 g_return_if_fail (hildon_touch_selector_get_num_columns (selector) > 0);
1261 current_mode = hildon_touch_selector_get_column_selection_mode (selector);
1263 if (current_mode == mode) {
1267 column = HILDON_TOUCH_SELECTOR_COLUMN ((g_slist_nth (selector->priv->columns, 0))->data);
1268 tv = column->priv->tree_view;
1272 case HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE:
1273 treeview_mode = GTK_SELECTION_BROWSE;
1275 case HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE:
1276 treeview_mode = GTK_SELECTION_MULTIPLE;
1280 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
1281 gtk_tree_selection_set_mode (selection, treeview_mode);
1283 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
1284 gtk_tree_model_get_iter_first (column->priv->model, &iter);
1285 gtk_tree_selection_unselect_all (selection);
1286 gtk_tree_selection_select_iter (selection, &iter);
1292 * hildon_touch_selector_set_print_func:
1293 * @selector: a #HildonTouchSelector
1294 * @func: a #HildonTouchSelectorPrintFunc function
1296 * Sets the function to be used by hildon_touch_selector_get_current_text()
1297 * to produce a text representation of the currently selected items in @selector.
1298 * The default function will return a concatenation of comma separated items
1299 * selected in each column in @selector. Use this to override this method if you
1300 * need a particular representation for your application.
1305 hildon_touch_selector_set_print_func (HildonTouchSelector * selector,
1306 HildonTouchSelectorPrintFunc func)
1308 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1310 selector->priv->print_func = func;
1314 * hildon_touch_selector_get_print_func:
1315 * @selector: a #HildonTouchSelector
1317 * Gets the #HildonTouchSelectorPrintFunc currently used. See
1318 * hildon_touch_selector_set_print_func().
1320 * Returns: a #HildonTouchSelectorPrintFunc or %NULL if the default
1321 * one is currently used.
1323 HildonTouchSelectorPrintFunc
1324 hildon_touch_selector_get_print_func (HildonTouchSelector * selector)
1326 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1328 return selector->priv->print_func;
1332 * hildon_touch_selector_set_active:
1333 * @selector: a #HildonTouchSelector
1334 * @column: column number
1335 * @index: the index of the item to select, or -1 to have no active item
1337 * Sets the active item of the #HildonTouchSelector to @index. The
1338 * column number is taken from @column.
1340 * @selector must be in %HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE
1345 hildon_touch_selector_set_active (HildonTouchSelector *selector,
1349 GtkTreeSelection *selection = NULL;
1350 HildonTouchSelectorColumn *current_column = NULL;
1351 HildonTouchSelectorSelectionMode mode;
1354 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1355 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
1356 mode = hildon_touch_selector_get_column_selection_mode (selector);
1357 g_return_if_fail (mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE);
1359 current_column = g_slist_nth_data (selector->priv->columns, column);
1361 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (current_column->priv->tree_view));
1362 path = gtk_tree_path_new_from_indices (index, -1);
1363 gtk_tree_selection_unselect_all (selection);
1365 gtk_tree_selection_select_path (selection, path);
1367 gtk_tree_path_free (path);
1371 * hildon_touch_selector_get_active:
1372 * @selector: a #HildonTouchSelector
1373 * @column: column number
1375 * Returns the index of the currently active item in column number
1376 * @column, or -1 if there's no active item.
1378 * @selector must be in %HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE
1380 * Returns: an integer which is the index of the currently active
1381 * item, or -1 if there's no active item.
1386 hildon_touch_selector_get_active (HildonTouchSelector *selector,
1389 GtkTreeSelection *selection = NULL;
1390 HildonTouchSelectorColumn *current_column = NULL;
1391 HildonTouchSelectorSelectionMode mode;
1392 GtkTreeModel *model;
1397 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), -1);
1398 g_return_val_if_fail (column < hildon_touch_selector_get_num_columns (selector), -1);
1399 mode = hildon_touch_selector_get_column_selection_mode (selector);
1400 g_return_val_if_fail (mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE, -1);
1402 current_column = g_slist_nth_data (selector->priv->columns, column);
1404 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (current_column->priv->tree_view));
1405 model = gtk_tree_view_get_model (GTK_TREE_VIEW (current_column->priv->tree_view));
1407 gtk_tree_selection_get_selected (selection, NULL, &iter);
1408 path = gtk_tree_model_get_path (model, &iter);
1409 index = (gtk_tree_path_get_indices (path))[0];
1411 gtk_tree_path_free (path);
1417 * hildon_touch_selector_get_selected:
1418 * @selector: a #HildonTouchSelector
1419 * @column: the column number we want to get the element
1420 * @iter: #GtkTreeIter currently selected
1422 * Sets @iter to the currently selected node on the nth-column, if selection is
1423 * set to %HILDON_TOUCH_SELECTOR_SINGLE or %HILDON_TOUCH_SELECTOR_MULTIPLE with
1424 * a column different that the first one. @iter may be %NULL if you just want to
1425 * test if selection has any selected items.
1427 * This function will not work if selection is in
1428 * %HILDON_TOUCH_SELECTOR_MULTIPLE mode and the column is the first one.
1430 * See gtk_tree_selection_get_selected() for more information.
1432 * Returns: %TRUE if @iter was correctly set, %FALSE otherwise
1437 hildon_touch_selector_get_selected (HildonTouchSelector * selector,
1438 gint column, GtkTreeIter * iter)
1440 GtkTreeSelection *selection = NULL;
1441 HildonTouchSelectorColumn *current_column = NULL;
1442 HildonTouchSelectorSelectionMode mode;
1444 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
1445 g_return_val_if_fail (column < hildon_touch_selector_get_num_columns (selector),
1447 mode = hildon_touch_selector_get_column_selection_mode (selector);
1448 g_return_val_if_fail
1449 ((mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE) ||
1450 ((mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE)&&(column>0)),
1453 current_column = g_slist_nth_data (selector->priv->columns, column);
1456 gtk_tree_view_get_selection (GTK_TREE_VIEW (current_column->priv->tree_view));
1458 return gtk_tree_selection_get_selected (selection, NULL, iter);
1462 * hildon_touch_selector_select_iter
1463 * @selector: a #HildonTouchSelector
1464 * @column: the column to selects
1465 * @iter: the #GtkTreeIter to be selected
1466 * @scroll_to: whether to smoothly scroll to the item
1468 * Sets the currently selected item in the column @column to the one pointed by @iter,
1469 * optionally smoothly scrolling to it.
1474 hildon_touch_selector_select_iter (HildonTouchSelector * selector,
1475 gint column, GtkTreeIter * iter,
1479 GtkTreeModel *model;
1481 HildonTouchSelectorColumn *current_column = NULL;
1482 GtkTreeView *tv = NULL;
1483 GtkTreeSelection *selection = NULL;
1486 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1487 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
1489 current_column = g_slist_nth_data (selector->priv->columns, column);
1491 tv = current_column->priv->tree_view;
1492 selection = gtk_tree_view_get_selection (tv);
1493 model = gtk_tree_view_get_model (tv);
1494 path = gtk_tree_model_get_path (model, iter);
1496 gtk_tree_selection_select_iter (selection, iter);
1499 gtk_tree_view_get_background_area (tv,
1501 gtk_tree_view_convert_bin_window_to_tree_coords (tv,
1502 0, rect.y, NULL, &y);
1503 hildon_pannable_area_scroll_to (HILDON_PANNABLE_AREA (current_column->priv->panarea),
1506 gtk_tree_path_free (path);
1510 * hildon_touch_selector_unselect_iter
1511 * @selector: a #HildonTouchSelector
1512 * @column: the column to unselects from
1513 * @iter: the #GtkTreeIter to be unselected
1515 * Unselect the item pointed by @iter in the column @column
1520 void hildon_touch_selector_unselect_iter (HildonTouchSelector * selector,
1524 HildonTouchSelectorColumn *current_column = NULL;
1525 GtkTreeSelection *selection = NULL;
1527 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
1528 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
1530 current_column = g_slist_nth_data (selector->priv->columns, column);
1531 selection = gtk_tree_view_get_selection (current_column->priv->tree_view);
1532 gtk_tree_selection_unselect_iter (selection, iter);
1536 * hildon_touch_selector_get_selected_rows:
1537 * @selector: a #HildonTouchSelector
1538 * @column: the position of the column to get the selected rows from
1540 * Creates a list of #GtkTreePath<!-- -->s of all selected rows in a column. Additionally,
1541 * if you to plan to modify the model after calling this function, you may
1542 * want to convert the returned list into a list of GtkTreeRowReferences. To do this,
1543 * you can use gtk_tree_row_reference_new().
1545 * See gtk_tree_selection_get_selected_rows() for more information.
1547 * Returns: A new #GList containing a #GtkTreePath for each selected row in the column @column.
1552 hildon_touch_selector_get_selected_rows (HildonTouchSelector * selector,
1555 GList *result = NULL;
1556 HildonTouchSelectorColumn *current_column = NULL;
1557 GtkTreeSelection *selection = NULL;
1559 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1560 g_return_val_if_fail (column < hildon_touch_selector_get_num_columns (selector),
1563 current_column = g_slist_nth_data (selector->priv->columns, column);
1564 selection = gtk_tree_view_get_selection (current_column->priv->tree_view);
1566 result = gtk_tree_selection_get_selected_rows (selection, NULL);
1572 * hildon_touch_selector_get_model:
1573 * @selector: a #HildonTouchSelector
1574 * @column: the position of the column in @selector
1576 * Gets the model of a column of @selector.
1578 * Returns: the #GtkTreeModel for the column @column of @selector.
1583 hildon_touch_selector_get_model (HildonTouchSelector * selector, gint column)
1585 HildonTouchSelectorColumn *current_column = NULL;
1587 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1588 g_return_val_if_fail (column < hildon_touch_selector_get_num_columns (selector),
1591 current_column = g_slist_nth_data (selector->priv->columns, column);
1593 return current_column->priv->model;
1597 _hildon_touch_selector_set_model (HildonTouchSelector * selector,
1598 gint column, GtkTreeModel * model)
1600 HildonTouchSelectorColumn *current_column = NULL;
1603 HILDON_TOUCH_SELECTOR_COLUMN (g_slist_nth_data (selector->priv->columns, column));
1605 current_column->priv->model = model;
1606 gtk_tree_view_set_model (current_column->priv->tree_view,
1607 current_column->priv->model);
1611 * hildon_touch_selector_set_model:
1612 * @selector: a #HildonTouchSelector
1613 * @column: the position of the column to set the model to
1614 * @model: a #GtkTreeModel
1616 * Sets the #GtkTreeModel for a particular column in @model.
1621 hildon_touch_selector_set_model (HildonTouchSelector * selector,
1622 gint column, GtkTreeModel * model)
1624 g_return_if_fail (HILDON_TOUCH_SELECTOR (selector));
1625 g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
1627 HILDON_TOUCH_SELECTOR_GET_CLASS (selector)->set_model (selector, column, model);
1631 * hildon_touch_selector_get_current_text:
1632 * @selector: a #HildonTouchSelector
1634 * Returns a string representing the currently selected items for
1635 * each column of @selector. See hildon_touch_selector_set_print_func().
1637 * Returns: a newly allocated string.
1642 hildon_touch_selector_get_current_text (HildonTouchSelector * selector)
1644 gchar *result = NULL;
1645 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1647 if (selector->priv->print_func) {
1648 result = (*selector->priv->print_func) (selector);
1650 result = _default_print_func (selector);
1657 _hildon_touch_selector_center_on_selected_items (GtkWidget *widget,
1660 HildonTouchSelector *selector = NULL;
1661 HildonTouchSelectorColumn *column = NULL;
1663 GtkTreePath *path = NULL;
1666 gint num_column = -1;
1667 HildonTouchSelectorSelectionMode selection_mode;
1669 column = HILDON_TOUCH_SELECTOR_COLUMN (data);
1670 selector = column->priv->parent;
1672 if (!selector->priv->initial_scroll) {
1675 selection_mode = hildon_touch_selector_get_column_selection_mode (selector);
1676 num_column = g_slist_index (selector->priv->columns, column);
1678 if ((num_column == 0)
1679 && (selection_mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE)) {
1684 if (hildon_touch_selector_get_selected (selector, num_column, &iter)) {
1685 path = gtk_tree_model_get_path (column->priv->model, &iter);
1686 gtk_tree_view_get_background_area (GTK_TREE_VIEW
1687 (column->priv->tree_view), path, NULL,
1690 gtk_tree_view_convert_bin_window_to_tree_coords (GTK_TREE_VIEW
1691 (column->priv->tree_view), 0,
1694 hildon_pannable_area_scroll_to (HILDON_PANNABLE_AREA
1695 (column->priv->panarea), -1, y);
1697 gtk_tree_path_free (path);
1704 _hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector)
1706 HildonTouchSelectorSelectionMode mode = HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE;
1709 n_columns = hildon_touch_selector_get_num_columns (selector);
1710 mode = hildon_touch_selector_get_column_selection_mode (selector);
1712 return ((n_columns > 1) || (mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE));
1716 * hildon_touch_selector_has_multiple_selection:
1717 * @selector: A #HildonTouchSelector
1719 * Determines whether @selector is complex enough to actually require an
1720 * extra selection step than only picking an item. This is normally %TRUE
1721 * if @selector has multiple columns, multiple selection, or when it is a
1722 * more complex widget, like #HildonTouchSelectorEntry.
1724 * This information is useful for widgets containing a #HildonTouchSelector,
1725 * like #HildonPickerDialog, that could need a "Done" button, in case that
1726 * its internal #HildonTouchSelector has multiple columns, for instance.
1728 * Returns: %TRUE if @selector requires multiple selection steps.
1733 hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector)
1735 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
1737 return HILDON_TOUCH_SELECTOR_GET_CLASS (selector)->has_multiple_selection (selector);
1742 * hildon_touch_selector_get_column:
1743 * @selector: A #HildonTouchSelector
1744 * @column: a column number
1746 * Use this method to retrieve a #HildonTouchSelectorColumn. Then, you can use
1747 * the #GtkCellLayout interface to set up the layout of the column.
1749 * Returns: the @column<!-- -->-th #HildonTouchSelectorColumn in @selector
1753 HildonTouchSelectorColumn *
1754 hildon_touch_selector_get_column (HildonTouchSelector * selector,
1757 gint num_columns = -1;
1759 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), NULL);
1760 num_columns = hildon_touch_selector_get_num_columns (selector);
1761 g_return_val_if_fail (column < num_columns && column >= 0, NULL);
1763 return g_slist_nth_data (selector->priv->columns, column);