[gimp] app: Make positioning of new dockables depend on window mode



commit 07556242b01e6638c94cc544758d86274e0d5451
Author: Martin Nordholts <martinn src gnome org>
Date:   Sun Jul 3 20:55:03 2011 +0200

    app: Make positioning of new dockables depend on window mode
    
    Add GimpWindowingStrategy with create_dockable_dialog() and use it in
    dialogs_create_dockable_cmd_callback(). There are two implementations:
    GimpSingleWindowStrategy and GimpMultiWindowStrategy. Depending on the
    window mode, we want new dockables to appear in different places when
    created. In single-window mode, they should appear inside the single
    image window. In multi-window mode, a new dock window is created.

 app/actions/dialogs-commands.c         |   14 +++-
 app/core/gimp-gui.c                    |   11 +++
 app/core/gimp-gui.h                    |    2 +
 app/display/Makefile.am                |    8 ++-
 app/display/display-types.h            |   29 ++++----
 app/display/gimpimagewindow.c          |   53 ++++++++++++++
 app/display/gimpimagewindow.h          |   66 +++++++++---------
 app/display/gimpmultiwindowstrategy.c  |   86 +++++++++++++++++++++++
 app/display/gimpmultiwindowstrategy.h  |   54 ++++++++++++++
 app/display/gimpsinglewindowstrategy.c |  119 ++++++++++++++++++++++++++++++++
 app/display/gimpsinglewindowstrategy.h |   54 ++++++++++++++
 app/display/gimpwindowstrategy.c       |   91 ++++++++++++++++++++++++
 app/display/gimpwindowstrategy.h       |   54 ++++++++++++++
 app/gui/gui-vtable.c                   |   13 ++++
 14 files changed, 605 insertions(+), 49 deletions(-)
---
diff --git a/app/actions/dialogs-commands.c b/app/actions/dialogs-commands.c
index e572ae4..0731500 100644
--- a/app/actions/dialogs-commands.c
+++ b/app/actions/dialogs-commands.c
@@ -23,8 +23,12 @@
 
 #include "actions-types.h"
 
+#include "core/gimp.h"
+
 #include "widgets/gimpdialogfactory.h"
 
+#include "display/gimpwindowstrategy.h"
+
 #include "actions.h"
 #include "dialogs-commands.h"
 
@@ -51,11 +55,15 @@ dialogs_create_dockable_cmd_callback (GtkAction   *action,
                                       const gchar *value,
                                       gpointer     data)
 {
+  Gimp      *gimp;
   GtkWidget *widget;
+  return_if_no_gimp   (gimp, data);
   return_if_no_widget (widget, data);
 
   if (value)
-    gimp_dialog_factory_dialog_raise (gimp_dialog_factory_get_singleton (),
-                                      gtk_widget_get_screen (widget),
-                                      value, -1);
+    gimp_window_strategy_create_dockable_dialog (GIMP_WINDOW_STRATEGY (gimp_get_window_strategy (gimp)),
+                                                 gimp,
+                                                 gimp_dialog_factory_get_singleton (),
+                                                 gtk_widget_get_screen (widget),
+                                                 value);
 }
diff --git a/app/core/gimp-gui.c b/app/core/gimp-gui.c
index 957d78e..6a0a046 100644
--- a/app/core/gimp-gui.c
+++ b/app/core/gimp-gui.c
@@ -261,6 +261,17 @@ gimp_get_theme_dir (Gimp *gimp)
 }
 
 GimpObject *
