[maemo-commits] [maemo-commits] r17444 - in projects/haf/trunk/gtk+: . gtk tests

From: subversion at stage.maemo.org subversion at stage.maemo.org
Date: Tue Feb 17 11:00:04 EET 2009
Author: kris
Date: 2009-02-17 11:00:01 +0200 (Tue, 17 Feb 2009)
New Revision: 17444

Added:
   projects/haf/trunk/gtk+/tests/testtreeviewactionarea.c
Modified:
   projects/haf/trunk/gtk+/ChangeLog
   projects/haf/trunk/gtk+/gtk/gtk.symbols
   projects/haf/trunk/gtk+/gtk/gtkrbtree.c
   projects/haf/trunk/gtk+/gtk/gtkrbtree.h
   projects/haf/trunk/gtk+/gtk/gtktreeprivate.h
   projects/haf/trunk/gtk+/gtk/gtktreeview.c
   projects/haf/trunk/gtk+/gtk/gtktreeview.h
   projects/haf/trunk/gtk+/tests/Makefile.am
Log:
2009-02-17  Kristian Rietveld  <kris at imendio.com>

	Allow for an action area above the first row in the scrollable
	part of the tree view wherein arbitrary widgets can be embedded.

	* gtk/gtktreeview.[ch] (gtk_tree_view_class_init),
	(gtk_tree_view_init), (gtk_tree_view_[gs]et_property):
	new action-area-visible, action-area-orientation properties,
	(gtk_tree_view_update_size), (gtk_tree_view_size_allocate),
	(gtk_tree_view_bin_expose), (gtk_tree_view_move_cursor_page_up_down):
	take rows-offset into account,
	(gtk_tree_view_row_inserted), (gtk_tree_view_set_model): set
	rows offset after creating root rbtree,
	(gtk_tree_view_style_set): update rows-offset from new style,
	(hildon_tree_view_set_rows_offset),
	(hildon_tree_view_create_action_area),
	(hildon_tree_view_set_action_area_height),
	(hildon_tree_view_rotate_action_area_box): new internal functions,
	(hildon_tree_view_[gs]et_action_area_visible),
	(hildon_tree_view_[gs]et_action_area_orientation),
	(hildon_tree_view_get_action_area_box): new public functions.

	* gtk/gtktreeprivate.h: add new fields.

	* gtk/gtkrbtree.[ch] (_gtk_rbtree_set_base_offset): allow for
	setting a base offset on a tree,
	(_gtk_rbtree_node_find_offset), (_gtk_rbtree_find_offset): take
	base offset into account.

	* gtk/gtk.symbols: add new functions.

	* tests/Makefile.am
	* tests/testtreeviewactionarea.c: new test application.



Modified: projects/haf/trunk/gtk+/ChangeLog
===================================================================
--- projects/haf/trunk/gtk+/ChangeLog	2009-02-16 18:48:09 UTC (rev 17443)
+++ projects/haf/trunk/gtk+/ChangeLog	2009-02-17 09:00:01 UTC (rev 17444)
@@ -1,3 +1,37 @@
+2009-02-17  Kristian Rietveld  <kris at imendio.com>
+
+	Allow for an action area above the first row in the scrollable
+	part of the tree view wherein arbitrary widgets can be embedded.
+
+	* gtk/gtktreeview.[ch] (gtk_tree_view_class_init),
+	(gtk_tree_view_init), (gtk_tree_view_[gs]et_property):
+	new action-area-visible, action-area-orientation properties,
+	(gtk_tree_view_update_size), (gtk_tree_view_size_allocate),
+	(gtk_tree_view_bin_expose), (gtk_tree_view_move_cursor_page_up_down):
+	take rows-offset into account,
+	(gtk_tree_view_row_inserted), (gtk_tree_view_set_model): set
+	rows offset after creating root rbtree,
+	(gtk_tree_view_style_set): update rows-offset from new style,
+	(hildon_tree_view_set_rows_offset),
+	(hildon_tree_view_create_action_area),
+	(hildon_tree_view_set_action_area_height),
+	(hildon_tree_view_rotate_action_area_box): new internal functions,
+	(hildon_tree_view_[gs]et_action_area_visible),
+	(hildon_tree_view_[gs]et_action_area_orientation),
+	(hildon_tree_view_get_action_area_box): new public functions.
+
+	* gtk/gtktreeprivate.h: add new fields.
+
+	* gtk/gtkrbtree.[ch] (_gtk_rbtree_set_base_offset): allow for
+	setting a base offset on a tree,
+	(_gtk_rbtree_node_find_offset), (_gtk_rbtree_find_offset): take
+	base offset into account.
+
+	* gtk/gtk.symbols: add new functions.
+
+	* tests/Makefile.am
+	* tests/testtreeviewactionarea.c: new test application.
+
 2009-02-11  Claudio Saavedra  <csaavedra at igalia.com>
 
 	* ChangeLog.pre-2-12.mameo: Renamed to ChangeLog.pre-2-12.maemo

