[gimp] app: Add GimpPanedBox



commit eb9b365864e0d40e396614e55b490f402e64f7bb
Author: Martin Nordholts <martinn src gnome org>
Date:   Sat Oct 24 18:52:48 2009 +0200

    app: Add GimpPanedBox
    
    Add a new class GimpPanedBox that wraps the arrangement of widgets
    into GtkPaned hierarchies. It takes over the separator management from
    GimpDock and the GtkPaned management from
    gimpwidgets-utils.[ch]. GimpPanedBox can be both vertically and
    horizontally oriented.
    
    Change GimpDock to use this widget and make some other minor
    adaptations.

 app/widgets/Makefile.am         |    2 +
 app/widgets/gimpdock.c          |  109 ++-----------
 app/widgets/gimpdock.h          |    4 -
 app/widgets/gimpdockbook.c      |   28 +++-
 app/widgets/gimppanedbox.c      |  324 +++++++++++++++++++++++++++++++++++++++
 app/widgets/gimppanedbox.h      |   74 +++++++++
 app/widgets/gimpwidgets-utils.c |  171 ---------------------
 app/widgets/gimpwidgets-utils.h |    8 -
 app/widgets/widgets-types.h     |    1 +
 9 files changed, 436 insertions(+), 285 deletions(-)
---
diff --git a/app/widgets/Makefile.am b/app/widgets/Makefile.am
index 8fc196a..ead3c35 100644
--- a/app/widgets/Makefile.am
+++ b/app/widgets/Makefile.am
@@ -222,6 +222,8 @@ libappwidgets_a_sources = \
 	gimpoverlaychild.c		\
 	gimpoverlaychild.h		\
 	gimppaletteeditor.c		\
+	gimppanedbox.c			\
+	gimppanedbox.h			\
 	gimppaletteeditor.h		\
 	gimppaletteselect.c		\
 	gimppaletteselect.h		\
diff --git a/app/widgets/gimpdock.c b/app/widgets/gimpdock.c
index 8ff5cc1..0119b2b 100644
--- a/app/widgets/gimpdock.c
+++ b/app/widgets/gimpdock.c
@@ -35,6 +35,7 @@
 #include "gimpdockable.h"
 #include "gimpdockbook.h"
 #include "gimpdockseparator.h"
+#include "gimppanedbox.h"
 #include "gimpuimanager.h"
 #include "gimpwidgets-utils.h"
 
@@ -66,12 +67,9 @@ struct _GimpDockPrivate
   GimpUIManager     *ui_manager;
 
   GtkWidget         *main_vbox;
-  GtkWidget         *vbox;
+  GtkWidget         *paned_vbox;
 
   GList             *dockbooks;
-
-  GtkWidget         *north_separator;
-  GtkWidget         *south_separator;
 };
 
 
@@ -83,7 +81,6 @@ static void      gimp_dock_get_property      (GObject               *object,
                                               guint                  property_id,
                                               GValue                *value,
                                               GParamSpec            *pspec);
-static void      gimp_dock_finalize          (GObject               *object);
 
 static void      gimp_dock_destroy           (GtkObject             *object);
 
@@ -94,8 +91,6 @@ static void      gimp_dock_real_book_removed (GimpDock              *dock,
 static gboolean  gimp_dock_dropped_cb        (GimpDockSeparator     *separator,
                                               GtkWidget             *source,
                                               gpointer               data);
-static void      gimp_dock_show_separators   (GimpDock              *dock,
-                                              gboolean               show);
 
 
 G_DEFINE_TYPE (GimpDock, gimp_dock, GTK_TYPE_VBOX)
@@ -104,9 +99,6 @@ G_DEFINE_TYPE (GimpDock, gimp_dock, GTK_TYPE_VBOX)
 
 static guint dock_signals[LAST_SIGNAL] = { 0 };
 
-/* Keep the list of instance for gimp_dock_class_show_separators() */
-static GList *dock_instances = NULL;
-
 
 static void
 gimp_dock_class_init (GimpDockClass *klass)
@@ -154,7 +146,6 @@ gimp_dock_class_init (GimpDockClass *klass)
 
   object_class->set_property     = gimp_dock_set_property;
   object_class->get_property     = gimp_dock_get_property;
-  object_class->finalize         = gimp_dock_finalize;
 
   gtk_object_class->destroy      = gimp_dock_destroy;
 
@@ -196,30 +187,17 @@ gimp_dock_init (GimpDock *dock)
                                          GimpDockPrivate);
   dock->p->context        = NULL;
   dock->p->dialog_factory = NULL;