+gimp_get_window_strategy (Gimp *gimp)
+{
+  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
+
+  if (gimp->gui.get_window_strategy)
+    return gimp->gui.get_window_strategy (gimp);
+
+  return NULL;
+}
+
+GimpObject *
 gimp_get_empty_display (Gimp *gimp)
 {
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
diff --git a/app/core/gimp-gui.h b/app/core/gimp-gui.h
index 82a02c6..582bf19 100644
--- a/app/core/gimp-gui.h
+++ b/app/core/gimp-gui.h
@@ -49,6 +49,7 @@ struct _GimpGui
 
   const gchar  * (* get_theme_dir)         (Gimp                *gimp);
 
+  GimpObject   * (* get_window_strategy)   (Gimp                *gimp);
   GimpObject   * (* get_empty_display)     (Gimp                *gimp);
   GimpObject   * (* display_get_by_id)     (Gimp                *gimp,
                                             gint                 ID);
@@ -99,6 +100,7 @@ void           gimp_gui_ungrab            (Gimp                *gimp);
 void           gimp_threads_enter         (Gimp                *gimp);
 void           gimp_threads_leave         (Gimp                *gimp);
 
+GimpObject   * gimp_get_window_strategy   (Gimp                *gimp);
 GimpObject   * gimp_get_empty_display     (Gimp                *gimp);
 GimpObject   * gimp_get_display_by_ID     (Gimp                *gimp,
                                            gint                 ID);
diff --git a/app/display/Makefile.am b/app/display/Makefile.am
index de95d21..3ac38c7 100644
--- a/app/display/Makefile.am
+++ b/app/display/Makefile.am
@@ -131,14 +131,20 @@ libappdisplay_a_sources = \
 	gimpimagewindow.h			\
 	gimpmotionbuffer.c			\
 	gimpmotionbuffer.h			\
+	gimpmultiwindowstrategy.c		\
+	gimpmultiwindowstrategy.h		\
 	gimpnavigationeditor.c			\
 	gimpnavigationeditor.h			\
 	gimpscalecombobox.c			\
 	gimpscalecombobox.h			\
+	gimpsinglewindowstrategy.c		\
+	gimpsinglewindowstrategy.h		\
 	gimpstatusbar.c				\
 	gimpstatusbar.h				\
 	gimptooldialog.c			\
-	gimptooldialog.h
+	gimptooldialog.h			\
+	gimpwindowstrategy.c			\
+	gimpwindowstrategy.h
 
 libappdisplay_a_built_sources = display-enums.c
 
diff --git a/app/display/display-types.h b/app/display/display-types.h
index 251f9d5..e7201a5 100644
--- a/app/display/display-types.h
+++ b/app/display/display-types.h
@@ -24,24 +24,27 @@
 #include "display/display-enums.h"
 
 
-typedef struct _GimpCanvas            GimpCanvas;
-typedef struct _GimpCanvasItem        GimpCanvasItem;
-typedef struct _GimpCanvasGroup       GimpCanvasGroup;
+typedef struct _GimpCanvas               GimpCanvas;
+typedef struct _GimpCanvasGroup          GimpCanvasGroup;
+typedef struct _GimpCanvasItem           GimpCanvasItem;
 
-typedef struct _GimpDisplay           GimpDisplay;
-typedef struct _GimpDisplayShell      GimpDisplayShell;
-typedef struct _GimpMotionBuffer      GimpMotionBuffer;
+typedef struct _GimpDisplay              GimpDisplay;
+typedef struct _GimpDisplayShell         GimpDisplayShell;
+typedef struct _GimpMotionBuffer         GimpMotionBuffer;
 
-typedef struct _GimpImageWindow       GimpImageWindow;
+typedef struct _GimpImageWindow          GimpImageWindow;
+typedef struct _GimpMultiWindowStrategy  GimpMultiWindowStrategy;
+typedef struct _GimpSingleWindowStrategy GimpSingleWindowStrategy;
+typedef struct _GimpWindowStrategy       GimpWindowStrategy;
 
-typedef struct _GimpCursorView        GimpCursorView;
-typedef struct _GimpNavigationEditor  GimpNavigationEditor;
-typedef struct _GimpScaleComboBox     GimpScaleComboBox;
-typedef struct _GimpStatusbar         GimpStatusbar;
+typedef struct _GimpCursorView           GimpCursorView;
+typedef struct _GimpNavigationEditor     GimpNavigationEditor;
+typedef struct _GimpScaleComboBox        GimpScaleComboBox;
+typedef struct _GimpStatusbar            GimpStatusbar;
 
-typedef struct _GimpToolDialog        GimpToolDialog;
+typedef struct _GimpToolDialog           GimpToolDialog;
 
-typedef struct _Selection             Selection;
+typedef struct _Selection                Selection;
 
 
 #endif /* __DISPLAY_TYPES_H__ */
diff --git a/app/display/gimpimagewindow.c b/app/display/gimpimagewindow.c
index 8f9c2a5..e5a9460 100644
--- a/app/display/gimpimagewindow.c
+++ b/app/display/gimpimagewindow.c
@@ -35,6 +35,7 @@
 #include "widgets/gimpactiongroup.h"
 #include "widgets/gimpdialogfactory.h"
 #include "widgets/gimpdock.h"
+#include "widgets/gimpdockbook.h"
 #include "widgets/gimpdockcolumns.h"
 #include "widgets/gimpdockcontainer.h"
 #include "widgets/gimphelp-ids.h"
@@ -1315,6 +1316,58 @@ gimp_image_window_shrink_wrap (GimpImageWindow *window,
   gimp_display_shell_scroll_center_image (active_shell, TRUE, TRUE);
 }
 
+static GtkWidget *
+gimp_image_window_get_first_dockbook (GimpDockColumns *columns)
+{
+  GList *dock_iter;
+  
+  for (dock_iter = gimp_dock_columns_get_docks (columns);
+       dock_iter;
+       dock_iter = g_list_next (dock_iter))
+    {
+      GimpDock *dock      = GIMP_DOCK (dock_iter->data);
+      GList    *dockbooks = gimp_dock_get_dockbooks (dock);
+
+      if (dockbooks)
+        return GTK_WIDGET (dockbooks->data);
+    }
+
+  return NULL;
+}
+
+/**
+ * gimp_image_window_get_default_dockbook:
+ * @window:
+ *
+ * Gets the default dockbook, which is the dockbook in which new
+ * dockables should be put in single-window mode.
+ *
+ * Returns: The default dockbook for new dockables, or NULL if no
+ *          dockbook were avaialble.
+ **/
+GtkWidget *
+gimp_image_window_get_default_dockbook (GimpImageWindow  *window)
+{
+  GimpImageWindowPrivate *private;
+  GimpDockColumns        *dock_columns;
+  GtkWidget              *dockbook = NULL;
+
+  private = GIMP_IMAGE_WINDOW_GET_PRIVATE (window);
+
+  /* First try the first dockbook in the right docks */
+  dock_columns = GIMP_DOCK_COLUMNS (private->right_docks);
+  dockbook     = gimp_image_window_get_first_dockbook (dock_columns);
+
+  /* Then the left docks */
+  if (! dockbook)
+    {
+      dock_columns = GIMP_DOCK_COLUMNS (private->left_docks);
+      dockbook     = gimp_image_window_get_first_dockbook (dock_columns);
+    }
+
+  return dockbook;
+}
+
 /**
  * gimp_image_window_keep_canvas_pos:
  * @window:
diff --git a/app/display/gimpimagewindow.h b/app/display/gimpimagewindow.h
index cab3894..239c240 100644
--- a/app/display/gimpimagewindow.h
+++ b/app/display/gimpimagewindow.h
@@ -43,48 +43,50 @@ struct _GimpImageWindowClass
 };
 
 
-GType              gimp_image_window_get_type           (void) G_GNUC_CONST;
+GType              gimp_image_window_get_type             (void) G_GNUC_CONST;
 
-GimpImageWindow  * gimp_image_window_new                (Gimp              *gimp,
-                                                         GimpImage         *image,
-                                                         GimpMenuFactory   *menu_factory,
-                                                         GimpDialogFactory *dialog_factory);
-void               gimp_image_window_destroy            (GimpImageWindow   *window);
+GimpImageWindow  * gimp_image_window_new                  (Gimp              *gimp,
+                                                           GimpImage         *image,
+                                                           GimpMenuFactory   *menu_factory,
+                                                           GimpDialogFactory *dialog_factory);
+void               gimp_image_window_destroy              (GimpImageWindow   *window);
 
-GimpUIManager    * gimp_image_window_get_ui_manager     (GimpImageWindow  *window);
-GimpDockColumns  * gimp_image_window_get_left_docks     (GimpImageWindow  *window);
-GimpDockColumns  * gimp_image_window_get_right_docks    (GimpImageWindow  *window);
+GimpUIManager    * gimp_image_window_get_ui_manager       (GimpImageWindow  *window);
+GimpDockColumns  * gimp_image_window_get_left_docks       (GimpImageWindow  *window);
+GimpDockColumns  * gimp_image_window_get_right_docks      (GimpImageWindow  *window);
 
-void               gimp_image_window_add_shell          (GimpImageWindow  *window,
-                                                         GimpDisplayShell *shell);
-GimpDisplayShell * gimp_image_window_get_shell          (GimpImageWindow  *window,
-                                                         gint              index);
-void               gimp_image_window_remove_shell       (GimpImageWindow  *window,
-                                                         GimpDisplayShell *shell);
+void               gimp_image_window_add_shell            (GimpImageWindow  *window,
+                                                           GimpDisplayShell *shell);
+GimpDisplayShell * gimp_image_window_get_shell            (GimpImageWindow  *window,
+                                                           gint              index);
+void               gimp_image_window_remove_shell         (GimpImageWindow  *window,
+                                                           GimpDisplayShell *shell);
 
-gint               gimp_image_window_get_n_shells       (GimpImageWindow  *window);
+gint               gimp_image_window_get_n_shells         (GimpImageWindow  *window);
 
-void               gimp_image_window_set_active_shell   (GimpImageWindow  *window,
-                                                         GimpDisplayShell *shell);
-GimpDisplayShell * gimp_image_window_get_active_shell   (GimpImageWindow  *window);
+void               gimp_image_window_set_active_shell     (GimpImageWindow  *window,
+                                                           GimpDisplayShell *shell);
+GimpDisplayShell * gimp_image_window_get_active_shell     (GimpImageWindow  *window);
 
-void               gimp_image_window_set_fullscreen     (GimpImageWindow  *window,
-                                                         gboolean          fullscreen);
-gboolean           gimp_image_window_get_fullscreen     (GimpImageWindow  *window);
+void               gimp_image_window_set_fullscreen       (GimpImageWindow  *window,
+                                                           gboolean          fullscreen);
+gboolean           gimp_image_window_get_fullscreen       (GimpImageWindow  *window);
 
-void               gimp_image_window_set_show_menubar   (GimpImageWindow  *window,
-                                                         gboolean          show);
-gboolean           gimp_image_window_get_show_menubar   (GimpImageWindow  *window);
+void               gimp_image_window_set_show_menubar     (GimpImageWindow  *window,
+                                                           gboolean          show);
+gboolean           gimp_image_window_get_show_menubar     (GimpImageWindow  *window);
 
-void               gimp_image_window_set_show_statusbar (GimpImageWindow  *window,
-                                                         gboolean          show);
-gboolean           gimp_image_window_get_show_statusbar (GimpImageWindow  *window);
+void               gimp_image_window_set_show_statusbar   (GimpImageWindow  *window,
+                                                           gboolean          show);
+gboolean           gimp_image_window_get_show_statusbar   (GimpImageWindow  *window);
 
-gboolean           gimp_image_window_is_iconified       (GimpImageWindow  *window);
+gboolean           gimp_image_window_is_iconified         (GimpImageWindow  *window);
 
-void               gimp_image_window_shrink_wrap        (GimpImageWindow  *window,
-                                                         gboolean          grow_only);
+void               gimp_image_window_shrink_wrap          (GimpImageWindow  *window,
+                                                           gboolean          grow_only);
 
-void               gimp_image_window_keep_canvas_pos    (GimpImageWindow  *window);
+GtkWidget        * gimp_image_window_get_default_dockbook (GimpImageWindow  *window);
+
+void               gimp_image_window_keep_canvas_pos      (GimpImageWindow  *window);
 
 #endif /* __GIMP_IMAGE_WINDOW_H__ */
diff --git a/app/display/gimpmultiwindowstrategy.c b/app/display/gimpmultiwindowstrategy.c
new file mode 100644
index 0000000..d7aa6c7
--- /dev/null
+++ b/app/display/gimpmultiwindowstrategy.c
@@ -0,0 +1,86 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpmultiwindowstrategy.c
+ * Copyright (C) 2011 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 <gegl.h>
+#include <gtk/gtk.h>
+
+#include "display-types.h"
+
+#include "core/gimp.h"
+
+#include "widgets/gimpdialogfactory.h"
+
+#include "gimpmultiwindowstrategy.h"
+#include "gimpwindowstrategy.h"
+
+
+static void        gimp_multi_window_strategy_window_strategy_iface_init (GimpWindowStrategyInterface *iface);
+static GtkWidget * gimp_multi_window_strategy_create_dockable_dialog     (GimpWindowStrategy          *strategy,
+                                                                          Gimp                        *gimp,
+                                                                          GimpDialogFactory           *factory,
+                                                                          GdkScreen                   *screen,
+                                                                          const gchar                 *identifiers);
+
+
+G_DEFINE_TYPE_WITH_CODE (GimpMultiWindowStrategy, gimp_multi_window_strategy, GIMP_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_WINDOW_STRATEGY,
+                                                gimp_multi_window_strategy_window_strategy_iface_init))
+
+#define parent_class gimp_multi_window_strategy_parent_class
+
+
+static void
+gimp_multi_window_strategy_class_init (GimpMultiWindowStrategyClass *klass)
+{
+}
+
+static void
+gimp_multi_window_strategy_init (GimpMultiWindowStrategy *strategy)
+{
+}
+
+static void
+gimp_multi_window_strategy_window_strategy_iface_init (GimpWindowStrategyInterface *iface)
+{
+  iface->create_dockable_dialog = gimp_multi_window_strategy_create_dockable_dialog;
+}
+
+static GtkWidget *
+gimp_multi_window_strategy_create_dockable_dialog (GimpWindowStrategy *strategy,
+                                                   Gimp               *gimp,
+                                                   GimpDialogFactory  *factory,
+                                                   GdkScreen          *screen,
+                                                   const gchar        *identifiers)
+{
+  return gimp_dialog_factory_dialog_raise (factory, screen, identifiers, -1);
+}
+
+GimpObject *
+gimp_multi_window_strategy_get_singleton (void)
+{
+  static GimpObject *singleton = NULL;
+
+  if (! singleton)
+    singleton = g_object_new (GIMP_TYPE_MULTI_WINDOW_STRATEGY, NULL);
+
+  return singleton;
+}
diff --git a/app/display/gimpmultiwindowstrategy.h b/app/display/gimpmultiwindowstrategy.h
new file mode 100644
index 0000000..e9cd502
--- /dev/null
+++ b/app/display/gimpmultiwindowstrategy.h
@@ -0,0 +1,54 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpmultiwindowstrategy.h
+ * Copyright (C) 2011 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_MULTI_WINDOW_STRATEGY_H__
+#define __GIMP_MULTI_WINDOW_STRATEGY_H__
+
+
+#include "core/gimpobject.h"
+
+
+#define GIMP_TYPE_MULTI_WINDOW_STRATEGY            (gimp_multi_window_strategy_get_type ())
+#define GIMP_MULTI_WINDOW_STRATEGY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_MULTI_WINDOW_STRATEGY, GimpMultiWindowStrategy))
+#define GIMP_MULTI_WINDOW_STRATEGY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_MULTI_WINDOW_STRATEGY, GimpMultiWindowStrategyClass))
+#define GIMP_IS_MULTI_WINDOW_STRATEGY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_MULTI_WINDOW_STRATEGY))
+#define GIMP_IS_MULTI_WINDOW_STRATEGY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_MULTI_WINDOW_STRATEGY))
+#define GIMP_MULTI_WINDOW_STRATEGY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_MULTI_WINDOW_STRATEGY, GimpMultiWindowStrategyClass))
+
+
+typedef struct _GimpMultiWindowStrategyClass GimpMultiWindowStrategyClass;
+
+struct _GimpMultiWindowStrategy
+{
+  GimpObject  parent_instance;
+};
+
+struct _GimpMultiWindowStrategyClass
+{
+  GimpObjectClass  parent_class;
+};
+
+
+GType        gimp_multi_window_strategy_get_type          (void) G_GNUC_CONST;
+
+GimpObject * gimp_multi_window_strategy_get_singleton     (void);
+
+
+#endif /* __GIMP_MULTI_WINDOW_STRATEGY_H__ */
diff --git a/app/display/gimpsinglewindowstrategy.c b/app/display/gimpsinglewindowstrategy.c
new file mode 100644
index 0000000..b82cdc7
--- /dev/null
+++ b/app/display/gimpsinglewindowstrategy.c
@@ -0,0 +1,119 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpsinglewindowstrategy.c
+ * Copyright (C) 2011 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 <gegl.h>
+#include <gtk/gtk.h>
+
+#include "display-types.h"
+
+#include "core/gimp.h"
+
+#include "widgets/gimpdockcolumns.h"
+#include "widgets/gimpdockbook.h"
+
+#include "display/gimpimagewindow.h"
+
+#include "gimpsinglewindowstrategy.h"
+#include "gimpwindowstrategy.h"
+
+
+static void        gimp_single_window_strategy_window_strategy_iface_init (GimpWindowStrategyInterface *iface);
+static GtkWidget * gimp_single_window_strategy_create_dockable_dialog     (GimpWindowStrategy          *strategy,
+                                                                           Gimp                        *gimp,
+                                                                           GimpDialogFactory           *factory,
+                                                                           GdkScreen                   *screen,
+                                                                           const gchar                 *identifiers);
+
+
+G_DEFINE_TYPE_WITH_CODE (GimpSingleWindowStrategy, gimp_single_window_strategy, GIMP_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_WINDOW_STRATEGY,
+                                                gimp_single_window_strategy_window_strategy_iface_init))
+
+#define parent_class gimp_single_window_strategy_parent_class
+
+
+static void
+gimp_single_window_strategy_class_init (GimpSingleWindowStrategyClass *klass)
+{
+}
+
+static void
+gimp_single_window_strategy_init (GimpSingleWindowStrategy *strategy)
+{
+}
+
+static void
+gimp_single_window_strategy_window_strategy_iface_init (GimpWindowStrategyInterface *iface)
+{
+  iface->create_dockable_dialog = gimp_single_window_strategy_create_dockable_dialog;
+}
+
+static GtkWidget *
+gimp_single_window_strategy_create_dockable_dialog (GimpWindowStrategy *strategy,
+                                                    Gimp               *gimp,
+                                                    GimpDialogFactory  *factory,
+                                                    GdkScreen          *screen,
+                                                    const gchar        *identifiers)
+{
+  GList           *windows = gimp_get_image_windows (gimp);
+  GtkWidget       *dockbook;
+  GtkWidget       *dockable;
+  GimpImageWindow *window;
+
+  g_return_val_if_fail (g_list_length (windows) > 0, NULL);
+
+  /* In single-window mode, there should only be one window... */
+  window = GIMP_IMAGE_WINDOW (windows->data);
+
+  /* There shall not is more than one window in single-window mode */
+  dockbook = gimp_image_window_get_default_dockbook (window);
+
+  if (! dockbook)
+    {
+      GimpDockColumns *dock_columns;
+
+      /* No dock, need to add one */
+      dock_columns = gimp_image_window_get_right_docks (window);
+      gimp_dock_columns_prepare_dockbook (dock_columns,
+                                          -1 /*index*/,
+                                          &dockbook);
+    }
+
+  dockable = gimp_dockbook_add_from_dialog_factory (GIMP_DOCKBOOK (dockbook),
+                                                    identifiers,
+                                                    -1 /*index*/);
+
+  g_list_free (windows);
+
+  return dockable;
+}
+
+GimpObject *
+gimp_single_window_strategy_get_singleton (void)
+{
+  static GimpObject *singleton = NULL;
+
+  if (! singleton)
+    singleton = g_object_new (GIMP_TYPE_SINGLE_WINDOW_STRATEGY, NULL);
+
+  return singleton;
+}
diff --git a/app/display/gimpsinglewindowstrategy.h b/app/display/gimpsinglewindowstrategy.h
new file mode 100644
index 0000000..e25852c
--- /dev/null
+++ b/app/display/gimpsinglewindowstrategy.h
@@ -0,0 +1,54 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpsinglewindowstrategy.h
+ * Copyright (C) 2011 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_SINGLE_WINDOW_STRATEGY_H__
+#define __GIMP_SINGLE_WINDOW_STRATEGY_H__
+
+
+#include "core/gimpobject.h"
+
+
+#define GIMP_TYPE_SINGLE_WINDOW_STRATEGY            (gimp_single_window_strategy_get_type ())
+#define GIMP_SINGLE_WINDOW_STRATEGY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SINGLE_WINDOW_STRATEGY, GimpSingleWindowStrategy))
+#define GIMP_SINGLE_WINDOW_STRATEGY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SINGLE_WINDOW_STRATEGY, GimpSingleWindowStrategyClass))
+#define GIMP_IS_SINGLE_WINDOW_STRATEGY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_SINGLE_WINDOW_STRATEGY))
+#define GIMP_IS_SINGLE_WINDOW_STRATEGY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SINGLE_WINDOW_STRATEGY))
+#define GIMP_SINGLE_WINDOW_STRATEGY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SINGLE_WINDOW_STRATEGY, GimpSingleWindowStrategyClass))
+
+
+typedef struct _GimpSingleWindowStrategyClass GimpSingleWindowStrategyClass;
+
+struct _GimpSingleWindowStrategy
+{
+  GimpObject  parent_instance;
+};
+
+struct _GimpSingleWindowStrategyClass
+{
+  GimpObjectClass  parent_class;
+};
+
+
+GType        gimp_single_window_strategy_get_type          (void) G_GNUC_CONST;
+
+GimpObject * gimp_single_window_strategy_get_singleton     (void);
+
+
+#endif /* __GIMP_SINGLE_WINDOW_STRATEGY_H__ */
diff --git a/app/display/gimpwindowstrategy.c b/app/display/gimpwindowstrategy.c
new file mode 100644
index 0000000..0959c2c
--- /dev/null
+++ b/app/display/gimpwindowstrategy.c
@@ -0,0 +1,91 @@
+ /* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpwindowstrategy.c
+ * Copyright (C) 2011 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 "display-types.h"
+
+#include "gimpwindowstrategy.h"
+
+
+static void   gimp_window_strategy_iface_base_init   (GimpWindowStrategyInterface *strategy_iface);
+
+
+GType
+gimp_window_strategy_interface_get_type (void)
+{
+  static GType iface_type = 0;
+
+  if (! iface_type)
+    {
+      const GTypeInfo iface_info =
+      {
+        sizeof (GimpWindowStrategyInterface),
+        (GBaseInitFunc)     gimp_window_strategy_iface_base_init,
+        (GBaseFinalizeFunc) NULL,
+      };
+
+      iface_type = g_type_register_static (G_TYPE_INTERFACE,
+                                           "GimpWindowStrategyInterface",
+                                           &iface_info,
+                                           0);
+    }
+
+  return iface_type;
+}
+
+static void
+gimp_window_strategy_iface_base_init (GimpWindowStrategyInterface *strategy_iface)
+{
+  static gboolean initialized = FALSE;
+
+  if (initialized)
+    return;
+
+  initialized = TRUE;
+
+  strategy_iface->create_dockable_dialog = NULL;
+}
+
+GtkWidget *
+gimp_window_strategy_create_dockable_dialog (GimpWindowStrategy *strategy,
+                                             Gimp               *gimp,
+                                             GimpDialogFactory  *factory,
+                                             GdkScreen          *screen,
+                                             const gchar        *identifiers)
+{
+  GimpWindowStrategyInterface *iface;
+
+  g_return_val_if_fail (GIMP_IS_WINDOW_STRATEGY (strategy), NULL);
+
+  iface = GIMP_WINDOW_STRATEGY_GET_INTERFACE (strategy);
+
+  if (iface->create_dockable_dialog)
+    return iface->create_dockable_dialog (strategy,
+                                          gimp,
+                                          factory,
+                                          screen,
+                                          identifiers);
+
+  return NULL;
+}
+
diff --git a/app/display/gimpwindowstrategy.h b/app/display/gimpwindowstrategy.h
new file mode 100644
index 0000000..aed3ad2
--- /dev/null
+++ b/app/display/gimpwindowstrategy.h
@@ -0,0 +1,54 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpwindowstrategy.h
+ * Copyright (C) 2011 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_WINDOW_STRATEGY_H__
+#define __GIMP_WINDOW_STRATEGY_H__
+
+
+#define GIMP_TYPE_WINDOW_STRATEGY               (gimp_window_strategy_interface_get_type ())
+#define GIMP_WINDOW_STRATEGY(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_WINDOW_STRATEGY, GimpWindowStrategy))
+#define GIMP_IS_WINDOW_STRATEGY(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_WINDOW_STRATEGY))
+#define GIMP_WINDOW_STRATEGY_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GIMP_TYPE_WINDOW_STRATEGY, GimpWindowStrategyInterface))
+
+
+typedef struct _GimpWindowStrategyInterface GimpWindowStrategyInterface;
+
+struct _GimpWindowStrategyInterface
+{
+  GTypeInterface base_iface;
+
+  /*  virtual functions  */
+  GtkWidget       * (* create_dockable_dialog)         (GimpWindowStrategy *strategy,
+                                                        Gimp               *gimp,
+                                                        GimpDialogFactory  *factory,
+                                                        GdkScreen          *screen,
+                                                        const gchar        *identifiers);
+};
+
+
+GType              gimp_window_strategy_interface_get_type     (void) G_GNUC_CONST;
+GtkWidget        * gimp_window_strategy_create_dockable_dialog (GimpWindowStrategy *strategy,
+                                                                Gimp               *gimp,
+                                                                GimpDialogFactory  *factory,
+                                                                GdkScreen          *screen,
+                                                                const gchar        *identifiers);
+
+
+#endif  /*  __GIMP_WINDOW_STRATEGY_H__  */
diff --git a/app/gui/gui-vtable.c b/app/gui/gui-vtable.c
index 2207a6f..3876f76 100644
--- a/app/gui/gui-vtable.c
+++ b/app/gui/gui-vtable.c
@@ -65,6 +65,8 @@
 #include "display/gimpdisplay.h"
 #include "display/gimpdisplay-foreach.h"
 #include "display/gimpdisplayshell.h"