Modified: projects/haf/trunk/gtk+/gtk/gtk.symbols
===================================================================
--- projects/haf/trunk/gtk+/gtk/gtk.symbols	2009-02-16 18:48:09 UTC (rev 17443)
+++ projects/haf/trunk/gtk+/gtk/gtk.symbols	2009-02-17 09:00:01 UTC (rev 17444)
@@ -4568,8 +4568,13 @@
 #endif
 gtk_tree_view_columns_autosize
 #ifdef MAEMO_CHANGES
+hildon_tree_view_get_action_area_box
+hildon_tree_view_get_action_area_orientation
+hildon_tree_view_get_action_area_visible
 hildon_tree_view_get_hildon_ui_mode
 hildon_tree_view_get_row_header_func
+hildon_tree_view_set_action_area_orientation
+hildon_tree_view_set_action_area_visible
 hildon_tree_view_set_hildon_ui_mode
 hildon_tree_view_set_row_header_func
 #endif

Modified: projects/haf/trunk/gtk+/gtk/gtkrbtree.c
===================================================================
--- projects/haf/trunk/gtk+/gtk/gtkrbtree.c	2009-02-16 18:48:09 UTC (rev 17443)
+++ projects/haf/trunk/gtk+/gtk/gtkrbtree.c	2009-02-17 09:00:01 UTC (rev 17444)
@@ -337,6 +337,9 @@
   retval = g_new (GtkRBTree, 1);
   retval->parent_tree = NULL;
   retval->parent_node = NULL;
+#ifdef MAEMO_CHANGES
+  retval->base_offset = 0;
+#endif /* MAEMO_CHANGES */
 
   retval->nil = g_slice_new (GtkRBNode);
   retval->nil->left = NULL;
@@ -964,6 +967,9 @@
 {
   GtkRBNode *last;
   gint retval;
+#ifdef MAEMO_CHANGES
+  GtkRBTree *origtree = tree;
+#endif /* !MAEMO_CHANGES */
 
   g_assert (node);
   g_assert (node->left);
@@ -989,7 +995,15 @@
 	    retval += node->left->offset + GTK_RBNODE_GET_HEIGHT (node);
 	}
     }
+
+#ifdef MAEMO_CHANGES
+  while (origtree->parent_tree)
+    origtree = origtree->parent_tree;
+
+  return retval + origtree->base_offset;
+#else /* !MAEMO_CHANGES */
   return retval;
+#endif /* !MAEMO_CHANGES */
 }
 
 gint
@@ -1097,6 +1111,13 @@
 {
   g_assert (tree);
 
+#ifdef MAEMO_CHANGES
+  /* We (ab)use the fact that "tree" that is passed in is always
+   * the root.
+   */
+  height -= tree->base_offset;
+#endif /* MAEMO_CHANGES */
+
   if ((height < 0) ||
       (height >= tree->root->offset))
     {
@@ -1413,6 +1434,15 @@
   return depth;
 }
 
+#ifdef MAEMO_CHANGES
+void
+_gtk_rbtree_set_base_offset (GtkRBTree *tree,
+                             short      base_offset)
+{
+  tree->base_offset = base_offset;
+}
+#endif /* MAEMO_CHANGES */
+
 static void
 _gtk_rbtree_traverse_pre_order (GtkRBTree             *tree,
 				GtkRBNode             *node,

Modified: projects/haf/trunk/gtk+/gtk/gtkrbtree.h
===================================================================
--- projects/haf/trunk/gtk+/gtk/gtkrbtree.h	2009-02-16 18:48:09 UTC (rev 17443)
+++ projects/haf/trunk/gtk+/gtk/gtkrbtree.h	2009-02-17 09:00:01 UTC (rev 17444)
@@ -64,6 +64,9 @@
   GtkRBNode *nil;
   GtkRBTree *parent_tree;
   GtkRBNode *parent_node;
+#ifdef MAEMO_CHANGES
+  short base_offset;
+#endif /* MAEMO_CHANGES */
 };
 
 struct _GtkRBNode
@@ -170,6 +173,11 @@
 
 gint       _gtk_rbtree_get_depth        (GtkRBTree              *tree);
 
+#ifdef MAEMO_CHANGES
+void       _gtk_rbtree_set_base_offset  (GtkRBTree              *tree,
+                                         short                   base_offset);
+#endif /* MAEMO_CHANGES */
+
 /* This func checks the integrity of the tree */
 #ifdef G_ENABLE_DEBUG  
 void       _gtk_rbtree_test             (const gchar            *where,

Modified: projects/haf/trunk/gtk+/gtk/gtktreeprivate.h
===================================================================
--- projects/haf/trunk/gtk+/gtk/gtktreeprivate.h	2009-02-16 18:48:09 UTC (rev 17443)
+++ projects/haf/trunk/gtk+/gtk/gtktreeprivate.h	2009-02-17 09:00:01 UTC (rev 17444)
@@ -294,8 +294,15 @@
   GDestroyNotify row_header_destroy;
   PangoLayout *row_header_layout;
 
+  gint rows_offset;
+  GtkOrientation action_area_orientation;
+  GtkWidget *action_area_event_box;
+  GtkWidget *action_area_box;
+
   guint queued_shift_pressed : 1;
   guint queued_ctrl_pressed : 1;
+
+  guint action_area_visible : 1;
 #endif /* MAEMO_CHANGES */
 };
 

Modified: projects/haf/trunk/gtk+/gtk/gtktreeview.c
===================================================================
--- projects/haf/trunk/gtk+/gtk/gtktreeview.c	2009-02-16 18:48:09 UTC (rev 17443)
+++ projects/haf/trunk/gtk+/gtk/gtktreeview.c	2009-02-17 09:00:01 UTC (rev 17444)
@@ -45,6 +45,7 @@
 #include "gtktooltip.h"
 #ifdef MAEMO_CHANGES
 #include "gtkicontheme.h"
+#include "gtkeventbox.h"
 #endif /* MAEMO_CHANGES */
 #include "gtkprivate.h"
 #include "gtkalias.h"
@@ -160,7 +161,9 @@
   PROP_TOOLTIP_COLUMN
 #ifdef MAEMO_CHANGES
   ,
-  PROP_HILDON_UI_MODE
+  PROP_HILDON_UI_MODE,
+  PROP_ACTION_AREA_VISIBLE,
+  PROP_ACTION_AREA_ORIENTATION
 #endif /* MAEMO_CHANGES */
 };
 