-  dock->p->dockbooks      = NULL;
 
   dock->p->main_vbox = gtk_vbox_new (FALSE, 0);
   gtk_container_add (GTK_CONTAINER (dock), dock->p->main_vbox);
   gtk_widget_show (dock->p->main_vbox);
 
-  dock->p->vbox = gtk_vbox_new (FALSE, 0);
-  gtk_container_add (GTK_CONTAINER (dock->p->main_vbox), dock->p->vbox);
-  gtk_widget_show (dock->p->vbox);
-
-  dock->p->north_separator = gimp_dock_separator_new (GTK_ANCHOR_NORTH);
-  gimp_dock_separator_set_dropped_cb (GIMP_DOCK_SEPARATOR (dock->p->north_separator),
-                                      gimp_dock_dropped_cb,
-                                      dock);
-  dock->p->south_separator = gimp_dock_separator_new (GTK_ANCHOR_SOUTH);
-  gimp_dock_separator_set_dropped_cb (GIMP_DOCK_SEPARATOR (dock->p->north_separator),
-                                      gimp_dock_dropped_cb,
-                                      dock);
-  gtk_box_pack_start (GTK_BOX (dock->p->vbox), dock->p->north_separator,
-                      FALSE, FALSE, 0);
-  gtk_box_pack_end (GTK_BOX (dock->p->vbox), dock->p->south_separator,
-                    FALSE, FALSE, 0);
-
-  dock_instances = g_list_prepend (dock_instances, dock);
+  dock->p->paned_vbox = gimp_paned_box_new (FALSE, 0, GTK_ORIENTATION_VERTICAL);
+  gimp_paned_box_set_dropped_cb (GIMP_PANED_BOX (dock->p->paned_vbox),
+                                 gimp_dock_dropped_cb,
+                                 dock);
+  gtk_container_add (GTK_CONTAINER (dock->p->main_vbox), dock->p->paned_vbox);
+  gtk_widget_show (dock->p->paned_vbox);
 }
 
 static void
@@ -279,12 +257,6 @@ gimp_dock_get_property (GObject    *object,
 }
 
 static void
