2006-12-10 05:33:38 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
2001-04-07 22:44:12 +08:00
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
|
|
|
* gimpdock.c
|
2018-05-01 06:17:27 +08:00
|
|
|
* Copyright (C) 2001-2018 Michael Natterer <mitch@gimp.org>
|
2001-04-07 22:44:12 +08:00
|
|
|
*
|
2009-01-18 06:28:01 +08:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
2001-04-07 22:44:12 +08:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
2009-01-18 06:28:01 +08:00
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2001-04-07 22:44:12 +08:00
|
|
|
* (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
|
2018-07-12 05:27:07 +08:00
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2001-04-07 22:44:12 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2012-03-30 01:19:01 +08:00
|
|
|
#include <gegl.h>
|
2001-04-07 22:44:12 +08:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
2001-04-11 00:03:40 +08:00
|
|
|
#include "libgimpwidgets/gimpwidgets.h"
|
|
|
|
|
2001-05-08 11:48:54 +08:00
|
|
|
#include "widgets-types.h"
|
2001-04-07 22:44:12 +08:00
|
|
|
|
2003-11-21 04:36:55 +08:00
|
|
|
#include "core/gimp.h"
|
2002-03-15 01:07:02 +08:00
|
|
|
#include "core/gimpcontext.h"
|
|
|
|
|
2001-04-15 00:37:28 +08:00
|
|
|
#include "gimpdialogfactory.h"
|
2001-04-07 22:44:12 +08:00
|
|
|
#include "gimpdock.h"
|
|
|
|
#include "gimpdockable.h"
|
2001-04-11 00:03:40 +08:00
|
|
|
#include "gimpdockbook.h"
|
2010-01-05 18:08:10 +08:00
|
|
|
#include "gimpdockcolumns.h"
|
2011-05-14 00:56:03 +08:00
|
|
|
#include "gimpdockcontainer.h"
|
2009-12-06 04:20:18 +08:00
|
|
|
#include "gimpdockwindow.h"
|
2009-10-25 00:52:48 +08:00
|
|
|
#include "gimppanedbox.h"
|
2009-09-21 01:24:04 +08:00
|
|
|
#include "gimpuimanager.h"
|
2009-10-11 22:58:59 +08:00
|
|
|
#include "gimpwidgets-utils.h"
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2003-03-26 00:38:19 +08:00
|
|
|
#include "gimp-intl.h"
|
2003-03-15 02:37:12 +08:00
|
|
|
|
2001-04-07 22:44:12 +08:00
|
|
|
|
2002-10-25 21:21:54 +08:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
BOOK_ADDED,
|
|
|
|
BOOK_REMOVED,
|
2010-03-14 00:18:47 +08:00
|
|
|
DESCRIPTION_INVALIDATED,
|
2009-09-13 20:14:08 +08:00
|
|
|
GEOMETRY_INVALIDATED,
|
2002-10-25 21:21:54 +08:00
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-09-06 06:15:25 +08:00
|
|
|
struct _GimpDockPrivate
|
2009-01-04 18:28:31 +08:00
|
|
|
{
|
2018-06-08 07:41:44 +08:00
|
|
|
GtkWidget *main_vbox;
|
|
|
|
GtkWidget *paned_vbox;
|
2009-01-04 18:28:31 +08:00
|
|
|
|
2018-06-08 07:41:44 +08:00
|
|
|
GList *dockbooks;
|
2009-12-04 06:08:30 +08:00
|
|
|
|
2018-06-08 07:41:44 +08:00
|
|
|
gint ID;
|
2009-01-04 18:28:31 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2011-05-05 04:40:40 +08:00
|
|
|
static void gimp_dock_dispose (GObject *object);
|
|
|
|
|
|
|
|
static gchar * gimp_dock_real_get_description (GimpDock *dock,
|
|
|
|
gboolean complete);
|
|
|
|
static void gimp_dock_real_book_added (GimpDock *dock,
|
|
|
|
GimpDockbook *dockbook);
|
|
|
|
static void gimp_dock_real_book_removed (GimpDock *dock,
|
|
|
|
GimpDockbook *dockbook);
|
|
|
|
static void gimp_dock_invalidate_description (GimpDock *dock);
|
2018-06-08 07:37:19 +08:00
|
|
|
static gboolean gimp_dock_dropped_cb (GtkWidget *notebook,
|
|
|
|
GtkWidget *child,
|
2011-05-05 04:40:40 +08:00
|
|
|
gint insert_index,
|
|
|
|
gpointer data);
|
2003-11-21 04:36:55 +08:00
|
|
|
|
2002-10-25 21:21:54 +08:00
|
|
|
|
app, libgimp*, modules: don't use g_type_class_add_private() ...
... and G_TYPE_INSTANCE_GET_PRIVATE()
g_type_class_add_private() and G_TYPE_INSTANCE_GET_PRIVATE() were
deprecated in GLib 2.58. Instead, use
G_DEFINE_[ABSTRACT_]TYPE_WITH_PRIVATE(), and
G_ADD_PRIVATE[_DYNAMIC](), and the implictly-defined
foo_get_instance_private() functions, all of which are available in
the GLib versions we depend on.
This commit only covers types registered using one of the
G_DEFINE_FOO() macros (i.e., most types), but not types with a
custom registration function, of which we still have a few -- GLib
currently only provides a (non-deprecated) public API for adding a
private struct using the G_DEFINE_FOO() macros.
Note that this commit was 99% auto-generated (because I'm not
*that* crazy :), so if there are any style mismatches... we'll have
to live with them for now.
2018-09-19 00:09:39 +08:00
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE (GimpDock, gimp_dock, GTK_TYPE_BOX)
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2005-12-20 06:37:49 +08:00
|
|
|
#define parent_class gimp_dock_parent_class
|
|
|
|
|
|
|
|
static guint dock_signals[LAST_SIGNAL] = { 0 };
|
2001-04-07 22:44:12 +08:00
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_dock_class_init (GimpDockClass *klass)
|
|
|
|
{
|
2010-10-15 20:08:36 +08:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
2001-04-07 22:44:12 +08:00
|
|
|
|
2002-10-25 21:21:54 +08:00
|
|
|
dock_signals[BOOK_ADDED] =
|
2005-05-27 21:05:26 +08:00
|
|
|
g_signal_new ("book-added",
|
2006-04-12 20:49:29 +08:00
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
G_STRUCT_OFFSET (GimpDockClass, book_added),
|
2020-01-12 18:06:05 +08:00
|
|
|
NULL, NULL, NULL,
|
2006-04-12 20:49:29 +08:00
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
GIMP_TYPE_DOCKBOOK);
|
2002-10-25 21:21:54 +08:00
|
|
|
|
|
|
|
dock_signals[BOOK_REMOVED] =
|
2005-05-27 21:05:26 +08:00
|
|
|
g_signal_new ("book-removed",
|
2006-04-12 20:49:29 +08:00
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
G_STRUCT_OFFSET (GimpDockClass, book_removed),
|
2020-01-12 18:06:05 +08:00
|
|
|
NULL, NULL, NULL,
|
2006-04-12 20:49:29 +08:00
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
GIMP_TYPE_DOCKBOOK);
|
2002-10-25 21:21:54 +08:00
|
|
|
|
2010-03-14 00:18:47 +08:00
|
|
|
dock_signals[DESCRIPTION_INVALIDATED] =
|
|
|
|
g_signal_new ("description-invalidated",
|
2009-09-13 19:14:18 +08:00
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2010-03-14 00:18:47 +08:00
|
|
|
G_STRUCT_OFFSET (GimpDockClass, description_invalidated),
|
2020-01-12 18:06:05 +08:00
|
|
|
NULL, NULL, NULL,
|
2009-09-13 19:14:18 +08:00
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2009-09-13 20:14:08 +08:00
|
|
|
dock_signals[GEOMETRY_INVALIDATED] =
|
|
|
|
g_signal_new ("geometry-invalidated",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
G_STRUCT_OFFSET (GimpDockClass, geometry_invalidated),
|
2020-01-12 18:06:05 +08:00
|
|
|
NULL, NULL, NULL,
|
2009-09-13 20:14:08 +08:00
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2010-10-15 20:08:36 +08:00
|
|
|
object_class->dispose = gimp_dock_dispose;
|
2001-11-26 21:17:18 +08:00
|
|
|
|
2010-03-14 00:18:47 +08:00
|
|
|
klass->get_description = gimp_dock_real_get_description;
|
2009-09-13 20:14:08 +08:00
|
|
|
klass->set_host_geometry_hints = NULL;
|
|
|
|
klass->book_added = gimp_dock_real_book_added;
|
|
|
|
klass->book_removed = gimp_dock_real_book_removed;
|
2010-03-14 00:18:47 +08:00
|
|
|
klass->description_invalidated = NULL;
|
2009-09-13 20:14:08 +08:00
|
|
|
klass->geometry_invalidated = NULL;
|
2003-11-21 04:36:55 +08:00
|
|
|
|
2018-05-01 06:17:27 +08:00
|
|
|
gtk_widget_class_set_css_name (widget_class, "GimpDock");
|
2001-04-07 22:44:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_dock_init (GimpDock *dock)
|
|
|
|
{
|
2009-12-04 06:08:30 +08:00
|
|
|
static gint dock_ID = 1;
|
|
|
|
gchar *name = NULL;
|
|
|
|
|
2010-10-30 21:44:46 +08:00
|
|
|
gtk_orientable_set_orientation (GTK_ORIENTABLE (dock),
|
|
|
|
GTK_ORIENTATION_VERTICAL);
|
|
|
|
|
app, libgimp*, modules: don't use g_type_class_add_private() ...
... and G_TYPE_INSTANCE_GET_PRIVATE()
g_type_class_add_private() and G_TYPE_INSTANCE_GET_PRIVATE() were
deprecated in GLib 2.58. Instead, use
G_DEFINE_[ABSTRACT_]TYPE_WITH_PRIVATE(), and
G_ADD_PRIVATE[_DYNAMIC](), and the implictly-defined
foo_get_instance_private() functions, all of which are available in
the GLib versions we depend on.
This commit only covers types registered using one of the
G_DEFINE_FOO() macros (i.e., most types), but not types with a
custom registration function, of which we still have a few -- GLib
currently only provides a (non-deprecated) public API for adding a
private struct using the G_DEFINE_FOO() macros.
Note that this commit was 99% auto-generated (because I'm not
*that* crazy :), so if there are any style mismatches... we'll have
to live with them for now.
2018-09-19 00:09:39 +08:00
|
|
|
dock->p = gimp_dock_get_instance_private (dock);
|
2011-05-07 07:18:59 +08:00
|
|
|
dock->p->ID = dock_ID++;
|
2009-12-04 06:08:30 +08:00
|
|
|
|
|
|
|
name = g_strdup_printf ("gimp-internal-dock-%d", dock->p->ID);
|
|
|
|
gtk_widget_set_name (GTK_WIDGET (dock), name);
|
|
|
|
g_free (name);
|
2001-04-24 00:58:18 +08:00
|
|
|
|
2011-09-30 17:29:11 +08:00
|
|
|
dock->p->main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
2010-10-30 21:44:46 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (dock), dock->p->main_vbox, TRUE, TRUE, 0);
|
2009-09-06 06:15:25 +08:00
|
|
|
gtk_widget_show (dock->p->main_vbox);
|
2001-04-22 08:38:56 +08:00
|
|
|
|
2009-10-25 00:52:48 +08:00
|
|
|
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);
|
2010-10-30 21:44:46 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (dock->p->main_vbox), dock->p->paned_vbox,
|
|
|
|
TRUE, TRUE, 0);
|
2009-10-25 00:52:48 +08:00
|
|
|
gtk_widget_show (dock->p->paned_vbox);
|
2001-04-07 22:44:12 +08:00
|
|
|
}
|
|
|
|
|
2010-10-15 20:08:36 +08:00
|
|
|
static void
|
|
|
|
gimp_dock_dispose (GObject *object)
|
|
|
|
{
|
|
|
|
GimpDock *dock = GIMP_DOCK (object);
|
|
|
|
|
|
|
|
while (dock->p->dockbooks)
|
2012-02-21 07:36:18 +08:00
|
|
|
{
|
|
|
|
GimpDockbook *dockbook = dock->p->dockbooks->data;
|
|
|
|
|
|
|
|
g_object_ref (dockbook);
|
|
|
|
gimp_dock_remove_book (dock, dockbook);
|
|
|
|
gtk_widget_destroy (GTK_WIDGET (dockbook));
|
|
|
|
g_object_unref (dockbook);
|
|
|
|
}
|
2010-10-15 20:08:36 +08:00
|
|
|
|
|
|
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
|
|
|
}
|
|
|
|
|
2010-03-05 15:26:24 +08:00
|
|
|
static gchar *
|
2010-03-14 03:02:55 +08:00
|
|
|
gimp_dock_real_get_description (GimpDock *dock,
|
|
|
|
gboolean complete)
|
2010-03-05 15:26:24 +08:00
|
|
|
{
|
2010-03-14 00:18:47 +08:00
|
|
|
GString *desc;
|
2010-03-05 15:26:24 +08:00
|
|
|
GList *list;
|
|
|
|
|
2010-03-14 00:18:47 +08:00
|
|
|
desc = g_string_new (NULL);
|
2010-03-05 15:26:24 +08:00
|
|
|
|
|
|
|
for (list = gimp_dock_get_dockbooks (dock);
|
|
|
|
list;
|
|
|
|
list = g_list_next (list))
|
|
|
|
{
|
|
|
|
GimpDockbook *dockbook = list->data;
|
|
|
|
GList *children;
|
|
|
|
GList *child;
|
|
|
|
|
2010-03-14 03:02:55 +08:00
|
|
|
if (complete)
|
|
|
|
{
|
|
|
|
/* Include all dockables */
|
|
|
|
children = gtk_container_get_children (GTK_CONTAINER (dockbook));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GtkWidget *dockable = NULL;
|
|
|
|
gint page_num = 0;
|
|
|
|
|
|
|
|
page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook));
|
|
|
|
dockable = gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook), page_num);
|
|
|
|
|
|
|
|
/* Only include active dockables */
|
|
|
|
children = g_list_append (NULL, dockable);
|
|
|
|
}
|
2010-03-05 15:26:24 +08:00
|
|
|
|
|
|
|
for (child = children; child; child = g_list_next (child))
|
|
|
|
{
|
|
|
|
GimpDockable *dockable = child->data;
|
|
|
|
|
2010-03-14 00:18:47 +08:00
|
|
|
g_string_append (desc, gimp_dockable_get_name (dockable));
|
2010-03-05 15:26:24 +08:00
|
|
|
|
|
|
|
if (g_list_next (child))
|
2010-03-14 00:18:47 +08:00
|
|
|
g_string_append (desc, GIMP_DOCK_DOCKABLE_SEPARATOR);
|
2010-03-05 15:26:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
g_list_free (children);
|
|
|
|
|
|
|
|
if (g_list_next (list))
|
2010-03-14 00:18:47 +08:00
|
|
|
g_string_append (desc, GIMP_DOCK_BOOK_SEPARATOR);
|
2010-03-05 15:26:24 +08:00
|
|
|
}
|
|
|
|
|
2010-03-14 00:18:47 +08:00
|
|
|
return g_string_free (desc, FALSE);
|
2010-03-05 15:26:24 +08:00
|
|
|
}
|
|
|
|
|
2002-10-25 21:21:54 +08:00
|
|
|
static void
|
|
|
|
gimp_dock_real_book_added (GimpDock *dock,
|
|
|
|
GimpDockbook *dockbook)
|
|
|
|
{
|
2010-03-14 03:02:55 +08:00
|
|
|
g_signal_connect_object (dockbook, "switch-page",
|
|
|
|
G_CALLBACK (gimp_dock_invalidate_description),
|
|
|
|
dock, G_CONNECT_SWAPPED);
|
2002-10-25 21:21:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_dock_real_book_removed (GimpDock *dock,
|
|
|
|
GimpDockbook *dockbook)
|
|
|
|
{
|
2010-03-14 03:02:55 +08:00
|
|
|
g_signal_handlers_disconnect_by_func (dockbook,
|
|
|
|
gimp_dock_invalidate_description,
|
|
|
|
dock);
|
2002-10-25 21:21:54 +08:00
|
|
|
}
|
|
|
|
|
2010-03-07 17:25:24 +08:00
|
|
|
static void
|
2010-03-14 00:18:47 +08:00
|
|
|
gimp_dock_invalidate_description (GimpDock *dock)
|
2010-03-07 17:25:24 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_DOCK (dock));
|
|
|
|
|
2010-03-14 00:18:47 +08:00
|
|
|
g_signal_emit (dock, dock_signals[DESCRIPTION_INVALIDATED], 0);
|
2010-03-07 17:25:24 +08:00
|
|
|
}
|
|
|
|
|
2009-10-11 19:59:02 +08:00
|
|
|
static gboolean
|
2018-06-08 07:37:19 +08:00
|
|
|
gimp_dock_dropped_cb (GtkWidget *notebook,
|
|
|
|
GtkWidget *child,
|
app: Use a GdkWindow instead of GimpDockSeparators for dockable DND
Make drag-and-drop rearrangement of dockables happen directly in the
existing widget hierarchy so we don't have to use special, ugly
widgets (read GimpDockSeparator:s) for that.
More specifically, make edges of dockables and dockbooks have the same
semantics as the GimpDockSeparators had. We put a highlight colored
GdkWindow on top of the widget in question to highlight these special
drop areas. This GdkWindow is not taken into consideration in the GTK+
drag-and-drop code, so it does not interupt the DND interaction.
To achive this, there is a problem we must solve: Drag events in GTK+
are propagated inwards and out, but we sometimes want ancenstor
widgets to take care of drop events. We solve this by introducing the
concept of "drag handlers". A drag handler is asked if it will handle
a given drag event, and if it will, a client will let the drag event
be propagated upwards in the widget hierarchy. Right now, the
GimpPanedBox is the only "drag handler". The code could be generalized
more but it doesn't feel worth it at this point.
The size of the special drop area is 5px, the same size as the default
GtkPaned handles. This is because the plan is to later use these
handles as drop areas too.
Other changes of interest are:
* We need to take care of "drag-motion", "drag-drop" and widget
highlightning ourselves. We can not use the GtkDestDefaults
conveniences with gtk_drag_dest_set() any longer since we need more
control.
* Make the drop callback pass the insert index directly instead of a
GimpDockSeparator
* Add some GIMP_LOG() debug output for DND
* Disable the GimpDockSeparator code in GimpToolbox
2009-11-30 01:22:12 +08:00
|
|
|
gint insert_index,
|
|
|
|
gpointer data)
|
2009-10-11 19:59:02 +08:00
|
|
|
{
|
2016-11-24 02:16:36 +08:00
|
|
|
GimpDock *dock = GIMP_DOCK (data);
|
2018-06-08 07:37:19 +08:00
|
|
|
GimpDockbook *dockbook = GIMP_DOCKBOOK (notebook);
|
|
|
|
GimpDockable *dockable = GIMP_DOCKABLE (child);
|
2016-11-24 02:16:36 +08:00
|
|
|
GimpDialogFactory *factory;
|
2018-06-08 07:37:19 +08:00
|
|
|
GtkWidget *new_dockbook;
|
2009-10-11 19:59:02 +08:00
|
|
|
|
|
|
|
/* if dropping to the same dock, take care that we don't try
|
|
|
|
* to reorder the *only* dockable in the dock
|
|
|
|
*/
|
2018-06-08 07:37:19 +08:00
|
|
|
if (gimp_dockbook_get_dock (dockbook) == dock)
|
2009-10-11 19:59:02 +08:00
|
|
|
{
|
2018-06-08 08:40:31 +08:00
|
|
|
GList *children = gtk_container_get_children (GTK_CONTAINER (dockable));
|
|
|
|
gint n_dockables = g_list_length (children);
|
|
|
|
gint n_books = g_list_length (gimp_dock_get_dockbooks (dock));
|
2009-10-11 19:59:02 +08:00
|
|
|
|
|
|
|
g_list_free (children);
|
|
|
|
|
|
|
|
if (n_books == 1 && n_dockables == 1)
|
|
|
|
return TRUE; /* successfully do nothing */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Detach the dockable from the old dockbook */
|
|
|
|
g_object_ref (dockable);
|
2018-06-08 07:37:19 +08:00
|
|
|
gtk_notebook_detach_tab (GTK_NOTEBOOK (notebook), child);
|
2009-10-11 19:59:02 +08:00
|
|
|
|
|
|
|
/* Create a new dockbook */
|
2016-11-24 02:16:36 +08:00
|
|
|
factory = gimp_dock_get_dialog_factory (dock);
|
2018-06-08 07:37:19 +08:00
|
|
|
new_dockbook = gimp_dockbook_new (gimp_dialog_factory_get_menu_factory (factory));
|
|
|
|
gimp_dock_add_book (dock, GIMP_DOCKBOOK (new_dockbook), insert_index);
|
2009-10-11 19:59:02 +08:00
|
|
|
|
|
|
|
/* Add the dockable to new new dockbook */
|
2018-06-08 08:40:31 +08:00
|
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (new_dockbook), child, NULL);
|
2009-10-11 19:59:02 +08:00
|
|
|
g_object_unref (dockable);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-01-05 18:08:10 +08:00
|
|
|
|
2005-02-01 00:09:52 +08:00
|
|
|
/* public functions */
|
2001-04-11 04:38:42 +08:00
|
|
|
|
2010-03-14 03:02:55 +08:00
|
|
|
/**
|
|
|
|
* gimp_dock_get_description:
|
|
|
|
* @dock:
|
|
|
|
* @complete: If %TRUE, only includes the active dockables, i.e. not the
|
|
|
|
* dockables in a non-active GtkNotebook tab
|
|
|
|
*
|
|
|
|
* Returns: A string describing the contents of the dock.
|
|
|
|
**/
|
2009-09-13 19:14:18 +08:00
|
|
|
gchar *
|
2010-03-14 03:02:55 +08:00
|
|
|
gimp_dock_get_description (GimpDock *dock,
|
|
|
|
gboolean complete)
|
2009-09-13 19:14:18 +08:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DOCK (dock), NULL);
|
2009-09-13 20:14:08 +08:00
|
|
|
|
2010-03-14 00:18:47 +08:00
|
|
|
if (GIMP_DOCK_GET_CLASS (dock)->get_description)
|
2010-03-14 03:02:55 +08:00
|
|
|
return GIMP_DOCK_GET_CLASS (dock)->get_description (dock, complete);
|
2009-09-13 19:14:18 +08:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-09-13 20:14:08 +08:00
|
|
|
/**
|
|
|
|
* gimp_dock_set_host_geometry_hints:
|
|
|
|
* @dock: The dock
|
|
|
|
* @window: The #GtkWindow to adapt to hosting the dock
|
|
|
|
*
|
|
|
|
* Some docks have some specific needs on the #GtkWindow they are
|
|
|
|
* in. This function allows such docks to perform any such setup on
|
|
|
|
* the #GtkWindow they are in/will be put in.
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_dock_set_host_geometry_hints (GimpDock *dock,
|
|
|
|
GtkWindow *window)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_DOCK (dock));
|
|
|
|
g_return_if_fail (GTK_IS_WINDOW (window));
|
|
|
|
|
|
|
|
if (GIMP_DOCK_GET_CLASS (dock)->set_host_geometry_hints)
|
|
|
|
GIMP_DOCK_GET_CLASS (dock)->set_host_geometry_hints (dock, window);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_dock_invalidate_geometry:
|
|
|
|
* @dock:
|
|
|
|
*
|
|
|
|
* Call when the dock needs to setup its host #GtkWindow with
|
|
|
|
* GtkDock::set_host_geometry_hints().
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_dock_invalidate_geometry (GimpDock *dock)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_DOCK (dock));
|
|
|
|
|
|
|
|
g_signal_emit (dock, dock_signals[GEOMETRY_INVALIDATED], 0);
|
|
|
|
}
|
|
|
|
|
2010-01-06 20:33:47 +08:00
|
|
|
/**
|
|
|
|
* gimp_dock_update_with_context:
|
|
|
|
* @dock:
|
|
|
|
* @context:
|
|
|
|
*
|
|
|
|
* Set the @context on all dockables in the @dock.
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_dock_update_with_context (GimpDock *dock,
|
|
|
|
GimpContext *context)
|
|
|
|
{
|
|
|
|
GList *iter = NULL;
|
|
|
|
|
|
|
|
for (iter = gimp_dock_get_dockbooks (dock);
|
|
|
|
iter;
|
|
|
|
iter = g_list_next (iter))
|
|
|
|
{
|
|
|
|
GimpDockbook *dockbook = GIMP_DOCKBOOK (iter->data);
|
|
|
|
|
|
|
|
gimp_dockbook_update_with_context (dockbook, context);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-06 04:20:18 +08:00
|
|
|
/**
|
|
|
|
* gimp_dock_get_context:
|
|
|
|
* @dock:
|
|
|
|
*
|
|
|
|
* Returns: The #GimpContext for the #GimpDockWindow the @dock is in.
|
|
|
|
**/
|
2009-01-04 18:28:31 +08:00
|
|
|
GimpContext *
|
|
|
|
gimp_dock_get_context (GimpDock *dock)
|
|
|
|
{
|
2010-01-08 02:18:03 +08:00
|
|
|
GimpContext *context = NULL;
|
2009-12-06 04:20:18 +08:00
|
|
|
|
2009-01-04 18:28:31 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_DOCK (dock), NULL);
|
|
|
|
|
2010-01-05 18:08:10 +08:00
|
|
|
/* First try GimpDockColumns */
|
|
|
|
if (! context)
|
|
|
|
{
|
2011-05-05 04:40:40 +08:00
|
|
|
GimpDockColumns *dock_columns;
|
|
|
|
|
|
|
|
dock_columns =
|
|
|
|
GIMP_DOCK_COLUMNS (gtk_widget_get_ancestor (GTK_WIDGET (dock),
|
|
|
|
GIMP_TYPE_DOCK_COLUMNS));
|
2010-01-05 18:08:10 +08:00
|
|
|
|
|
|
|
if (dock_columns)
|
|
|
|
context = gimp_dock_columns_get_context (dock_columns);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Then GimpDockWindow */
|
|
|
|
if (! context)
|
|
|
|
{
|
|
|
|
GimpDockWindow *dock_window = gimp_dock_window_from_dock (dock);
|
|
|
|
|
|
|
|
if (dock_window)
|
|
|
|
context = gimp_dock_window_get_context (dock_window);
|
|
|
|
}
|
2009-12-06 04:20:18 +08:00
|
|
|
|
2010-01-08 02:18:03 +08:00
|
|
|
return context;
|
2009-01-04 18:28:31 +08:00
|
|
|
}
|
|
|
|
|
2009-12-06 04:20:18 +08:00
|
|
|
/**
|
|
|
|
* gimp_dock_get_dialog_factory:
|
|
|
|
* @dock:
|
|
|
|
*
|
|
|
|
* Returns: The #GimpDialogFactory for the #GimpDockWindow the @dock
|
|
|
|
* is in.
|
|
|
|
**/
|
2009-01-04 18:28:31 +08:00
|
|
|
GimpDialogFactory *
|
|
|
|
gimp_dock_get_dialog_factory (GimpDock *dock)
|
|
|
|
{
|
2010-01-08 02:18:03 +08:00
|
|
|
GimpDialogFactory *dialog_factory = NULL;
|
2009-12-06 04:20:18 +08:00
|
|
|
|
2009-01-04 18:28:31 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_DOCK (dock), NULL);
|
|
|
|
|
2010-01-08 02:18:03 +08:00
|
|
|
/* First try GimpDockColumns */
|
|
|
|
if (! dialog_factory)
|
|
|
|
{
|
2011-05-05 04:40:40 +08:00
|
|
|
GimpDockColumns *dock_columns;
|
|
|
|
|
|
|
|
dock_columns =
|
|
|
|
GIMP_DOCK_COLUMNS (gtk_widget_get_ancestor (GTK_WIDGET (dock),
|
|
|
|
GIMP_TYPE_DOCK_COLUMNS));
|
2010-01-08 02:18:03 +08:00
|
|
|
|
|
|
|
if (dock_columns)
|
|
|
|
dialog_factory = gimp_dock_columns_get_dialog_factory (dock_columns);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Then GimpDockWindow */
|
|
|
|
if (! dialog_factory)
|
|
|
|
{
|
|
|
|
GimpDockWindow *dock_window = gimp_dock_window_from_dock (dock);
|
|
|
|
|
|
|
|
if (dock_window)
|
2016-11-25 20:26:08 +08:00
|
|
|
dialog_factory = gimp_dock_container_get_dialog_factory (GIMP_DOCK_CONTAINER (dock_window));
|
2010-01-08 02:18:03 +08:00
|
|
|
}
|
2009-12-06 04:20:18 +08:00
|
|
|
|
2010-01-08 02:18:03 +08:00
|
|
|
return dialog_factory;
|
2009-01-04 18:28:31 +08:00
|
|
|
}
|
|
|
|
|
2009-12-06 04:20:18 +08:00
|
|
|
/**
|
|
|
|
* gimp_dock_get_ui_manager:
|
|
|
|
* @dock:
|
|
|
|
*
|
|
|
|
* Returns: The #GimpUIManager for the #GimpDockWindow the @dock is
|
|
|
|
* in.
|
|
|
|
**/
|
2009-09-21 01:24:04 +08:00
|
|
|
GimpUIManager *
|
|
|
|
gimp_dock_get_ui_manager (GimpDock *dock)
|
|
|
|
{
|
2010-01-08 02:18:03 +08:00
|
|
|
GimpUIManager *ui_manager = NULL;
|
2009-12-06 04:20:18 +08:00
|
|
|
|
2009-09-21 01:24:04 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_DOCK (dock), NULL);
|
|
|
|
|
2010-01-08 02:18:03 +08:00
|
|
|
/* First try GimpDockColumns */
|
|
|
|
if (! ui_manager)
|
|
|
|
{
|
2011-05-05 04:40:40 +08:00
|
|
|
GimpDockColumns *dock_columns;
|
|
|
|
|
|
|
|
dock_columns =
|
|
|
|
GIMP_DOCK_COLUMNS (gtk_widget_get_ancestor (GTK_WIDGET (dock),
|
|
|
|
GIMP_TYPE_DOCK_COLUMNS));
|
2010-01-08 02:18:03 +08:00
|
|
|
|
|
|
|
if (dock_columns)
|
|
|
|
ui_manager = gimp_dock_columns_get_ui_manager (dock_columns);
|
|
|
|
}
|
|
|
|
|
2011-05-14 00:56:03 +08:00
|
|
|
/* Then GimpDockContainer */
|
2010-01-08 02:18:03 +08:00
|
|
|
if (! ui_manager)
|
|
|
|
{
|
|
|
|
GimpDockWindow *dock_window = gimp_dock_window_from_dock (dock);
|
|
|
|
|
|
|
|
if (dock_window)
|
2011-05-14 00:56:03 +08:00
|
|
|
{
|
|
|
|
GimpDockContainer *dock_container = GIMP_DOCK_CONTAINER (dock_window);
|
|
|
|
|
|
|
|
ui_manager = gimp_dock_container_get_ui_manager (dock_container);
|
|
|
|
}
|
2010-01-08 02:18:03 +08:00
|
|
|
}
|
2009-12-06 04:20:18 +08:00
|
|
|
|
2010-01-08 02:18:03 +08:00
|
|
|
return ui_manager;
|
2009-09-21 01:24:04 +08:00
|
|
|
}
|
|
|
|
|
2009-01-04 18:28:31 +08:00
|
|
|
GList *
|
|
|
|
gimp_dock_get_dockbooks (GimpDock *dock)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DOCK (dock), NULL);
|
|
|
|
|
2009-09-06 06:15:25 +08:00
|
|
|
return dock->p->dockbooks;
|
2009-01-04 18:28:31 +08:00
|
|
|
}
|
|
|
|
|
2009-09-13 17:51:39 +08:00
|
|
|
gint
|
|
|
|
gimp_dock_get_n_dockables (GimpDock *dock)
|
|
|
|
{
|
|
|
|
GList *list = NULL;
|
|
|
|
gint n = 0;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GIMP_IS_DOCK (dock), 0);
|
|
|
|
|
|
|
|
for (list = dock->p->dockbooks; list; list = list->next)
|
|
|
|
n += gtk_notebook_get_n_pages (GTK_NOTEBOOK (list->data));
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2009-01-04 18:28:31 +08:00
|
|
|
GtkWidget *
|
|
|
|
gimp_dock_get_main_vbox (GimpDock *dock)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DOCK (dock), NULL);
|
|
|
|
|
2009-09-06 06:15:25 +08:00
|
|
|
return dock->p->main_vbox;
|
2009-01-04 18:28:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
GtkWidget *
|
|
|
|
gimp_dock_get_vbox (GimpDock *dock)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DOCK (dock), NULL);
|
|
|
|
|
2009-10-25 00:52:48 +08:00
|
|
|
return dock->p->paned_vbox;
|
2009-01-04 18:28:31 +08:00
|
|
|
}
|
|
|
|
|
2011-04-22 01:56:42 +08:00
|
|
|
void
|
|
|
|
gimp_dock_set_id (GimpDock *dock,
|
|
|
|
gint ID)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_DOCK (dock));
|
|
|
|
|
|
|
|
dock->p->ID = ID;
|
|
|
|
}
|
|
|
|
|
2018-06-08 08:40:31 +08:00
|
|
|
gint
|
|
|
|
gimp_dock_get_id (GimpDock *dock)
|
2001-04-11 00:03:40 +08:00
|
|
|
{
|
2018-06-08 08:40:31 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_DOCK (dock), 0);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2018-06-08 08:40:31 +08:00
|
|
|
return dock->p->ID;
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dock_add_book (GimpDock *dock,
|
2006-04-12 20:49:29 +08:00
|
|
|
GimpDockbook *dockbook,
|
|
|
|
gint index)
|
2001-04-11 00:03:40 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_DOCK (dock));
|
|
|
|
g_return_if_fail (GIMP_IS_DOCKBOOK (dockbook));
|
2009-09-13 22:30:09 +08:00
|
|
|
g_return_if_fail (gimp_dockbook_get_dock (dockbook) == NULL);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2009-09-13 22:30:09 +08:00
|
|
|
gimp_dockbook_set_dock (dockbook, dock);
|
2002-03-22 06:23:39 +08:00
|
|
|
|
2010-03-07 17:25:24 +08:00
|
|
|
g_signal_connect_object (dockbook, "dockable-added",
|
2010-03-14 00:18:47 +08:00
|
|
|
G_CALLBACK (gimp_dock_invalidate_description),
|
2010-03-07 17:25:24 +08:00
|
|
|
dock, G_CONNECT_SWAPPED);
|
|
|
|
g_signal_connect_object (dockbook, "dockable-removed",
|
2010-03-14 00:18:47 +08:00
|
|
|
G_CALLBACK (gimp_dock_invalidate_description),
|
2010-03-07 17:25:24 +08:00
|
|
|
dock, G_CONNECT_SWAPPED);
|
|
|
|
g_signal_connect_object (dockbook, "dockable-reordered",
|
2010-03-14 00:18:47 +08:00
|
|
|
G_CALLBACK (gimp_dock_invalidate_description),
|
2010-03-07 17:25:24 +08:00
|
|
|
dock, G_CONNECT_SWAPPED);
|
|
|
|
|
2009-10-25 18:49:54 +08:00
|
|
|
dock->p->dockbooks = g_list_insert (dock->p->dockbooks, dockbook, index);
|
2009-10-25 00:52:48 +08:00
|
|
|
gimp_paned_box_add_widget (GIMP_PANED_BOX (dock->p->paned_vbox),
|
|
|
|
GTK_WIDGET (dockbook),
|
|
|
|
index);
|
2002-03-22 06:23:39 +08:00
|
|
|
gtk_widget_show (GTK_WIDGET (dockbook));
|
2002-10-25 21:21:54 +08:00
|
|
|
|
2010-03-14 00:18:47 +08:00
|
|
|
gimp_dock_invalidate_description (dock);
|
2010-03-07 17:25:24 +08:00
|
|
|
|
2003-01-06 06:07:10 +08:00
|
|
|
g_signal_emit (dock, dock_signals[BOOK_ADDED], 0, dockbook);
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dock_remove_book (GimpDock *dock,
|
2006-04-12 20:49:29 +08:00
|
|
|
GimpDockbook *dockbook)
|
2001-04-11 00:03:40 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_DOCK (dock));
|
|
|
|
g_return_if_fail (GIMP_IS_DOCKBOOK (dockbook));
|
2009-09-13 22:30:09 +08:00
|
|
|
g_return_if_fail (gimp_dockbook_get_dock (dockbook) == dock);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2009-09-13 22:30:09 +08:00
|
|
|
gimp_dockbook_set_dock (dockbook, NULL);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2010-03-07 17:25:24 +08:00
|
|
|
g_signal_handlers_disconnect_by_func (dockbook,
|
2010-03-14 00:18:47 +08:00
|
|
|
gimp_dock_invalidate_description,
|
2010-03-07 17:25:24 +08:00
|
|
|
dock);
|
|
|
|
|
2009-10-11 22:58:59 +08:00
|
|
|
/* Ref the dockbook so we can emit the "book-removed" signal and
|
|
|
|
* pass it as a parameter before it's destroyed
|
|
|
|
*/
|
2002-10-25 21:21:54 +08:00
|
|
|
g_object_ref (dockbook);
|
|
|
|
|
2009-10-25 00:52:48 +08:00
|
|
|
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));
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2010-03-14 00:18:47 +08:00
|
|
|
gimp_dock_invalidate_description (dock);
|
2010-03-07 17:25:24 +08:00
|
|
|
|
2003-01-06 06:07:10 +08:00
|
|
|
g_signal_emit (dock, dock_signals[BOOK_REMOVED], 0, dockbook);
|
2002-10-25 21:21:54 +08:00
|
|
|
|
|
|
|
g_object_unref (dockbook);
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|