@@ -498,6 +501,8 @@
 static void     free_queued_select_row           (GtkTreeView  *tree_view);
 static void     free_queued_activate_row         (GtkTreeView  *tree_view);
 static void     free_queued_actions              (GtkTreeView  *tree_view);
+
+static void     hildon_tree_view_set_action_area_height (GtkTreeView *tree_view);
 #endif /* MAEMO_CHANGES */
 
 static guint tree_view_signals [LAST_SIGNAL] = { 0 };
@@ -836,6 +841,44 @@
                                                         HILDON_TYPE_UI_MODE,
                                                         HILDON_UI_MODE_NORMAL,
                                                         GTK_PARAM_READWRITE));
+
+    /**
+     * GtkTreeView:action-area-visible:
+     *
+     * Makes the action area of the GtkTreeView visible or invisible.
+     * Based on the value of the GtkTreeView:action-area-orientation
+     * property a certain height will be allocated above the first row
+     * for the action area.
+     *
+     * Since: maemo 5.0
+     * Stability: unstable
+     */
+    g_object_class_install_property (o_class,
+                                     PROP_ACTION_AREA_VISIBLE,
+                                     g_param_spec_boolean ("action-area-visible",
+                                                           P_("Action Area Visible"),
+                                                           P_("Whether the action area above the first row is visible"),
+                                                           FALSE,
+                                                           GTK_PARAM_READWRITE));
+
+    /**
+     * GtkTreeView:action-area-orientation:
+     *
+     * Sets the orientation of the action area.  This is either
+     * horizontal (landscape) or vertical (portrait).  The height of
+     * the action area depends on this setting.
+     *
+     * Since: maemo 5.0
+     * Stability: unstable
+     */
+    g_object_class_install_property (o_class,
+                                     PROP_ACTION_AREA_ORIENTATION,
+                                     g_param_spec_enum ("action-area-orientation",
+                                                         P_("Action Area Orientation"),
+                                                         P_("Determines the orientation of the action area."),
+                                                         GTK_TYPE_ORIENTATION,
+                                                         GTK_ORIENTATION_HORIZONTAL,
+                                                         GTK_PARAM_READWRITE));
 #endif /* MAEMO_CHANGES */
 
   /* Style properties */
@@ -1532,6 +1575,14 @@
   tree_view->priv->tree_lines_enabled = FALSE;
 
   tree_view->priv->tooltip_column = -1;
+
+#ifdef MAEMO_CHANGES
+  tree_view->priv->rows_offset = 0;
+  tree_view->priv->action_area_visible = FALSE;
+  tree_view->priv->action_area_orientation = GTK_ORIENTATION_HORIZONTAL;
+  tree_view->priv->action_area_event_box = NULL;
+  tree_view->priv->action_area_box = NULL;
+#endif /* MAEMO_CHANGES */
 }
 
 
@@ -1612,6 +1663,12 @@
     case PROP_HILDON_UI_MODE:
       hildon_tree_view_set_hildon_ui_mode (tree_view, g_value_get_enum (value));
       break;
+    case PROP_ACTION_AREA_VISIBLE:
+      hildon_tree_view_set_action_area_visible (tree_view, g_value_get_boolean (value));
+      break;
+    case PROP_ACTION_AREA_ORIENTATION:
+      hildon_tree_view_set_action_area_orientation (tree_view, g_value_get_enum (value));
+      break;
 #endif /* MAEMO_CHANGES */
     default:
       break;