-gimp_dock_finalize (GObject *object)
-{
-  dock_instances = g_list_remove (dock_instances, object);
-}
-
-static void
 gimp_dock_destroy (GtkObject *object)
 {
   GimpDock *dock = GIMP_DOCK (object);
@@ -379,28 +351,6 @@ gimp_dock_dropped_cb (GimpDockSeparator *separator,
   return TRUE;
 }
 
-static void
-gimp_dock_show_separators (GimpDock *dock,
-                           gboolean  show)
-{
-  if (show)
-    {
-      gtk_widget_show (dock->p->north_separator);
-
-      /* Only show the south separator if there are any dockbooks */
-      if (g_list_length (dock->p->dockbooks) > 0)
-        gtk_widget_show (dock->p->south_separator);
-    }
-  else /* (! show) */
-    {
-      /* Hide separators unconditionally so we can handle the case
-       * where we remove the last dockbook while separators are shown
-       */
-      gtk_widget_hide (dock->p->north_separator);
-      gtk_widget_hide (dock->p->south_separator);
-    }
-}
-
 /*  public functions  */
 
 void
@@ -548,7 +498,7 @@ gimp_dock_get_vbox (GimpDock *dock)
 {
   g_return_val_if_fail (GIMP_IS_DOCK (dock), NULL);
 
-  return dock->p->vbox;
+  return dock->p->paned_vbox;
 }
 
 void
@@ -591,13 +541,10 @@ gimp_dock_add_book (GimpDock     *dock,
 
   gimp_dockbook_set_dock (dockbook, dock);
 
-  /* Add the dockbook to the hierarchy of GtkPaned:s */
-  gimp_widgets_add_paned_widget (GTK_BOX (dock->p->vbox),
-                                 &dock->p->dockbooks,
-                                 dock->p->south_separator,
-                                 GTK_WIDGET (dockbook),
-                                 index);
-
+  dock->p->dockbooks = g_list_prepend (dock->p->dockbooks, dockbook);
+  gimp_paned_box_add_widget (GIMP_PANED_BOX (dock->p->paned_vbox),
+                             GTK_WIDGET (dockbook),
+                             index);
   gtk_widget_show (GTK_WIDGET (dockbook));
 
   g_signal_emit (dock, dock_signals[BOOK_ADDED], 0, dockbook);
@@ -618,36 +565,12 @@ gimp_dock_remove_book (GimpDock     *dock,
    */
   g_object_ref (dockbook);
 
-  /* Now remove the dockbook from the hierarchy of GtkPaned:s */
-  gimp_widgets_remove_paned_widget (GTK_BOX (dock->p->vbox),
-                                    &dock->p->dockbooks,
-                                    GTK_WIDGET (dockbook));
+  dock->p->dockbooks = g_list_remove (dock->p->dockbooks, dockbook);
+  gimp_paned_box_remove_widget (GIMP_PANED_BOX (dock->p->paned_vbox),
+                                GTK_WIDGET (dockbook));
 
   g_signal_emit (dock, dock_signals[BOOK_REMOVED], 0, dockbook);
 
   g_object_unref (dockbook);
 }
 
-/**
- * gimp_dock_class_show_separators:
- * @klass:
- * @show:
- *
- * Show/hide the separators in all docks.
- **/
-void
-gimp_dock_class_show_separators (GimpDockClass *klass,
-                                 gboolean       show)
-{
-  GList *list;
-
-  /* Conceptually this is a class varaible */
-  g_return_if_fail (GIMP_IS_DOCK_CLASS (klass));
-
-  for (list = dock_instances; list != NULL; list = list->next)
-    {
-      GimpDock *dock = GIMP_DOCK (list->data);
-
-      gimp_dock_show_separators (dock, show);
-    }
-}
diff --git a/app/widgets/gimpdock.h b/app/widgets/gimpdock.h
index f6b308d..5e8a05a 100644
--- a/app/widgets/gimpdock.h
+++ b/app/widgets/gimpdock.h
@@ -104,8 +104,4 @@ void                gimp_dock_remove_book             (GimpDock       *dock,
                                                        GimpDockbook   *dockbook);
 
 
-void                gimp_dock_class_show_separators   (GimpDockClass  *klass,
-                                                       gboolean        show);
-
-
 #endif /* __GIMP_DOCK_H__ */
diff --git a/app/widgets/gimpdockbook.c b/app/widgets/gimpdockbook.c
index d67791e..5a6df48 100644
--- a/app/widgets/gimpdockbook.c
+++ b/app/widgets/gimpdockbook.c
@@ -41,6 +41,7 @@
 #include "gimpdockwindow.h"
 #include "gimphelp-ids.h"
 #include "gimpmenufactory.h"
+#include "gimppanedbox.h"
 #include "gimpstringaction.h"
 #include "gimpuimanager.h"
 #include "gimpview.h"
@@ -651,10 +652,14 @@ gimp_dockbook_tab_drag_begin (GtkWidget      *widget,
                               GdkDragContext *context,
                               GimpDockable   *dockable)
 {
-  GimpDockClass  *dock_class = GIMP_DOCK_GET_CLASS (dockable->dockbook->p->dock);
-  GtkWidget      *window;
-  GtkWidget      *view;
-  GtkRequisition  requisition;
+  GimpDock          *dock;
+  GimpPanedBoxClass *paned_box_class;
+  GtkWidget         *window;
+  GtkWidget         *view;
+  GtkRequisition     requisition;
+
+  dock            = GIMP_DOCK (dockable->dockbook->p->dock);
+  paned_box_class = GIMP_PANED_BOX_GET_CLASS (gimp_dock_get_vbox (dock));
 
   window = gtk_window_new (GTK_WINDOW_POPUP);
   gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DND);
@@ -684,7 +689,7 @@ gimp_dockbook_tab_drag_begin (GtkWidget      *widget,
    */
   gtk_widget_set_sensitive (GTK_WIDGET (dockable), FALSE);
 
-  gimp_dock_class_show_separators (dock_class, TRUE);
+  gimp_paned_box_class_show_separators (paned_box_class, TRUE);
 }
 
 static void
@@ -692,9 +697,14 @@ gimp_dockbook_tab_drag_end (GtkWidget      *widget,
                             GdkDragContext *context,
                             GimpDockable   *dockable)
 {
-  GimpDockClass *dock_class  = GIMP_DOCK_GET_CLASS (dockable->dockbook->p->dock);
-  GtkWidget     *drag_widget = g_object_get_data (G_OBJECT (dockable),
-                                                  "gimp-dock-drag-widget");
+  GimpDock          *dock;
+  GimpPanedBoxClass *paned_box_class;
+  GtkWidget         *drag_widget;
+
+  dock            = GIMP_DOCK (dockable->dockbook->p->dock);
+  paned_box_class = GIMP_PANED_BOX_GET_CLASS (gimp_dock_get_vbox (dock));
+  drag_widget     = g_object_get_data (G_OBJECT (dockable),
+                                       "gimp-dock-drag-widget");
 
   /*  finding the drag_widget means the drop was not successful, so
    *  pop up a new dock and move the dockable there
@@ -709,7 +719,7 @@ gimp_dockbook_tab_drag_end (GtkWidget      *widget,
   dockable->drag_y = GIMP_DOCKABLE_DRAG_OFFSET;
   gtk_widget_set_sensitive (GTK_WIDGET (dockable), TRUE);
 
-  gimp_dock_class_show_separators (dock_class, FALSE);
+  gimp_paned_box_class_show_separators (paned_box_class, FALSE);
 }
 
 
diff --git a/app/widgets/gimppanedbox.c b/app/widgets/gimppanedbox.c
new file mode 100644
index 0000000..c1b4da5
--- /dev/null
+++ b/app/widgets/gimppanedbox.c
@@ -0,0 +1,324 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimppanedbox.c
+ * Copyright (C) 2001-2005 Michael Natterer <mitch gimp org>
+ * Copyright (C)      2009 Martin Nordholts <martinn src gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+
+#include "widgets-types.h"
+
+#include "gimpdockseparator.h"
+#include "gimppanedbox.h"
+
+
+struct _GimpPanedBoxPrivate
+{
+  /* Widgets that are separated by panes */
+  GList     *widgets;
+
+  /* Supports drag & drop rearrangement of widgets */
+  GtkWidget *first_separator;
+  GtkWidget *last_separator;
+};
+
+
+static void      gimp_paned_box_finalize          (GObject               *object);
+
+
+G_DEFINE_TYPE (GimpPanedBox, gimp_paned_box, GTK_TYPE_BOX)
+
+#define parent_class gimp_paned_box_parent_class
+
+
+/* Keep the list of instance for gimp_dock_class_show_separators() */
+static GList *paned_box_instances = NULL;
+
+
+static void
+gimp_paned_box_class_init (GimpPanedBoxClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gimp_paned_box_finalize;
+
+  g_type_class_add_private (klass, sizeof (GimpPanedBoxPrivate));
+}
+
+static void
+gimp_paned_box_init (GimpPanedBox *paned_box)
+{
+  paned_box->p = G_TYPE_INSTANCE_GET_PRIVATE (paned_box,
+                                              GIMP_TYPE_PANED_BOX,
+                                              GimpPanedBoxPrivate);
+
+  paned_box->p->first_separator = gimp_dock_separator_new (GTK_ANCHOR_NORTH);
+  paned_box->p->last_separator = gimp_dock_separator_new (GTK_ANCHOR_SOUTH);
+
+  gtk_box_pack_start (GTK_BOX (paned_box), paned_box->p->first_separator,
+                      FALSE, FALSE, 0);
+  gtk_box_pack_end (GTK_BOX (paned_box), paned_box->p->last_separator,
+                    FALSE, FALSE, 0);
+
+  paned_box_instances = g_list_prepend (paned_box_instances, paned_box);
+}
+
+static void
+gimp_paned_box_finalize (GObject *object)
+{
+  paned_box_instances = g_list_remove (paned_box_instances, object);
+}
+
+
+GtkWidget *
+gimp_paned_box_new (gboolean       homogeneous,
+                    gint           spacing,
+                    GtkOrientation orientation)
+{
+  return g_object_new (GIMP_TYPE_PANED_BOX,
+                       "homogeneous",  homogeneous,
+                       "spacing",      0,
+                       "orientation",  orientation,
+                       NULL);
+}
+
+void
+gimp_paned_box_set_dropped_cb (GimpPanedBox                 *paned_box,
+                               GimpDockSeparatorDroppedFunc  dropped_cb,
+                               gpointer                      dropped_cb_data)
+{
+  g_return_if_fail (GIMP_IS_PANED_BOX (paned_box));
+
+  gimp_dock_separator_set_dropped_cb (GIMP_DOCK_SEPARATOR (paned_box->p->first_separator),
+                                      dropped_cb,
+                                      dropped_cb_data);
+  gimp_dock_separator_set_dropped_cb (GIMP_DOCK_SEPARATOR (paned_box->p->last_separator),
+                                      dropped_cb,
+                                      dropped_cb_data);
+}
+
+/**
+ * gimp_paned_box_add_widget:
+ * @paned_box: A #GimpPanedBox
+ * @widget:    The #GtkWidget to add
+ * @index:     Where to add the @widget
+ *
+ * Add a #GtkWidget to the #GimpPanedBox in a hierarchy of #GtkPaned:s
+ * so the space can be manually distributed between the widgets.
+ **/
+void
+gimp_paned_box_add_widget (GimpPanedBox *paned_box,
+                           GtkWidget    *widget,
+                           gint          index)
+{
+  gint old_length = 0;
+
+  g_return_if_fail (GIMP_IS_PANED_BOX (paned_box));
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  /* Calculate length */
+  old_length = g_list_length (paned_box->p->widgets);
+
+  /* If index is invalid append at the end */
+  if (index >= old_length || index < 0)
+    {
+      index = old_length;
+    }
+
+  /* Insert into the list */
+  paned_box->p->widgets = g_list_insert (paned_box->p->widgets, widget, index);
+
+  /* Insert into the GtkPaned hierarchy */
+  if (old_length == 0)
+    {
+      gtk_box_pack_start (GTK_BOX (paned_box), widget, TRUE, TRUE, 0);
+
+      /* Keep the desired widget at the end */
+      if (paned_box->p->last_separator)
+        gtk_box_reorder_child (GTK_BOX (paned_box),
+                               paned_box->p->last_separator,
+                               -1);
+    }
+  else
+    {
+      GtkWidget *old_widget;
+      GtkWidget *parent;
+      GtkWidget *paned;
+
+      /* Figure out what widget to detach */
+      if (index == 0)
+        {
+          old_widget = g_list_nth_data (paned_box->p->widgets, index + 1);
+        }
+      else
+        {
+          old_widget = g_list_nth_data (paned_box->p->widgets, index - 1);
+        }
+
+      parent = gtk_widget_get_parent (old_widget);
+
+      if (old_length > 1 && index > 0)
+        {
+          GtkWidget *grandparent = gtk_widget_get_parent (parent);
+
+          old_widget = parent;
+          parent     = grandparent;
+        }
+
+      /* Deatch the widget and bulid up a new hierarchy */
+      g_object_ref (old_widget);
+      gtk_container_remove (GTK_CONTAINER (parent), old_widget);
+
+      paned = gtk_vpaned_new ();
+      if (GTK_IS_VPANED (parent))
+        {
+          gtk_paned_pack1 (GTK_PANED (parent), paned, TRUE, FALSE);
+        }
+      else
+        {
+          gtk_box_pack_start (GTK_BOX (parent), paned, TRUE, TRUE, 0);
+        }
+      gtk_widget_show (paned);
+
+      if (index == 0)
+        {
+          gtk_paned_pack1 (GTK_PANED (paned), widget,
+                           TRUE, FALSE);
+          gtk_paned_pack2 (GTK_PANED (paned), old_widget,
+                           TRUE, FALSE);
+        }
+      else
+        {
+          gtk_paned_pack1 (GTK_PANED (paned), old_widget,
+                           TRUE, FALSE);
+          gtk_paned_pack2 (GTK_PANED (paned), widget,
+                           TRUE, FALSE);
+        }
+
+      g_object_unref (old_widget);
+    }
+}
+
+/**
+ * gimp_paned_box_remove_widget:
+ * @paned_box: A #GimpPanedBox
+ * @widget:    The #GtkWidget to remove
+ *
+ * Remove a #GtkWidget from a #GimpPanedBox added with
+ * gimp_widgets_add_paned_widget().
+ **/
+void
+gimp_paned_box_remove_widget (GimpPanedBox *paned_box,
+                              GtkWidget    *widget)
+{
+  gint       old_length   = 0;
+  gint       index        = 0;
+  GtkWidget *other_widget = NULL;
+  GtkWidget *parent       = NULL;
+  GtkWidget *grandparent  = NULL;
+
+  g_return_if_fail (GIMP_IS_PANED_BOX (paned_box));
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  /* Calculate length and index */
+  old_length = g_list_length (paned_box->p->widgets);
+  index      = g_list_index (paned_box->p->widgets, widget);
+
+  /* Remove from list */
+  paned_box->p->widgets = g_list_remove (paned_box->p->widgets, widget);
+
+  /* Remove from widget hierarchy */
+  if (old_length == 1)
+    {
+      gtk_container_remove (GTK_CONTAINER (paned_box), widget);
+    }
+  else
+    {
+      g_object_ref (widget);
+
+      parent      = gtk_widget_get_parent (GTK_WIDGET (widget));
+      grandparent = gtk_widget_get_parent (parent);
+
+      if (index == 0)
+        other_widget = gtk_paned_get_child2 (GTK_PANED (parent));
+      else
+        other_widget = gtk_paned_get_child1 (GTK_PANED (parent));
+
+      g_object_ref (other_widget);
+
+      gtk_container_remove (GTK_CONTAINER (parent), other_widget);
+      gtk_container_remove (GTK_CONTAINER (parent), GTK_WIDGET (widget));
+
+      gtk_container_remove (GTK_CONTAINER (grandparent), parent);
+
+      if (GTK_IS_VPANED (grandparent))
+        gtk_paned_pack1 (GTK_PANED (grandparent), other_widget, TRUE, FALSE);
+      else
+        gtk_box_pack_start (GTK_BOX (paned_box), other_widget, TRUE, TRUE, 0);
+
+      g_object_unref (other_widget);
+    }
+}
+
+void
+gimp_paned_box_show_separators (GimpPanedBox *paned_box,
+                                gboolean      show)
+{
+  if (show)
+    {
+      gtk_widget_show (paned_box->p->first_separator);
+
+      /* Only show the south separator if there are any widgets */
+      if (g_list_length (paned_box->p->widgets) > 0)
+        gtk_widget_show (paned_box->p->last_separator);
+    }
+  else /* (! show) */
+    {
+      /* Hide separators unconditionally so we can handle the case
+       * where we remove the last dockbook while separators are shown
+       */
+      gtk_widget_hide (paned_box->p->first_separator);
+      gtk_widget_hide (paned_box->p->last_separator);
+    }
+}
+
+
+/**
+ * gimp_dock_class_show_separators:
+ * @klass:
+ * @show:
+ *
+ * Show/hide the separators in all docks.
+ **/
+void
+gimp_paned_box_class_show_separators (GimpPanedBoxClass *klass,
+                                      gboolean           show)
+{
+  GList *list;
+
+  /* Conceptually this is a class varaible */
+  g_return_if_fail (GIMP_IS_PANED_BOX_CLASS (klass));
+
+  for (list = paned_box_instances; list != NULL; list = list->next)
+    {
+      GimpPanedBox *paned_box = GIMP_PANED_BOX (list->data);
+      gimp_paned_box_show_separators (paned_box, show);
+    }
+}
diff --git a/app/widgets/gimppanedbox.h b/app/widgets/gimppanedbox.h
new file mode 100644
index 0000000..6fd1782
--- /dev/null
+++ b/app/widgets/gimppanedbox.h
@@ -0,0 +1,74 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimppanedbox.h
+ * Copyright (C) 2001-2005 Michael Natterer <mitch gimp org>
+ * Copyright (C)      2009 Martin Nordholts <martinn src gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_PANED_BOX_H__
+#define __GIMP_PANED_BOX_H__
+
+
+#define GIMP_TYPE_PANED_BOX            (gimp_paned_box_get_type ())
+#define GIMP_PANED_BOX(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PANED_BOX, GimpPanedBox))
+#define GIMP_PANED_BOX_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PANED_BOX, GimpPanedBoxClass))
+#define GIMP_IS_PANED_BOX(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_PANED_BOX))
+#define GIMP_IS_PANED_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PANED_BOX))
+#define GIMP_PANED_BOX_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PANED_BOX, GimpPanedBoxClass))
+
+
+typedef struct _GimpPanedBoxClass    GimpPanedBoxClass;
+typedef struct _GimpPanedBoxPrivate  GimpPanedBoxPrivate;
+
+/**
+ * GimpPanedBox:
+ *
+ * A #GtkBox with the children separated by #GtkPaned:s and basic
+ * docking mechanisms.
+ */
+struct _GimpPanedBox
+{
+  GtkBox parent_instance;
+
+  GimpPanedBoxPrivate *p;
+};
+
+struct _GimpPanedBoxClass
+{
+  GtkBoxClass parent_class;
+};
+
+
+GType               gimp_paned_box_get_type              (void) G_GNUC_CONST;
+GtkWidget         * gimp_paned_box_new                   (gboolean                      homogeneous,
+                                                          gint                          spacing,
+                                                          GtkOrientation                orientation);
+void                gimp_paned_box_set_dropped_cb        (GimpPanedBox                 *paned_box,
+                                                          GimpDockSeparatorDroppedFunc  dropped_cb,
+                                                          gpointer                      dropped_cb_data);
+void                gimp_paned_box_add_widget            (GimpPanedBox                 *paned_box,
+                                                          GtkWidget                    *widget,
+                                                          gint                          index);
+void                gimp_paned_box_remove_widget         (GimpPanedBox                 *paned_box,
+                                                          GtkWidget                    *widget);
+void                gimp_paned_box_show_separators       (GimpPanedBox                 *dock,
+                                                          gboolean                      show);
+void                gimp_paned_box_class_show_separators (GimpPanedBoxClass            *klass,
+                                                          gboolean                      show);
+
+
+#endif /* __GIMP_PANED_BOX_H__ */
diff --git a/app/widgets/gimpwidgets-utils.c b/app/widgets/gimpwidgets-utils.c
index 28010f0..2ac244d 100644
--- a/app/widgets/gimpwidgets-utils.c
+++ b/app/widgets/gimpwidgets-utils.c
@@ -1167,174 +1167,3 @@ gimp_pango_layout_set_weight (PangoLayout *layout,
   pango_layout_set_attributes (layout, attrs);
   pango_attr_list_unref (attrs);
 }
-
-/**
- * gimp_widgets_add_paned_widget:
- * @box:                  A #GtkBox
- * @box_widget_list:      List of current widgets in the @box
- * @box_widget_keep_last: The widget to keep last in the @box
- * @widget:               The #GtkWidget to add
- * @index:                Where to add the @widget
- *
- * Add a #GtkWidget to a #GtkBox in a hierarchy of #GtkPaned:s so the
- * space can be manually distributed between the widgets.
- **/
-void
-gimp_widgets_add_paned_widget (GtkBox     *box,
-                               GList     **box_widget_list,
-                               GtkWidget  *box_widget_keep_last,
-                               GtkWidget  *widget,
-                               gint        index)
-{
-  gint old_length = 0;
-
-  g_return_if_fail (GTK_IS_BOX (box));
-  g_return_if_fail (box_widget_list != NULL);
-  g_return_if_fail (GTK_IS_WIDGET (box_widget_keep_last) ||
-                    box_widget_keep_last == NULL);
-  g_return_if_fail (GTK_IS_WIDGET (widget));
-
-  /* Calculate length */
-  old_length = g_list_length (*box_widget_list);
-
-  /* If index is invalid append at the end */
-  if (index >= old_length || index < 0)
-    {
-      index = old_length;
-    }
-
-  /* Insert into the list */
-  *box_widget_list = g_list_insert (*box_widget_list, widget, index);
-
-  /* Insert into the GtkPaned hierarchy */
-  if (old_length == 0)
-    {
-      gtk_box_pack_start (box, widget, TRUE, TRUE, 0);
-
-      /* Keep the desired widget at the end */
-      if (box_widget_keep_last)
-        gtk_box_reorder_child (box, box_widget_keep_last, -1);
-    }
-  else
-    {
-      GtkWidget *old_widget;
-      GtkWidget *parent;
-      GtkWidget *paned;
-
-      /* Figure out what widget to detach */
-      if (index == 0)
-        {
-          old_widget = g_list_nth_data (*box_widget_list, index + 1);
-        }
-      else
-        {
-          old_widget = g_list_nth_data (*box_widget_list, index - 1);
-        }
-
-      parent = gtk_widget_get_parent (old_widget);
-
-      if (old_length > 1 && index > 0)
-        {
-          GtkWidget *grandparent = gtk_widget_get_parent (parent);
-
-          old_widget = parent;
-          parent     = grandparent;
-        }
-
-      /* Deatch the widget and bulid up a new hierarchy */
-      g_object_ref (old_widget);
-      gtk_container_remove (GTK_CONTAINER (parent), old_widget);
-
-      paned = gtk_vpaned_new ();
-      if (GTK_IS_VPANED (parent))
-        {
-          gtk_paned_pack1 (GTK_PANED (parent), paned, TRUE, FALSE);
-        }
-      else
-        {
-          gtk_box_pack_start (GTK_BOX (parent), paned, TRUE, TRUE, 0);
-        }
-      gtk_widget_show (paned);
-
-      if (index == 0)
-        {
-          gtk_paned_pack1 (GTK_PANED (paned), widget,
-                           TRUE, FALSE);
-          gtk_paned_pack2 (GTK_PANED (paned), old_widget,
-                           TRUE, FALSE);
-        }
-      else
-        {
-          gtk_paned_pack1 (GTK_PANED (paned), old_widget,
-                           TRUE, FALSE);
-          gtk_paned_pack2 (GTK_PANED (paned), widget,
-                           TRUE, FALSE);
-        }
-
-      g_object_unref (old_widget);
-    }
-}
-
-/**
- * gimp_widgets_remove_paned_widget:
- * @box:             A #GtkBox
- * @box_widget_list: Pointer to list of current widgets in the @box
- * @widget:          The #GtkWidget to remove
- *
- * Remove a #GtkWidget from a #GtkBox added with
- * gimp_widgets_add_paned_widget().
- **/
-void
-gimp_widgets_remove_paned_widget (GtkBox     *box,
-                                  GList     **box_widget_list,
-                                  GtkWidget  *widget)
-{
-  gint       old_length   = 0;
-  gint       index        = 0;
-  GtkWidget *other_widget = NULL;
-  GtkWidget *parent       = NULL;
-  GtkWidget *grandparent  = NULL;
-
-  g_return_if_fail (GTK_IS_BOX (box));
-  g_return_if_fail (GTK_IS_WIDGET (widget));
-  g_return_if_fail (box_widget_list);
-
-  /* Calculate length and index */
-  old_length = g_list_length (*box_widget_list);
-  index      = g_list_index (*box_widget_list, widget);
-
-  /* Remove from list */
-  *box_widget_list = g_list_remove (*box_widget_list, widget);
-
-  /* Remove from widget hierarchy */
-  if (old_length == 1)
-    {
-      gtk_container_remove (GTK_CONTAINER (box), widget);
-    }
-  else
-    {
-      g_object_ref (widget);
-
-      parent      = gtk_widget_get_parent (GTK_WIDGET (widget));
-      grandparent = gtk_widget_get_parent (parent);
-
-      if (index == 0)
-        other_widget = gtk_paned_get_child2 (GTK_PANED (parent));
-      else
-        other_widget = gtk_paned_get_child1 (GTK_PANED (parent));
-
-      g_object_ref (other_widget);
-
-      gtk_container_remove (GTK_CONTAINER (parent), other_widget);
-      gtk_container_remove (GTK_CONTAINER (parent), GTK_WIDGET (widget));
-
-      gtk_container_remove (GTK_CONTAINER (grandparent), parent);
-
-      if (GTK_IS_VPANED (grandparent))
-        gtk_paned_pack1 (GTK_PANED (grandparent), other_widget, TRUE, FALSE);
-      else
-        gtk_box_pack_start (box, other_widget, TRUE, TRUE, 0);
-
-      g_object_unref (other_widget);
-    }
-}
diff --git a/app/widgets/gimpwidgets-utils.h b/app/widgets/gimpwidgets-utils.h
index 51b6f8c..7c14256 100644
--- a/app/widgets/gimpwidgets-utils.h
+++ b/app/widgets/gimpwidgets-utils.h
@@ -87,14 +87,6 @@ void              gimp_pango_layout_set_scale      (PangoLayout          *layout
                                                     double                scale);
 void              gimp_pango_layout_set_weight     (PangoLayout          *layout,
                                                     PangoWeight           weight);
-void              gimp_widgets_add_paned_widget    (GtkBox               *box,
-                                                    GList               **box_widget_list,
-                                                    GtkWidget            *box_widget_keep_last,
-                                                    GtkWidget            *widget,
-                                                    gint                  index);
-void              gimp_widgets_remove_paned_widget (GtkBox               *box,
-                                                    GList               **box_widget_list,
-                                                    GtkWidget            *widget);
 
 
 #endif /* __GIMP_WIDGETS_UTILS_H__ */
diff --git a/app/widgets/widgets-types.h b/app/widgets/widgets-types.h
index 997fb42..188ebde 100644
--- a/app/widgets/widgets-types.h
+++ b/app/widgets/widgets-types.h
@@ -45,6 +45,7 @@ typedef struct _GimpToolbox                  GimpToolbox;
 typedef struct _GimpDockbook                 GimpDockbook;
 typedef struct _GimpDockable                 GimpDockable;
 typedef struct _GimpDocked                   GimpDocked; /* dummy typedef */
+typedef struct _GimpPanedBox                 GimpPanedBox;
 
 
 /*  GimpEditor widgets  */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]