From eb9b365864e0d40e396614e55b490f402e64f7bb Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 24 Oct 2009 18:52:48 +0200 Subject: [PATCH] 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(-) create mode 100644 app/widgets/gimppanedbox.c create mode 100644 app/widgets/gimppanedbox.h diff --git a/app/widgets/Makefile.am b/app/widgets/Makefile.am index 8fc196a676..ead3c35db9 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 8ff5cc129c..0119b2b4f7 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 @@ -278,12 +256,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) { @@ -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 f6b308dbbf..5e8a05adb6 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 d67791e150..5a6df48444 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 0000000000..c1b4da5743 --- /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 + * Copyright (C) 2009 Martin Nordholts + * + * 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 . + */ + +#include "config.h" + +#include + +#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 0000000000..6fd17821ee --- /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 + * Copyright (C) 2009 Martin Nordholts + * + * 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 . + */ + +#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 28010f08cd..2ac244db68 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 51b6f8ca97..7c1425663b 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 997fb427d9..188ebdea8b 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 */