@@ -1691,6 +1748,12 @@
     case PROP_HILDON_UI_MODE:
       g_value_set_enum (value, tree_view->priv->hildon_ui_mode);
       break;
+    case PROP_ACTION_AREA_VISIBLE:
+      g_value_set_boolean (value, tree_view->priv->action_area_visible);
+      break;
+    case PROP_ACTION_AREA_ORIENTATION:
+      g_value_set_enum (value, tree_view->priv->action_area_orientation);
+      break;
 #endif /* MAEMO_CHANGES */
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -2258,7 +2321,11 @@
   if (tree_view->priv->tree == NULL)
     tree_view->priv->height = 0;
   else
+#ifdef MAEMO_CHANGES
+    tree_view->priv->height = tree_view->priv->tree->root->offset + tree_view->priv->rows_offset;
+#else /* !MAEMO_CHANGES */
     tree_view->priv->height = tree_view->priv->tree->root->offset;
+#endif /* !MAEMO_CHANGES */
 }
 
 static void
@@ -2567,6 +2634,19 @@
       allocation.y = child->y;
       allocation.width = child->width;
       allocation.height = child->height;
+
+#ifdef MAEMO_CHANGES
+      if (tree_view->priv->rows_offset != 0
+          && tree_view->priv->action_area_event_box == child->widget)
+        {
+          /* Set the child's location to be the area above the first row */
+          allocation.x = 0;
+          allocation.y = -tree_view->priv->dy;
+          allocation.width = MAX (widget->allocation.width, tree_view->priv->width);
+          allocation.height = tree_view->priv->rows_offset;
+        }
+#endif /* MAEMO_CHANGES */
+
       gtk_widget_size_allocate (child->widget, &allocation);
     }
 
@@ -4932,6 +5012,7 @@
   gboolean row_ending_details;
   gboolean draw_vgrid_lines, draw_hgrid_lines;
 #ifdef MAEMO_CHANGES
+  gint expose_start;
   gboolean render_checkboxes = FALSE;
   HildonMode mode;
 #endif /* MAEMO_CHANGES */
@@ -4965,11 +5046,33 @@
 
   validate_visible_area (tree_view);
 
+#ifdef MAEMO_CHANGES
+  if (G_UNLIKELY (tree_view->priv->rows_offset != 0)
+      && tree_view->priv->dy <= tree_view->priv->rows_offset
+      && event->area.y <= tree_view->priv->rows_offset - tree_view->priv->dy)
+    {
+      /* As long as a part of the button window is visible ... */
+      expose_start = tree_view->priv->rows_offset - tree_view->priv->dy;
+      y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree,
+                                           tree_view->priv->rows_offset,
+                                           &tree, &node);
+    }
+  else
+    {
+      new_y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, event->area.y);
+      if (new_y < 0)
+        new_y = 0;
+
+      expose_start = event->area.y;
+      y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node);
+    }
+#else /* !MAEMO_CHANGES */
   new_y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, event->area.y);
-
   if (new_y < 0)
     new_y = 0;
   y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node);
+#endif /* !MAEMO_CHANGES */
+
   gdk_drawable_get_size (tree_view->priv->bin_window,
                          &bin_window_width, &bin_window_height);
 
@@ -5081,7 +5184,11 @@
       highlight_x = 0; /* should match x coord of first cell */
       expander_cell_width = 0;
 
+#ifdef MAEMO_CHANGES
+      background_area.y = y_offset + expose_start;
+#else /* !MAEMO_CHANGES */
       background_area.y = y_offset + event->area.y;
+#endif /* !MAEMO_CHANGES */
       background_area.height = max_height;
 
       flags = 0;
@@ -9106,6 +9213,9 @@
                                                              "widgets_tickmark_list",
                                                              HILDON_TICK_MARK_SIZE,
                                                              0, NULL);
+
+  if (tree_view->priv->action_area_visible)
+    hildon_tree_view_set_action_area_height (tree_view);
 #endif /* MAEMO_CHANGES */
 
   gtk_widget_queue_resize (widget);
@@ -9475,7 +9585,16 @@
     gtk_tree_model_get_iter (model, iter, path);
 
   if (tree_view->priv->tree == NULL)
+#ifdef MAEMO_CHANGES
+    {
+      tree_view->priv->tree = _gtk_rbtree_new ();
+      if (G_UNLIKELY (tree_view->priv->rows_offset != 0))
+        _gtk_rbtree_set_base_offset (tree_view->priv->tree,
+                                     tree_view->priv->rows_offset);
+    }
+#else /* !MAEMO_CHANGES */
     tree_view->priv->tree = _gtk_rbtree_new ();
+#endif /* !MAEMO_CHANGES */
 
   tmptree = tree = tree_view->priv->tree;
 
@@ -11109,6 +11228,10 @@
 
   if (y >= tree_view->priv->height)
     y = tree_view->priv->height - 1;
