2008-08-04 Claudio Saavedra <csaavedra@igalia.com>
[hildon] / src / hildon-touch-selector.c
index 844e3d3..f8dac9e 100644 (file)
 #define HILDON_TOUCH_SELECTOR_GET_PRIVATE(obj)                          \
   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_TOUCH_SELECTOR, HildonTouchSelectorPrivate))
 
-G_DEFINE_TYPE (HildonTouchSelector, hildon_touch_selector, GTK_TYPE_HBOX)
+G_DEFINE_TYPE (HildonTouchSelector, hildon_touch_selector, GTK_TYPE_VBOX)
 
 #define CENTER_ON_SELECTED_ITEM_DELAY 50
 
 /**
  * Struct to maintain the data of each column. The columns are the elements
  * of the widget that belongs properly to the selection behaviour. As
- * the selector is a hbox, you can add more widgets, like buttons etc.
+ * the selector contents are arranged in a #GtkHBox, you can add more widgets, like buttons etc.
  * between the columns, but this doesn't belongs to the selection
  * logic
  */
@@ -63,18 +63,28 @@ struct _SelectorColumn
 struct _HildonTouchSelectorPrivate
 {
   GSList *columns;              /* the selection columns */
+  GtkWidget *hbox;              /* the container for the selector's columns */
 
   HildonTouchSelectorPrintFunc print_func;
 };
 
 enum
 {
+  PROP_HAS_MULTIPLE_SELECTION = 1
+};
+
+enum
+{
   CHANGED,
   LAST_SIGNAL
 };
 
 static gint hildon_touch_selector_signals[LAST_SIGNAL] = { 0 };
 
+static void hildon_touch_selector_get_property (GObject * object,
+                                                guint prop_id,
+                                                GValue * value, GParamSpec * pspec);
+
 /* gtkwidget */
 static void hildon_touch_selector_map (GtkWidget * widget);
 
@@ -93,6 +103,12 @@ static SelectorColumn *_create_new_column (HildonTouchSelector * selector,
 static gboolean _hildon_touch_selector_center_on_selected_items (gpointer data);
 
 static void
+_hildon_touch_selector_set_model (HildonTouchSelector * selector,
+                                  gint num_column, GtkTreeModel * model);
+static gboolean
+_hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector);
+
+static void
 hildon_touch_selector_class_init (HildonTouchSelectorClass * class)
 {
   GObjectClass *gobject_class;
@@ -107,12 +123,18 @@ hildon_touch_selector_class_init (HildonTouchSelectorClass * class)
 
   /* GObject */
 
+  gobject_class->get_property = hildon_touch_selector_get_property;
+
   /* GtkWidget */
   widget_class->map = hildon_touch_selector_map;
 
   /* GtkContainer */
   container_class->remove = hildon_touch_selector_remove;
 
+  /* HildonTouchSelector */
+  class->set_model = _hildon_touch_selector_set_model;
+
+  class->has_multiple_selection = _hildon_touch_selector_has_multiple_selection;
 
   /* signals */
   /**
@@ -135,10 +157,37 @@ hildon_touch_selector_class_init (HildonTouchSelectorClass * class)
                   gtk_marshal_NONE__INT, G_TYPE_NONE, 1, G_TYPE_INT);
   /* properties */
 
+  g_object_class_install_property (gobject_class, PROP_HAS_MULTIPLE_SELECTION,
+                                   g_param_spec_boolean ("has-multiple-selection",
+                                                         "has multiple selection",
+                                                         "Whether the widget has multiple "
+                                                         "selection (like multiple columns, "
+                                                         "multiselection mode, or multiple "
+                                                         "internal widgets) and therefore "
+                                                         "it may need a confirmation button, "
+                                                         "for instance.",
+                                                         FALSE,
+                                                         G_PARAM_READABLE));
+
   /* style properties */
   g_type_class_add_private (object_class, sizeof (HildonTouchSelectorPrivate));
 }
 
+static void
+hildon_touch_selector_get_property (GObject * object,
+                                    guint prop_id,
+                                    GValue * value, GParamSpec * pspec)
+{
+  switch (prop_id) {
+  case PROP_HAS_MULTIPLE_SELECTION:
+    g_value_set_boolean (value,
+                         hildon_touch_selector_has_multiple_selection (HILDON_TOUCH_SELECTOR (object)));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    break;
+  }
+}
 
 static void
 hildon_touch_selector_init (HildonTouchSelector * selector)