+#include "display/gimpsinglewindowstrategy.h"
+#include "display/gimpmultiwindowstrategy.h"
 
 #include "actions/plug-in-actions.h"
 
@@ -93,6 +95,7 @@ static gchar        * gui_get_display_name      (Gimp                *gimp,
                                                  gint                *monitor_number);
 static guint32        gui_get_user_time         (Gimp                *gimp);
 static const gchar  * gui_get_theme_dir         (Gimp                *gimp);
+static GimpObject   * gui_get_window_strategy   (Gimp                *gimp);
 static GimpObject   * gui_get_empty_display     (Gimp                *gimp);
 static GimpObject   * gui_display_get_by_ID     (Gimp                *gimp,
                                                  gint                 ID);
@@ -150,6 +153,7 @@ gui_vtable_init (Gimp *gimp)
   gimp->gui.get_display_name      = gui_get_display_name;
   gimp->gui.get_user_time         = gui_get_user_time;
   gimp->gui.get_theme_dir         = gui_get_theme_dir;
+  gimp->gui.get_window_strategy   = gui_get_window_strategy;
   gimp->gui.get_empty_display     = gui_get_empty_display;
   gimp->gui.display_get_by_id     = gui_display_get_by_ID;
   gimp->gui.display_get_id        = gui_display_get_ID;
@@ -279,6 +283,15 @@ gui_get_theme_dir (Gimp *gimp)
 }
 
 static GimpObject *
+gui_get_window_strategy (Gimp *gimp)
+{
+  if (GIMP_GUI_CONFIG (gimp->config)->single_window_mode)
+    return gimp_single_window_strategy_get_singleton ();
+  else
+    return gimp_multi_window_strategy_get_singleton ();
+}
+
+static GimpObject *
 gui_get_empty_display (Gimp *gimp)
 {
   GimpObject *display = NULL;



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