+#ifdef MAEMO_CHANGES
+  else if (tree_view->priv->rows_offset != 0 && y < tree_view->priv->rows_offset)
+    y = tree_view->priv->rows_offset;
+#endif /* MAEMO_CHANGES */
 
   tree_view->priv->cursor_offset =
     _gtk_rbtree_find_offset (tree_view->priv->tree, y,
@@ -12246,6 +12369,12 @@
       if (gtk_tree_model_get_iter (tree_view->priv->model, &iter, path))
 	{
 	  tree_view->priv->tree = _gtk_rbtree_new ();
+#ifdef MAEMO_CHANGES
+          if (G_UNLIKELY (tree_view->priv->rows_offset != 0))
+            _gtk_rbtree_set_base_offset (tree_view->priv->tree,
+                                         tree_view->priv->rows_offset);
+#endif /* MAEMO_CHANGES */
+
 	  gtk_tree_view_build_tree (tree_view, tree_view->priv->tree, &iter, 1, FALSE);
 	}
 #ifdef MAEMO_CHANGES
@@ -17471,6 +17600,212 @@
   else
     g_assert_not_reached ();
 }
+
+static void
+hildon_tree_view_set_rows_offset (GtkTreeView *tree_view,
+                                  int          rows_offset)
+{
+  if (tree_view->priv->rows_offset == rows_offset)
+    return;
+
+  tree_view->priv->rows_offset = rows_offset;
+  if (tree_view->priv->tree)
+    _gtk_rbtree_set_base_offset (tree_view->priv->tree, rows_offset);
+
+  gtk_widget_queue_resize (GTK_WIDGET (tree_view));
+}
+
+static void
+hildon_tree_view_create_action_area (GtkTreeView *tree_view)
+{
+  /* gtk_tree_view_put() takes over ownership and so we do not
+   * have to unref these values in gtk_tree_view_destroy().
+   */
+  tree_view->priv->action_area_event_box = gtk_event_box_new ();
+  gtk_tree_view_put (tree_view, tree_view->priv->action_area_event_box,
+                     0, 0, 0, 0);
+
+  if (tree_view->priv->action_area_orientation == GTK_ORIENTATION_HORIZONTAL)
+    tree_view->priv->action_area_box = gtk_hbox_new (TRUE, 5);
+  else if (tree_view->priv->action_area_orientation == GTK_ORIENTATION_VERTICAL)
+    tree_view->priv->action_area_box = gtk_vbox_new (TRUE, 5);
+
+  gtk_container_add (GTK_CONTAINER (tree_view->priv->action_area_event_box),
+                     tree_view->priv->action_area_box);
+}
+
+static void
+hildon_tree_view_set_action_area_height (GtkTreeView *tree_view)
+{
+  if (tree_view->priv->action_area_orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      int row_height;
+
+      gtk_widget_style_get (GTK_WIDGET (tree_view),
+                            "row-height", &row_height,
+                            NULL);
+      hildon_tree_view_set_rows_offset (tree_view, row_height);
+    }
+  else if (tree_view->priv->action_area_orientation == GTK_ORIENTATION_VERTICAL)
+    {
+      GList *children;
+
+      /* The height in portrait mode is currently hardcoded to 93px per
+       * button.
+       */
+      children = gtk_container_get_children (GTK_CONTAINER (tree_view->priv->action_area_box));
+      hildon_tree_view_set_rows_offset (tree_view,
+                                        g_list_length (children) * 93);
+      g_list_free (children);
+    }
+}
+
+void
+hildon_tree_view_set_action_area_visible (GtkTreeView *tree_view,
+                                          gboolean     visible)
+{
+  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+
+  if (tree_view->priv->action_area_visible == !!visible)
+    return;
+
+  tree_view->priv->action_area_visible = visible;
+
+  if (visible)
+    {
+      hildon_tree_view_set_action_area_height (tree_view);
+
+      if (!tree_view->priv->action_area_event_box)
+        hildon_tree_view_create_action_area (tree_view);
+
+      gtk_widget_show (tree_view->priv->action_area_box);
+      gtk_widget_show (tree_view->priv->action_area_event_box);
+    }
+  else
+    {
+      gtk_widget_hide (tree_view->priv->action_area_event_box);
+
+      hildon_tree_view_set_rows_offset (tree_view, 0);
+    }
+}
+
+gboolean
+hildon_tree_view_get_action_area_visible (GtkTreeView *tree_view)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), FALSE);
+
+  return tree_view->priv->action_area_visible;
+}
+
+static void
+hildon_tree_view_rotate_action_area_box (GtkBox *old_box,
+                                         GtkBox *new_box)
+{
+  int spacing, border_width;
+  GList *children, *child;
+  gboolean homogeneous;
+
+  g_object_get (old_box,
+                "homogeneous", &homogeneous,
+                "spacing", &spacing,
+                "border-width", &border_width,
+                NULL);
+
+  g_object_set (new_box,
+                "homogeneous", homogeneous,
+                "spacing", spacing,
+                "border-width", border_width,
+                NULL);
+
+  children = gtk_container_get_children (GTK_CONTAINER (old_box));
+  for (child = children; child; child = child->next)
+    {
+      guint padding;
+      gboolean expand, fill;
+      GtkPackType type;
+      GtkWidget *widget = child->data;
+
+      g_object_ref (widget);
+      gtk_box_query_child_packing (old_box, widget,
+                                   &expand, &fill, &padding, &type);
+      gtk_container_remove (GTK_CONTAINER (old_box), widget);
+      gtk_container_add (GTK_CONTAINER (new_box), widget);
+      gtk_box_set_child_packing (new_box, widget,
+                                 expand, fill, padding, type);
+      g_object_unref (widget);
+    }
+
+  g_list_free (children);
+
+  if (GTK_WIDGET_VISIBLE (old_box))
+    gtk_widget_show (GTK_WIDGET (new_box));
+}
+
+void
+hildon_tree_view_set_action_area_orientation (GtkTreeView    *tree_view,
+                                              GtkOrientation  orientation)
+{
+  GtkWidget *old_box;
+  GtkWidget *new_box;
+
+  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+
+  if (tree_view->priv->action_area_orientation == orientation)
+    return;
+
+  tree_view->priv->action_area_orientation = orientation;
+
+  old_box = tree_view->priv->action_area_box;
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    new_box = gtk_hbox_new (TRUE, 5);
+  else if (orientation == GTK_ORIENTATION_VERTICAL)
+    new_box = gtk_vbox_new (TRUE, 5);
+
+  if (tree_view->priv->action_area_visible)
+    hildon_tree_view_set_action_area_height (tree_view);
+
+  hildon_tree_view_rotate_action_area_box (GTK_BOX (old_box),
+                                           GTK_BOX (new_box));
+
+  gtk_widget_destroy (old_box);
+
+  tree_view->priv->action_area_box = new_box;
+  gtk_container_add (GTK_CONTAINER (tree_view->priv->action_area_event_box),
+                     tree_view->priv->action_area_box);
+}
+
+GtkOrientation
+hildon_tree_view_get_action_area_orientation (GtkTreeView *tree_view)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), 0);
+
+  return tree_view->priv->action_area_orientation;
+}
+
+/**
+ * hildon_tree_view_get_action_area_box:
+ * @tree_view: a #GtkTreeView
+ *
+ * Returns the GtkBox is embedded in GtkTreeView's action area.  Depending
+ * on the setting of the GtkTreeView:action-area-orientation property
+ * this is either a GtkHBox or GtkVBox.  You do not own a reference to
+ * the returned widget and thus this value should not be unreferenced.
+ *
+ * Returns: a pointer to a GtkBox.  This pointer should not be unreferenced.
+ *
+ * Since: maemo 5.0
+ * Stability: unstable
+ */
+GtkWidget *
+hildon_tree_view_get_action_area_box (GtkTreeView *tree_view)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
+
+  if (!tree_view->priv->action_area_event_box)
+    hildon_tree_view_create_action_area (tree_view);
+
+  return tree_view->priv->action_area_box;
+}
 #endif /* MAEMO_CHANGES */
 
 #define __GTK_TREE_VIEW_C__