@@ -151,6 +200,11 @@ hildon_touch_selector_init (HildonTouchSelector * selector)
   selector->priv->columns = NULL;
 
   selector->priv->print_func = NULL;
+  selector->priv->hbox = gtk_hbox_new (FALSE, 0);
+
+  gtk_box_pack_end (GTK_BOX (selector), selector->priv->hbox,
+                    TRUE, TRUE, 0);
+  gtk_widget_show (selector->priv->hbox);
 
   /* FIXME: this is the correct height? A fixed height is the correct 
      implementation */
@@ -540,7 +594,7 @@ hildon_touch_selector_append_column (HildonTouchSelector * selector,
 
     selector->priv->columns = g_slist_append (selector->priv->columns,
                                               new_column);
-    gtk_box_pack_start (GTK_BOX (selector), new_column->panarea, TRUE, TRUE, 6);
+    gtk_box_pack_start (GTK_BOX (selector->priv->hbox), new_column->panarea, TRUE, TRUE, 6);
 
     gtk_widget_show_all (new_column->panarea);
   } else {
@@ -878,15 +932,12 @@ hildon_touch_selector_get_model (HildonTouchSelector * selector, gint column)
   return current_column->model;
 }
 
-void
-hildon_touch_selector_set_model (HildonTouchSelector * selector,
+static void
+_hildon_touch_selector_set_model (HildonTouchSelector * selector,
                                  gint num_column, GtkTreeModel * model)
 {
   SelectorColumn *column = NULL;
-
-  g_return_if_fail (HILDON_TOUCH_SELECTOR (selector));
-  g_return_if_fail (num_column <
-                    hildon_touch_selector_get_num_columns (selector));
+  g_print ("this was actually called\n");
 
   column =
     (SelectorColumn *) g_slist_nth_data (selector->priv->columns, num_column);
@@ -895,6 +946,15 @@ hildon_touch_selector_set_model (HildonTouchSelector * selector,
   gtk_tree_view_set_model (column->tree_view, column->model);
 }
 
+void
+hildon_touch_selector_set_model (HildonTouchSelector * selector,
+                                 gint num_column, GtkTreeModel * model)
+{
+  g_return_if_fail (HILDON_TOUCH_SELECTOR (selector));
+  g_return_if_fail (num_column < hildon_touch_selector_get_num_columns (selector));
+
+  HILDON_TOUCH_SELECTOR_GET_CLASS (selector)->set_model (selector, num_column, model);
+}
 /**
  * hildon_touch_selector_get_active_text
  * @selector: the #HildonTouchSelector
@@ -967,3 +1027,38 @@ _hildon_touch_selector_center_on_selected_items (gpointer data)
 
   return FALSE;
 }
+
+static gboolean
+_hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector)
+{
+  HildonTouchSelectorSelectionMode mode = HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE;
+  gint n_columns = 0;
+
+  n_columns = hildon_touch_selector_get_num_columns (selector);
+  mode = hildon_touch_selector_get_column_selection_mode (selector);
+
+  return ((n_columns > 1) || (mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE));
+}
+
+/**
+ * hildon_touch_selector_has_multiple_selection:
+ * @selector: A #HildonTouchSelector
+ *
+ * Determines whether @selector is complex enough to actually require an
+ * extra selection step than only picking an item. This is normally %TRUE
+ * if @selector has multiple columns, multiple selection, or when it is a
+ * more complex widget, like %HildonTouchSelectorEntry.
+ *
+ * This information is useful for widgets containing a %HildonTouchSelector,
+ * like #HildonPickerDialog, that could need a "Done" button, in case that
+ * its internal #HildonTouchSelector has multiple columns, for instance.
+ *
+ * Returns: %TRUE if @selector requires multiple selection steps.
+ **/
+gboolean
+hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector)
+{
+  g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
+
+  return HILDON_TOUCH_SELECTOR_GET_CLASS (selector)->has_multiple_selection (selector);
+}