From 4f7693acf061e678bcbb4cc07adc59aade72640c Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 26 Sep 2009 16:21:10 +0200 Subject: [PATCH] app: Make GimpDock a GtkVBox Make GimpDock be a GtkVBox instead of a GimpDockWindow. This means we can now put a GimpDock anywhere, including inside an image window. In order to do this we need to: * Separate dock and dock window creation in the dialog factory and add a couple of new dock window constructors * Change gimp_dialog_factory_dock_new() to not only create a dock, but also create a dock window and then combine those two * Change the dock constructor to take a GimpUIManager since they depend on that during their construction. We get the ui manager from the dock window, but we can't create the dock *inside* the dock window, we have to add the dock later. So we create the dock window first and then pass its ui manager to the dock constructors * Make some other minor adaptions, mostly with gimp_dock_window_from_dock() and gimp_dock_window_get_dock() --- app/dialogs/dialogs-constructors.c | 35 ++++++++++++++++++++-- app/dialogs/dialogs-constructors.h | 7 +++++ app/dialogs/dialogs.c | 9 ++++++ app/widgets/gimpdialogfactory.c | 47 +++++++++++++++++++++++------- app/widgets/gimpdialogfactory.h | 11 +++++-- app/widgets/gimpdock.c | 2 +- app/widgets/gimpdock.h | 9 ++---- app/widgets/gimpdockable.c | 12 +++++--- app/widgets/gimpdockwindow.c | 23 +++++++++------ app/widgets/gimpmenudock.c | 4 --- app/widgets/gimpsessioninfo-dock.c | 12 +++++--- app/widgets/gimptoolbox.c | 14 ++++----- app/widgets/gimptoolbox.h | 3 +- 13 files changed, 134 insertions(+), 54 deletions(-) diff --git a/app/dialogs/dialogs-constructors.c b/app/dialogs/dialogs-constructors.c index e71493cafc..8e8ee76152 100644 --- a/app/dialogs/dialogs-constructors.c +++ b/app/dialogs/dialogs-constructors.c @@ -44,6 +44,7 @@ #include "widgets/gimpdevicestatus.h" #include "widgets/gimpdialogfactory.h" #include "widgets/gimpdockable.h" +#include "widgets/gimpdockwindow.h" #include "widgets/gimpdocumentview.h" #include "widgets/gimperrorconsole.h" #include "widgets/gimperrordialog.h" @@ -215,25 +216,53 @@ dialogs_quit_get (GimpDialogFactory *factory, GtkWidget * dialogs_toolbox_get (GimpDialogFactory *factory, GimpContext *context, - gint view_size) + GimpUIManager *ui_manager) { /* we pass "global_dock_factory", _not_ "global_toolbox_factory" to * the toolbox constructor, because the global_toolbox_factory has no * dockables registered */ - return gimp_toolbox_new (global_dock_factory, context); + return gimp_toolbox_new (global_dock_factory, + context, + ui_manager); +} + +GtkWidget * +dialogs_toolbox_dock_window_new (GimpDialogFactory *factory, + GimpContext *context, + gint view_size) +{ + return g_object_new (GIMP_TYPE_DOCK_WINDOW, + "role", "gimp-toolbox", + "ui-manager-name", "", + "gimp-dialog-factory", factory, + "gimp-context", context, + NULL); } GtkWidget * dialogs_dock_new (GimpDialogFactory *factory, GimpContext *context, - gint view_size) + GimpUIManager *ui_manager) { return gimp_menu_dock_new (factory, context->gimp->images, context->gimp->displays); } +GtkWidget * +dialogs_dock_window_new (GimpDialogFactory *factory, + GimpContext *context, + gint view_size) +{ + return g_object_new (GIMP_TYPE_DOCK_WINDOW, + "role", "gimp-dock", + "ui-manager-name", "", + "gimp-dialog-factory", factory, + "gimp-context", context, + NULL); +} + /***************/ /* dockables */ diff --git a/app/dialogs/dialogs-constructors.h b/app/dialogs/dialogs-constructors.h index 1c36024353..6f190fcced 100644 --- a/app/dialogs/dialogs-constructors.h +++ b/app/dialogs/dialogs-constructors.h @@ -68,9 +68,16 @@ GtkWidget * dialogs_quit_get (GimpDialogFactory *factory, /* docks */ GtkWidget * dialogs_toolbox_get (GimpDialogFactory *factory, + GimpContext *context, + GimpUIManager *ui_manager); +GtkWidget * dialogs_toolbox_dock_window_new + (GimpDialogFactory *factory, GimpContext *context, gint view_size); GtkWidget * dialogs_dock_new (GimpDialogFactory *factory, + GimpContext *context, + GimpUIManager *ui_manager); +GtkWidget * dialogs_dock_window_new (GimpDialogFactory *factory, GimpContext *context, gint view_size); diff --git a/app/dialogs/dialogs.c b/app/dialogs/dialogs.c index dcd9900e10..8a9670e0d9 100644 --- a/app/dialogs/dialogs.c +++ b/app/dialogs/dialogs.c @@ -245,12 +245,14 @@ dialogs_init (Gimp *gimp, g_return_if_fail (GIMP_IS_GIMP (gimp)); g_return_if_fail (GIMP_IS_MENU_FACTORY (menu_factory)); + /* Toplevel */ global_dialog_factory = gimp_dialog_factory_new ("toplevel", gimp_get_user_context (gimp), menu_factory, NULL, TRUE); + /* Toolbox */ global_toolbox_factory = gimp_dialog_factory_new ("toolbox", gimp_get_user_context (gimp), menu_factory, @@ -258,7 +260,10 @@ dialogs_init (Gimp *gimp, TRUE); gimp_dialog_factory_set_constructor (global_toolbox_factory, dialogs_dockable_constructor); + gimp_dialog_factory_set_dock_window_func (global_toolbox_factory, + dialogs_toolbox_dock_window_new); + /* Dock */ global_dock_factory = gimp_dialog_factory_new ("dock", gimp_get_user_context (gimp), menu_factory, @@ -266,13 +271,17 @@ dialogs_init (Gimp *gimp, TRUE); gimp_dialog_factory_set_constructor (global_dock_factory, dialogs_dockable_constructor); + gimp_dialog_factory_set_dock_window_func (global_dock_factory, + dialogs_dock_window_new); + /* Display */ global_display_factory = gimp_dialog_factory_new ("display", gimp_get_user_context (gimp), menu_factory, NULL, FALSE); + for (i = 0; i < G_N_ELEMENTS (toplevel_entries); i++) gimp_dialog_factory_register_entry (global_dialog_factory, toplevel_entries[i].identifier, diff --git a/app/widgets/gimpdialogfactory.c b/app/widgets/gimpdialogfactory.c index f06240660c..c9bea5e14a 100644 --- a/app/widgets/gimpdialogfactory.c +++ b/app/widgets/gimpdialogfactory.c @@ -242,11 +242,11 @@ gimp_dialog_factory_finalize (GObject *object) } GimpDialogFactory * -gimp_dialog_factory_new (const gchar *name, - GimpContext *context, - GimpMenuFactory *menu_factory, - GimpDialogNewFunc new_dock_func, - gboolean toggle_visibility) +gimp_dialog_factory_new (const gchar *name, + GimpContext *context, + GimpMenuFactory *menu_factory, + GimpDialogNewDockFunc new_dock_func, + gboolean toggle_visibility) { GimpDialogFactory *factory; gpointer key; @@ -318,6 +318,16 @@ gimp_dialog_factory_set_constructor (GimpDialogFactory *factory, factory->constructor = constructor; } +void +gimp_dialog_factory_set_dock_window_func (GimpDialogFactory *factory, + GimpDialogNewFunc new_dock_window_func) +{ + g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory)); + g_return_if_fail (new_dock_window_func != NULL); + + factory->new_dock_window_func = new_dock_window_func; +} + void gimp_dialog_factory_register_entry (GimpDialogFactory *factory, const gchar *identifier, @@ -764,21 +774,36 @@ GtkWidget * gimp_dialog_factory_dock_new (GimpDialogFactory *factory, GdkScreen *screen) { - GtkWidget *dock; + GtkWidget *dock_window = NULL; + GtkWidget *dock = NULL; + GimpUIManager *ui_manager = NULL; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (factory), NULL); g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); g_return_val_if_fail (factory->new_dock_func != NULL, NULL); - dock = factory->new_dock_func (factory, factory->context, 0); + /* Create a dock window to put the dock in. We need to create the + * dock window before the dock because the dock has a dependnecy to + * the ui manager in the dock window + */ + dock_window = factory->new_dock_window_func (factory, + factory->context, + 0); + gtk_window_set_screen (GTK_WINDOW (dock_window), screen); + gimp_dialog_factory_set_widget_data (dock_window, factory, NULL); + + /* Create the dock */ + ui_manager = gimp_dock_window_get_ui_manager (GIMP_DOCK_WINDOW (dock_window)); + dock = factory->new_dock_func (factory, factory->context, ui_manager); if (dock) { - gtk_window_set_screen (GTK_WINDOW (dock), screen); + /* Put the dock in the dock window */ + gimp_dock_window_set_dock (GIMP_DOCK_WINDOW (dock_window), + GIMP_DOCK (dock)); - gimp_dialog_factory_set_widget_data (dock, factory, NULL); - - gimp_dialog_factory_add_dialog (factory, dock); + /* Add the dock window to the dialog factory */ + gimp_dialog_factory_add_dialog (factory, dock_window); } return dock; diff --git a/app/widgets/gimpdialogfactory.h b/app/widgets/gimpdialogfactory.h index 58fe4f51c4..c72df156f4 100644 --- a/app/widgets/gimpdialogfactory.h +++ b/app/widgets/gimpdialogfactory.h @@ -37,6 +37,9 @@ typedef enum typedef GtkWidget * (* GimpDialogNewFunc) (GimpDialogFactory *factory, GimpContext *context, gint view_size); +typedef GtkWidget * (* GimpDialogNewDockFunc) (GimpDialogFactory *factory, + GimpContext *context, + GimpUIManager *ui_manager); typedef GtkWidget * (* GimpDialogConstructor) (GimpDialogFactory *factory, GimpDialogFactoryEntry *entry, GimpContext *context, @@ -84,7 +87,8 @@ struct _GimpDialogFactory GimpMenuFactory *menu_factory; /*< private >*/ - GimpDialogNewFunc new_dock_func; + GimpDialogNewFunc new_dock_window_func; + GimpDialogNewDockFunc new_dock_func; GimpDialogConstructor constructor; GList *registered_dialogs; @@ -112,13 +116,16 @@ GType gimp_dialog_factory_get_type (void) G_GNUC_CONST; GimpDialogFactory * gimp_dialog_factory_new (const gchar *name, GimpContext *context, GimpMenuFactory *menu_factory, - GimpDialogNewFunc new_dock_func, + GimpDialogNewDockFunc + new_dock_func, gboolean toggle_visibility); GimpDialogFactory * gimp_dialog_factory_from_name (const gchar *name); void gimp_dialog_factory_set_constructor (GimpDialogFactory *factory, GimpDialogConstructor constructor); +void gimp_dialog_factory_set_dock_window_func(GimpDialogFactory *factory, + GimpDialogNewFunc new_dock_window_func); void gimp_dialog_factory_register_entry (GimpDialogFactory *factory, const gchar *identifier, diff --git a/app/widgets/gimpdock.c b/app/widgets/gimpdock.c index 1ca1392978..926a268931 100644 --- a/app/widgets/gimpdock.c +++ b/app/widgets/gimpdock.c @@ -88,7 +88,7 @@ static void gimp_dock_real_book_removed (GimpDock *dock, GimpDockbook *dockbook); -G_DEFINE_TYPE (GimpDock, gimp_dock, GIMP_TYPE_DOCK_WINDOW) +G_DEFINE_TYPE (GimpDock, gimp_dock, GTK_TYPE_VBOX) #define parent_class gimp_dock_parent_class diff --git a/app/widgets/gimpdock.h b/app/widgets/gimpdock.h index ee357b2ed2..25db978f71 100644 --- a/app/widgets/gimpdock.h +++ b/app/widgets/gimpdock.h @@ -22,9 +22,6 @@ #define __GIMP_DOCK_H__ -#include "widgets/gimpdockwindow.h" - - #define GIMP_TYPE_DOCK (gimp_dock_get_type ()) #define GIMP_DOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_DOCK, GimpDock)) #define GIMP_DOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_DOCK, GimpDockClass)) @@ -37,18 +34,18 @@ typedef struct _GimpDockClass GimpDockClass; typedef struct _GimpDockPrivate GimpDockPrivate; /** - * A top-level window containing GimpDockbooks. + * Contains a column of GimpDockbooks. */ struct _GimpDock { - GimpDockWindow parent_instance; + GtkVBox parent_instance; GimpDockPrivate *p; }; struct _GimpDockClass { - GimpDockWindowClass parent_class; + GtkVBoxClass parent_class; /* virtual functions */ void (* setup) (GimpDock *dock, diff --git a/app/widgets/gimpdockable.c b/app/widgets/gimpdockable.c index 7f2adb7ded..3f545fcbbd 100644 --- a/app/widgets/gimpdockable.c +++ b/app/widgets/gimpdockable.c @@ -36,6 +36,7 @@ #include "gimpdockable.h" #include "gimpdockbook.h" #include "gimpdocked.h" +#include "gimpdockwindow.h" #include "gimphelp-ids.h" #include "gimpsessioninfo-aux.h" #include "gimpuimanager.h" @@ -991,9 +992,10 @@ gimp_dockable_get_menu (GimpDockable *dockable, void gimp_dockable_detach (GimpDockable *dockable) { - GimpDock *src_dock; - GtkWidget *dock; - GtkWidget *dockbook; + GimpDock *src_dock = NULL; + GtkWidget *dock = NULL; + GtkWidget *dockbook = NULL; + GimpDockWindow *dock_window = NULL; g_return_if_fail (GIMP_IS_DOCKABLE (dockable)); g_return_if_fail (GIMP_IS_DOCKBOOK (dockable->dockbook)); @@ -1002,7 +1004,8 @@ gimp_dockable_detach (GimpDockable *dockable) dock = gimp_dialog_factory_dock_new (gimp_dock_get_dialog_factory (src_dock), gtk_widget_get_screen (GTK_WIDGET (dockable))); - gtk_window_set_position (GTK_WINDOW (dock), GTK_WIN_POS_MOUSE); + dock_window = gimp_dock_window_from_dock (GIMP_DOCK (dock)); + gtk_window_set_position (GTK_WINDOW (dock_window), GTK_WIN_POS_MOUSE); gimp_dock_setup (GIMP_DOCK (dock), src_dock); dockbook = gimp_dockbook_new (gimp_dock_get_dialog_factory (GIMP_DOCK (dock))->menu_factory); @@ -1016,6 +1019,7 @@ gimp_dockable_detach (GimpDockable *dockable) g_object_unref (dockable); + gtk_widget_show (GTK_WIDGET (dock_window)); gtk_widget_show (dock); } diff --git a/app/widgets/gimpdockwindow.c b/app/widgets/gimpdockwindow.c index ffffe7f756..fc08e32de0 100644 --- a/app/widgets/gimpdockwindow.c +++ b/app/widgets/gimpdockwindow.c @@ -237,8 +237,6 @@ gimp_dock_window_constructor (GType type, G_CALLBACK (gimp_dock_window_image_flush), dock_window); - gimp_dock_window_set_dock (dock_window, GIMP_DOCK (dock_window)); - /* Done! */ return object; } @@ -421,7 +419,7 @@ gimp_dock_window_delete_event (GtkWidget *widget, gimp_object_set_name (GIMP_OBJECT (info), gtk_window_get_title (GTK_WINDOW (dock_window))); - gimp_session_info_set_widget (info, GTK_WIDGET (dock)); + gimp_session_info_set_widget (info, GTK_WIDGET (dock_window)); gimp_session_info_get_info (info); gimp_session_info_set_widget (info, NULL); @@ -477,8 +475,15 @@ gimp_dock_window_update_title (GimpDockWindow *dock_window) static gboolean gimp_dock_window_update_title_idle (GimpDockWindow *dock_window) { - GimpDock *dock = gimp_dock_window_get_dock (dock_window); - gchar *title = gimp_dock_get_title (dock); + GimpDock *dock = NULL; + gchar *title = NULL; + + dock = gimp_dock_window_get_dock (dock_window); + + if (! dock) + return FALSE; + + title = gimp_dock_get_title (dock); if (title) gtk_window_set_title (GTK_WINDOW (dock_window), title); @@ -508,6 +513,9 @@ gimp_dock_window_set_dock (GimpDockWindow *dock_window, g_return_if_fail (GIMP_IS_DOCK_WINDOW (dock_window)); g_return_if_fail (GIMP_IS_DOCK (dock)); + /* FIXME: Handle more than one call to this function */ + gtk_container_add (GTK_CONTAINER (dock_window), GTK_WIDGET (dock)); + /* Update window title now and when docks title is invalidated */ gimp_dock_window_update_title (dock_window); g_signal_connect_object (dock, "title-invalidated", @@ -581,8 +589,5 @@ gimp_dock_window_from_dock (GimpDock *dock) GimpDock * gimp_dock_window_get_dock (GimpDockWindow *dock_window) { - /* Change this to return the GimpDock *inside* the GimpDockWindow - * once GimpDock is not a subclass of GimpDockWindow any longer - */ - return GIMP_DOCK (dock_window); + return GIMP_DOCK (gtk_bin_get_child (GTK_BIN (dock_window))); } diff --git a/app/widgets/gimpmenudock.c b/app/widgets/gimpmenudock.c index 0aa32a170a..3e454b691c 100644 --- a/app/widgets/gimpmenudock.c +++ b/app/widgets/gimpmenudock.c @@ -383,12 +383,8 @@ gimp_menu_dock_new (GimpDialogFactory *dialog_factory, "Dock Context", NULL); menu_dock = g_object_new (GIMP_TYPE_MENU_DOCK, - "role", "gimp-dock", "context", context, "dialog-factory", dialog_factory, - "ui-manager-name", "", - "gimp-context", context, - "gimp-dialog-factory", dialog_factory, NULL); g_object_unref (context); diff --git a/app/widgets/gimpsessioninfo-dock.c b/app/widgets/gimpsessioninfo-dock.c index d1d474b400..8d751ebca5 100644 --- a/app/widgets/gimpsessioninfo-dock.c +++ b/app/widgets/gimpsessioninfo-dock.c @@ -28,6 +28,7 @@ #include "gimpdialogfactory.h" #include "gimpdock.h" +#include "gimpdockwindow.h" #include "gimpsessioninfo.h" #include "gimpsessioninfo-aux.h" #include "gimpsessioninfo-book.h" @@ -175,17 +176,19 @@ gimp_session_info_dock_restore (GimpSessionInfo *info, GimpDialogFactory *factory, GdkScreen *screen) { - GimpDock *dock; - GList *books; + GimpDock *dock = NULL; + GimpDockWindow *dock_window = NULL; + GList *books = NULL; g_return_if_fail (info != NULL); g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory)); g_return_if_fail (GDK_IS_SCREEN (screen)); - dock = GIMP_DOCK (gimp_dialog_factory_dock_new (factory, screen)); + dock = GIMP_DOCK (gimp_dialog_factory_dock_new (factory, screen)); + dock_window = gimp_dock_window_from_dock (GIMP_DOCK (dock)); if (dock && info->p->aux_info) - gimp_session_info_aux_set_list (GTK_WIDGET (dock), info->p->aux_info); + gimp_session_info_aux_set_list (GTK_WIDGET (dock_window), info->p->aux_info); for (books = info->p->books; books; books = g_list_next (books)) { @@ -208,5 +211,6 @@ gimp_session_info_dock_restore (GimpSessionInfo *info, } } + gtk_widget_show (GTK_WIDGET (dock_window)); gtk_widget_show (GTK_WIDGET (dock)); } diff --git a/app/widgets/gimptoolbox.c b/app/widgets/gimptoolbox.c index 7e36d5364d..e52c19c0fc 100644 --- a/app/widgets/gimptoolbox.c +++ b/app/widgets/gimptoolbox.c @@ -623,7 +623,8 @@ gimp_toolbox_set_host_geometry_hints (GimpDock *dock, GtkWidget * gimp_toolbox_new (GimpDialogFactory *dialog_factory, - GimpContext *context) + GimpContext *context, + GimpUIManager *ui_manager) { GimpToolbox *toolbox; @@ -631,12 +632,9 @@ gimp_toolbox_new (GimpDialogFactory *dialog_factory, g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); toolbox = g_object_new (GIMP_TYPE_TOOLBOX, - "role", "gimp-toolbox", "context", context, "dialog-factory", dialog_factory, - "ui-manager-name", "", - "gimp-context", context, - "gimp-dialog-factory", dialog_factory, + "ui-manager", ui_manager, NULL); return GTK_WIDGET (toolbox); @@ -694,7 +692,6 @@ toolbox_create_tools (GimpToolbox *toolbox, GimpToolInfo *tool_info = list->data; GtkWidget *button; GtkWidget *image; - GimpDockWindow *dock_window; const gchar *stock_id; button = gtk_radio_button_new (group); @@ -730,8 +727,7 @@ toolbox_create_tools (GimpToolbox *toolbox, G_CALLBACK (toolbox_tool_button_press), toolbox); - dock_window = gimp_dock_window_from_dock (GIMP_DOCK (toolbox)); - if (gimp_dock_window_get_ui_manager (dock_window)) + if (gimp_dock_get_ui_manager (GIMP_DOCK (toolbox))) { GimpUIManager *ui_manager; GtkAction *action; @@ -746,7 +742,7 @@ toolbox_create_tools (GimpToolbox *toolbox, name = g_strdup_printf ("tools-%s", tmp); g_free (tmp); - ui_manager = gimp_dock_window_get_ui_manager (dock_window); + ui_manager = gimp_dock_get_ui_manager (GIMP_DOCK (toolbox)); action = gimp_ui_manager_find_action (ui_manager, "tools", name); g_free (name); diff --git a/app/widgets/gimptoolbox.h b/app/widgets/gimptoolbox.h index 6d0d766e3a..6c23b9d450 100644 --- a/app/widgets/gimptoolbox.h +++ b/app/widgets/gimptoolbox.h @@ -61,7 +61,8 @@ struct _GimpToolboxClass GType gimp_toolbox_get_type (void) G_GNUC_CONST; GtkWidget * gimp_toolbox_new (GimpDialogFactory *factory, - GimpContext *context); + GimpContext *context, + GimpUIManager *ui_manager); #endif /* __GIMP_TOOLBOX_H__ */