Modified: projects/haf/trunk/gtk+/gtk/gtktreeview.h
===================================================================
--- projects/haf/trunk/gtk+/gtk/gtktreeview.h	2009-02-16 18:48:09 UTC (rev 17443)
+++ projects/haf/trunk/gtk+/gtk/gtktreeview.h	2009-02-17 09:00:01 UTC (rev 17444)
@@ -412,6 +412,17 @@
 HildonUIMode                hildon_tree_view_get_hildon_ui_mode  (GtkTreeView                 *tree_view);
 void                        hildon_tree_view_set_hildon_ui_mode  (GtkTreeView                 *tree_view,
                                                                   HildonUIMode                 mode);
+
+
+void                        hildon_tree_view_set_action_area_visible       (GtkTreeView    *tree_view,
+                                                                            gboolean        visible);
+gboolean                    hildon_tree_view_get_action_area_visible       (GtkTreeView    *tree_view);
+
+void                        hildon_tree_view_set_action_area_orientation   (GtkTreeView    *tree_view,
+                                                                            GtkOrientation  orientation);
+GtkOrientation              hildon_tree_view_get_action_area_orientation   (GtkTreeView    *tree_view);
+
+GtkWidget                  *hildon_tree_view_get_action_area_box           (GtkTreeView    *tree_view);
 #endif /* MAEMO_CHANGES */
 
 GtkTreeViewGridLines        gtk_tree_view_get_grid_lines         (GtkTreeView                *tree_view);

Modified: projects/haf/trunk/gtk+/tests/Makefile.am
===================================================================
--- projects/haf/trunk/gtk+/tests/Makefile.am	2009-02-16 18:48:09 UTC (rev 17443)
+++ projects/haf/trunk/gtk+/tests/Makefile.am	2009-02-17 09:00:01 UTC (rev 17444)
@@ -26,7 +26,10 @@
 endif
 
 if MAEMO_CHANGES
-testmaemo_programs = testhildontreeview testhildoniconview
+testmaemo_programs =			\
+	testhildontreeview		\
+	testhildoniconview		\
+	testtreeviewactionarea
 endif
 
 TESTS = floatingtest buildertest
@@ -169,6 +172,7 @@
 testvolumebutton_DEPENDENCIES = $(TEST_DEPS)
 testhildoniconview_DEPENDENCIES = $(TEST_DEPS)
 testhildontreeview_DEPENDENCIES = $(TEST_DEPS)
+testtreeviewactionarea_DEPENDENCIES = $(TEST_DEPS)
 
 autotestfilechooser_LDADD = $(LDADDS)
 simple_LDADD = $(LDADDS)
@@ -235,6 +239,7 @@
 testvolumebutton_LDADD = $(LDADDS)
 testhildoniconview_LDADD = $(LDADDS)
 testhildontreeview_LDADD = $(LDADDS)
+testtreeviewactionarea_LDADD = $(LDADDS)
 
 buildertest_LDFLAGS = -export-dynamic
 
@@ -333,6 +338,9 @@
 testhildontreeview_SOURCES =	\
 	testhildontreeview.c
 
+testtreeviewactionarea_SOURCES =	\
+	testtreeviewactionarea.c
+
 EXTRA_DIST += 			\
 	prop-editor.h		\
 	testgtk.1 		\

Added: projects/haf/trunk/gtk+/tests/testtreeviewactionarea.c
===================================================================
--- projects/haf/trunk/gtk+/tests/testtreeviewactionarea.c	2009-02-16 18:48:09 UTC (rev 17443)
+++ projects/haf/trunk/gtk+/tests/testtreeviewactionarea.c	2009-02-17 09:00:01 UTC (rev 17444)
@@ -0,0 +1,235 @@
+/* testtreeviewactionarea.c: test action area support in GtkTreeView.
+ *
+ * Copyright: (C) 2009  Nokia Corporation.
+ * Author: Kristian Rietveld <kris at imendio.com>
+ *
+ */
+
+#include <gtk/gtk.h>
+
+static GtkTreeModel *
+create_model (void)
+{
+  int i;
+  GtkListStore *store;
+
+  store = gtk_list_store_new (1, G_TYPE_STRING);
+
+  for (i = 0; i < 50; i++)
+    {
+      gchar *str;
+
+      str = g_strdup_printf ("Row %d", i);
+      gtk_list_store_insert_with_values (store, NULL, i, 0, str, -1);
+      g_free (str);
+    }
+
+  return GTK_TREE_MODEL (store);
+}
+
+static void
+portrait_toggled (GtkToggleButton *button,
+                  gpointer         user_data)
+{
+  if (gtk_toggle_button_get_active (button))
+    {
+      GtkWidget *tree_view;
+
+      gtk_window_resize (GTK_WINDOW (user_data), 480, 800);
+
+      tree_view = gtk_bin_get_child (GTK_BIN (user_data));
+      tree_view = gtk_bin_get_child (GTK_BIN (tree_view));
+
+      hildon_tree_view_set_action_area_orientation (GTK_TREE_VIEW (tree_view),
+                                                    GTK_ORIENTATION_VERTICAL);
+    }
+}
+
+static void
+landscape_toggled (GtkToggleButton *button,
+                   gpointer         user_data)
+{
+  if (gtk_toggle_button_get_active (button))
+    {
+      GtkWidget *tree_view;
+
+      gtk_window_resize (GTK_WINDOW (user_data), 800, 480);
+
+      tree_view = gtk_bin_get_child (GTK_BIN (user_data));
+      tree_view = gtk_bin_get_child (GTK_BIN (tree_view));
+
+      hildon_tree_view_set_action_area_orientation (GTK_TREE_VIEW (tree_view),
+                                                    GTK_ORIENTATION_HORIZONTAL);
+    }
+}
+
+static void
+show_buttons_toggled (GtkToggleButton *toggle_button,
+                      gpointer         user_data)
+{
+  gboolean value;
+  GtkTreeView *tree_view = GTK_TREE_VIEW (user_data);
+
+  value = hildon_tree_view_get_action_area_visible (tree_view);
+  value = !value;
+
+  hildon_tree_view_set_action_area_visible (tree_view, value);
+}
+
+static gboolean
+row_header_func (GtkTreeModel *model,
+                 GtkTreeIter  *iter,
+                 gchar       **header_text,
+                 gpointer      user_data)
+{
+  GtkTreePath *path;
+  gboolean retval = FALSE;
+
+  path = gtk_tree_model_get_path (model, iter);
+  if (gtk_tree_path_get_indices (path)[0] % 10 == 0)
+    {
+      retval = TRUE;
+      if (header_text)
+        *header_text = g_strdup ("Happy fun group header!");
+    }
+  gtk_tree_path_free (path);
+
+  return retval;
+}
+
+static GtkWidget *
+create_tree_view (void)
+{
+  GtkWidget *tree_view;
+  GtkCellRenderer *renderer;
+
+  tree_view = g_object_new (GTK_TYPE_TREE_VIEW,
+                            "model", create_model (),
+                            "name", "fremantle-widget",
+                            "hildon-ui-mode", HILDON_UI_MODE_NORMAL,
+                            "rules-hint", TRUE,
+                            NULL);
+
+  renderer = gtk_cell_renderer_text_new ();
+  g_object_set (renderer,
+                "xalign", 0.5,
+                "weight", PANGO_WEIGHT_BOLD,
+                NULL);
+
+  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
+                                               0, "Column 0",
+                                               renderer,
+                                               "text", 0,
+                                               NULL);
+
+  hildon_tree_view_set_row_header_func (GTK_TREE_VIEW (tree_view),
+                                        row_header_func,
+                                        NULL,
+                                        NULL);
+
+  return tree_view;
+
+}
+
+
+int
+main (int argc, char **argv)
+{
+  GtkWidget *window;
+  GtkWidget *tree_window;
+  GtkWidget *mainbox;
+  GtkWidget *padbox;
+  GtkWidget *vbox;
+  GtkWidget *label;
+  GtkWidget *button;
+  GtkWidget *check_button;
+  GtkWidget *tree_view;
+  GtkWidget *scrolled;
+
+  gtk_init (&argc, &argv);
+
+  gtk_rc_parse_string ("style \"fremantle-widget\" {\n"
+                       "  GtkWidget::hildon-mode = 1\n"
+                       "  GtkTreeView::row-height = 70\n"
+                       "} widget \"*.fremantle-widget\" style \"fremantle-widget\"");
+
+  /* Tree view window */
+  tree_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  g_signal_connect (tree_window, "delete-event",
+                    G_CALLBACK (gtk_main_quit), NULL);
+  gtk_container_set_border_width (GTK_CONTAINER (tree_window), 6);
+
+  scrolled = gtk_scrolled_window_new (NULL, NULL);
+  gtk_container_add (GTK_CONTAINER (tree_window), scrolled);
+
+  tree_view = create_tree_view ();
+  gtk_container_add (GTK_CONTAINER (scrolled), tree_view);
+
+  vbox = hildon_tree_view_get_action_area_box (GTK_TREE_VIEW (tree_view));
+  gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
+
+  button = gtk_button_new_with_label ("Button 1");
+  gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
+
+  button = gtk_button_new_with_label ("Button 2");
+  gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
+
+  gtk_window_resize (GTK_WINDOW (tree_window), 800, 480);
+
+  gtk_widget_show_all (tree_window);
+
+  /* Control window */
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  g_signal_connect (window, "delete-event",
+                    G_CALLBACK (gtk_main_quit), NULL);
+  gtk_container_set_border_width (GTK_CONTAINER (window), 6);
+
+  mainbox = gtk_vbox_new (FALSE, 6);
+  gtk_container_add (GTK_CONTAINER (window), mainbox);
+
+  label = gtk_label_new (NULL);
+  gtk_label_set_markup (GTK_LABEL (label), "<b>Orientation</b>");
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_box_pack_start (GTK_BOX (mainbox), label, FALSE, FALSE, 0);
+
+  padbox = gtk_hbox_new (FALSE, 6);
+  gtk_box_pack_start (GTK_BOX (mainbox), padbox, FALSE, FALSE, 6);
+
+  gtk_box_pack_start (GTK_BOX (padbox), gtk_label_new ("  "),
+                      FALSE, FALSE, 6);
+
+  vbox = gtk_vbox_new (FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (padbox), vbox, TRUE, TRUE, 0);
+
+  button = gtk_radio_button_new_with_label (NULL, "Landscape");
+  g_signal_connect (button, "toggled",
+                    G_CALLBACK (landscape_toggled), tree_window);
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (button), "Portrait");
+  g_signal_connect (button, "toggled",
+                    G_CALLBACK (portrait_toggled), tree_window);
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+
+  check_button = gtk_check_button_new_with_label ("Show buttons");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), FALSE);
+  g_signal_connect (check_button, "toggled",
+                    G_CALLBACK (show_buttons_toggled), tree_view);
+  gtk_box_pack_start (GTK_BOX (mainbox), check_button, FALSE, FALSE, 0);
+
+
+  button = gtk_button_new_with_label ("Close");
+  g_signal_connect (button, "clicked",
+                    G_CALLBACK (gtk_main_quit), NULL);
+  gtk_box_pack_end (GTK_BOX (mainbox), button, FALSE, FALSE, 0);
+
+  gtk_box_pack_end (GTK_BOX (mainbox), gtk_hseparator_new (),
+                    FALSE, FALSE, 6);
+
+  gtk_widget_show_all (window);
+
+  gtk_main ();
+
+  return 0;
+}


More information about the maemo-commits mailing list