2006-12-10 05:33:38 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
2001-04-11 00:03:40 +08:00
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
|
|
|
* gimpdockbook.c
|
2007-09-17 23:40:01 +08:00
|
|
|
* Copyright (C) 2001-2007 Michael Natterer <mitch@gimp.org>
|
2001-04-11 00:03:40 +08:00
|
|
|
*
|
2009-01-18 06:28:01 +08:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
2001-04-11 00:03:40 +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-11 00:03:40 +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
|
2009-01-18 06:28:01 +08:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2001-04-11 00:03:40 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2001-11-24 00:25:01 +08:00
|
|
|
#include <string.h>
|
|
|
|
|
2012-03-30 01:19:01 +08:00
|
|
|
#include <gegl.h>
|
2001-04-11 00:03:40 +08:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
|
|
|
#include "libgimpwidgets/gimpwidgets.h"
|
|
|
|
|
2001-05-08 11:48:54 +08:00
|
|
|
#include "widgets-types.h"
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2017-03-10 13:04:20 +08:00
|
|
|
#include "config/gimpguiconfig.h"
|
|
|
|
|
|
|
|
#include "core/gimp.h"
|
2003-01-11 01:55:53 +08:00
|
|
|
#include "core/gimpcontext.h"
|
2003-05-03 19:59:44 +08:00
|
|
|
#include "core/gimpmarshal.h"
|
2003-01-11 01:55:53 +08:00
|
|
|
|
2011-07-03 22:36:38 +08:00
|
|
|
#include "gimpdialogfactory.h"
|
2001-05-08 11:48:54 +08:00
|
|
|
#include "gimpdnd.h"
|
2009-09-13 15:31:21 +08:00
|
|
|
#include "gimpdock.h"
|
2001-04-11 00:03:40 +08:00
|
|
|
#include "gimpdockable.h"
|
|
|
|
#include "gimpdockbook.h"
|
2008-05-20 05:11:03 +08:00
|
|
|
#include "gimpdocked.h"
|
2011-05-14 00:56:03 +08:00
|
|
|
#include "gimpdockcontainer.h"
|
2009-09-15 13:58:14 +08:00
|
|
|
#include "gimpdockwindow.h"
|
2003-08-26 18:07:01 +08:00
|
|
|
#include "gimphelp-ids.h"
|
2003-01-11 01:55:53 +08:00
|
|
|
#include "gimpmenufactory.h"
|
2009-10-25 00:52:48 +08:00
|
|
|
#include "gimppanedbox.h"
|
2005-10-31 02:41:18 +08:00
|
|
|
#include "gimpstringaction.h"
|
|
|
|
#include "gimpuimanager.h"
|
2004-08-25 01:16:46 +08:00
|
|
|
#include "gimpview.h"
|
2005-10-31 02:41:18 +08:00
|
|
|
#include "gimpwidgets-utils.h"
|
2001-11-24 00:25:01 +08:00
|
|
|
|
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
|
|
|
#include "gimp-log.h"
|
2010-05-27 00:10:31 +08:00
|
|
|
#include "gimp-intl.h"
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2010-05-27 00:10:31 +08:00
|
|
|
#define DEFAULT_TAB_BORDER 0
|
|
|
|
#define DEFAULT_TAB_ICON_SIZE GTK_ICON_SIZE_BUTTON
|
|
|
|
#define DND_WIDGET_ICON_SIZE GTK_ICON_SIZE_BUTTON
|
|
|
|
#define MENU_WIDGET_ICON_SIZE GTK_ICON_SIZE_MENU
|
|
|
|
#define MENU_WIDGET_SPACING 4
|
|
|
|
#define TAB_HOVER_TIMEOUT 500
|
|
|
|
#define GIMP_DOCKABLE_DETACH_REF_KEY "gimp-dockable-detach-ref"
|
2001-05-07 00:14:34 +08:00
|
|
|
|
|
|
|
|
2003-05-03 19:59:44 +08:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
DOCKABLE_ADDED,
|
|
|
|
DOCKABLE_REMOVED,
|
|
|
|
DOCKABLE_REORDERED,
|
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
2012-02-02 03:38:10 +08:00
|
|
|
/* List of candidates for the automatic style, starting with the
|
|
|
|
* biggest first
|
|
|
|
*/
|
|
|
|
static const GimpTabStyle gimp_tab_style_candidates[] =
|
|
|
|
{
|
|
|
|
GIMP_TAB_STYLE_PREVIEW_BLURB,
|
|
|
|
GIMP_TAB_STYLE_PREVIEW_NAME,
|
|
|
|
GIMP_TAB_STYLE_PREVIEW
|
|
|
|
};
|
|
|
|
|
2009-09-13 22:30:09 +08:00
|
|
|
struct _GimpDockbookPrivate
|
|
|
|
{
|
2010-06-12 05:18:49 +08:00
|
|
|
GimpDock *dock;
|
|
|
|
GimpUIManager *ui_manager;
|
2009-09-13 22:30:09 +08:00
|
|
|
|
2010-06-12 05:18:49 +08:00
|
|
|
guint tab_hover_timeout;
|
|
|
|
GimpDockable *tab_hover_dockable;
|
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
|
|
|
|
2010-06-12 05:18:49 +08:00
|
|
|
GimpPanedBox *drag_handler;
|
|
|
|
|
|
|
|
/* Cache for "what actual tab style for automatic styles can we use
|
|
|
|
* for a given dockbook width
|
|
|
|
*/
|
2012-02-02 03:38:10 +08:00
|
|
|
gint min_width_for_style[G_N_ELEMENTS (gimp_tab_style_candidates)];
|
2010-06-12 05:18:49 +08:00
|
|
|
|
|
|
|
/* We need a list separate from the GtkContainer children list,
|
|
|
|
* because we need to do calculations for all dockables before we
|
|
|
|
* can add a dockable as a child, namely automatic tab style
|
|
|
|
* calculations
|
|
|
|
*/
|
|
|
|
GList *dockables;
|
|
|
|
|
|
|
|
GtkWidget *menu_button;
|
2009-09-13 22:30:09 +08:00
|
|
|
};
|
|
|
|
|
2003-05-03 19:59:44 +08:00
|
|
|
|
2010-06-11 13:35:07 +08:00
|
|
|
static void gimp_dockbook_dispose (GObject *object);
|
|
|
|
static void gimp_dockbook_finalize (GObject *object);
|
2010-06-12 05:18:49 +08:00
|
|
|
static void gimp_dockbook_size_allocate (GtkWidget *widget,
|
|
|
|
GtkAllocation *allocation);
|
2010-06-11 13:35:07 +08:00
|
|
|
static void gimp_dockbook_style_set (GtkWidget *widget,
|
|
|
|
GtkStyle *prev_style);
|
|
|
|
static void gimp_dockbook_drag_leave (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
guint time);
|
|
|
|
static gboolean gimp_dockbook_drag_motion (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
guint time);
|
|
|
|
static gboolean gimp_dockbook_drag_drop (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
guint time);
|
2010-05-27 00:10:31 +08:00
|
|
|
static gboolean gimp_dockbook_popup_menu (GtkWidget *widget);
|
|
|
|
static gboolean gimp_dockbook_menu_button_press (GimpDockbook *dockbook,
|
|
|
|
GdkEventButton *bevent,
|
|
|
|
GtkWidget *button);
|
|
|
|
static gboolean gimp_dockbook_show_menu (GimpDockbook *dockbook);
|
|
|
|
static void gimp_dockbook_menu_end (GimpDockable *dockable);
|
2010-06-11 13:35:07 +08:00
|
|
|
static void gimp_dockbook_dockable_added (GimpDockbook *dockbook,
|
|
|
|
GimpDockable *dockable);
|
|
|
|
static void gimp_dockbook_dockable_removed (GimpDockbook *dockbook,
|
|
|
|
GimpDockable *dockable);
|
2010-06-12 05:18:49 +08:00
|
|
|
static void gimp_dockbook_recreate_tab_widgets (GimpDockbook *dockbook,
|
|
|
|
gboolean only_auto);
|
2010-06-11 13:35:07 +08:00
|
|
|
static void gimp_dockbook_tab_drag_source_setup (GtkWidget *widget,
|
|
|
|
GimpDockable *dockable);
|
|
|
|
static void gimp_dockbook_tab_drag_begin (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
GimpDockable *dockable);
|
|
|
|
static void gimp_dockbook_tab_drag_end (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
GimpDockable *dockable);
|
|
|
|
static void gimp_dockbook_tab_drag_leave (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
guint time,
|
|
|
|
GimpDockable *dockable);
|
|
|
|
static gboolean gimp_dockbook_tab_drag_motion (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
guint time,
|
|
|
|
GimpDockable *dockable);
|
|
|
|
static gboolean gimp_dockbook_tab_drag_drop (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
guint time);
|
2012-09-11 00:22:12 +08:00
|
|
|
static GimpTabStyle gimp_dockbook_tab_style_to_preferred (GimpTabStyle tab_style,
|
2010-06-12 05:18:49 +08:00
|
|
|
GimpDockable *dockable);
|
|
|
|
static void gimp_dockbook_refresh_tab_layout_lut (GimpDockbook *dockbook);
|
|
|
|
static void gimp_dockbook_update_automatic_tab_style (GimpDockbook *dockbook);
|
2010-06-11 13:35:07 +08:00
|
|
|
static GtkWidget * gimp_dockable_create_event_box_tab_widget (GimpDockable *dockable,
|
|
|
|
GimpContext *context,
|
|
|
|
GimpTabStyle tab_style,
|
|
|
|
GtkIconSize size);
|
|
|
|
static GtkIconSize gimp_dockbook_get_tab_icon_size (GimpDockbook *dockbook);
|
2017-03-11 09:42:10 +08:00
|
|
|
static gint gimp_dockbook_get_tab_border (GimpDockbook *dockbook);
|
2010-06-11 13:35:07 +08:00
|
|
|
static void gimp_dockbook_add_tab_timeout (GimpDockbook *dockbook,
|
|
|
|
GimpDockable *dockable);
|
|
|
|
static void gimp_dockbook_remove_tab_timeout (GimpDockbook *dockbook);
|
|
|
|
static gboolean gimp_dockbook_tab_timeout (GimpDockbook *dockbook);
|
|
|
|
static void gimp_dockbook_tab_locked_notify (GimpDockable *dockable,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
GimpDockbook *dockbook);
|
|
|
|
static void gimp_dockbook_help_func (const gchar *help_id,
|
|
|
|
gpointer help_data);
|
2010-06-12 05:18:49 +08:00
|
|
|
static const gchar *gimp_dockbook_get_tab_style_name (GimpTabStyle tab_style);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2017-03-17 12:52:20 +08:00
|
|
|
static void gimp_dockbook_config_size_changed (GimpGuiConfig *config,
|
2017-03-10 13:04:20 +08:00
|
|
|
GimpDockbook *dockbook);
|
|
|
|
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2006-05-15 17:46:31 +08:00
|
|
|
G_DEFINE_TYPE (GimpDockbook, gimp_dockbook, GTK_TYPE_NOTEBOOK)
|
2005-12-20 06:37:49 +08:00
|
|
|
|
|
|
|
#define parent_class gimp_dockbook_parent_class
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2005-12-20 06:37:49 +08:00
|
|
|
static guint dockbook_signals[LAST_SIGNAL] = { 0 };
|
2003-05-03 19:59:44 +08:00
|
|
|
|
2006-04-06 20:43:58 +08:00
|
|
|
static const GtkTargetEntry dialog_target_table[] = { GIMP_TARGET_DIALOG };
|
2001-04-11 00:03:40 +08:00
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_dockbook_class_init (GimpDockbookClass *klass)
|
|
|
|
{
|
2005-08-03 17:34:55 +08:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2003-05-03 19:59:44 +08:00
|
|
|
dockbook_signals[DOCKABLE_ADDED] =
|
2005-05-27 21:05:26 +08:00
|
|
|
g_signal_new ("dockable-added",
|
2004-08-25 01:16:46 +08:00
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
G_STRUCT_OFFSET (GimpDockbookClass, dockable_added),
|
|
|
|
NULL, NULL,
|
|
|
|
gimp_marshal_VOID__OBJECT,
|
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
GIMP_TYPE_DOCKABLE);
|
2003-05-03 19:59:44 +08:00
|
|
|
|
|
|
|
dockbook_signals[DOCKABLE_REMOVED] =
|
2005-05-27 21:05:26 +08:00
|
|
|
g_signal_new ("dockable-removed",
|
2004-08-25 01:16:46 +08:00
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
G_STRUCT_OFFSET (GimpDockbookClass, dockable_removed),
|
|
|
|
NULL, NULL,
|
|
|
|
gimp_marshal_VOID__OBJECT,
|
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
GIMP_TYPE_DOCKABLE);
|
2003-05-03 19:59:44 +08:00
|
|
|
|
|
|
|
dockbook_signals[DOCKABLE_REORDERED] =
|
2005-05-27 21:05:26 +08:00
|
|
|
g_signal_new ("dockable-reordered",
|
2004-08-25 01:16:46 +08:00
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
G_STRUCT_OFFSET (GimpDockbookClass, dockable_reordered),
|
|
|
|
NULL, NULL,
|
|
|
|
gimp_marshal_VOID__OBJECT,
|
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
GIMP_TYPE_DOCKABLE);
|
2003-05-03 19:59:44 +08:00
|
|
|
|
2007-09-17 23:40:01 +08:00
|
|
|
object_class->dispose = gimp_dockbook_dispose;
|
2003-05-03 19:59:44 +08:00
|
|
|
object_class->finalize = gimp_dockbook_finalize;
|
|
|
|
|
2010-06-12 05:18:49 +08:00
|
|
|
widget_class->size_allocate = gimp_dockbook_size_allocate;
|
|
|
|
widget_class->style_set = gimp_dockbook_style_set;
|
|
|
|
widget_class->drag_leave = gimp_dockbook_drag_leave;
|
|
|
|
widget_class->drag_motion = gimp_dockbook_drag_motion;
|
|
|
|
widget_class->drag_drop = gimp_dockbook_drag_drop;
|
2010-05-27 00:10:31 +08:00
|
|
|
widget_class->popup_menu = gimp_dockbook_popup_menu;
|
2003-05-03 19:59:44 +08:00
|
|
|
|
2003-10-06 01:26:21 +08:00
|
|
|
klass->dockable_added = gimp_dockbook_dockable_added;
|
|
|
|
klass->dockable_removed = gimp_dockbook_dockable_removed;
|
2003-05-03 19:59:44 +08:00
|
|
|
klass->dockable_reordered = NULL;
|
2001-11-30 00:44:51 +08:00
|
|
|
|
|
|
|
gtk_widget_class_install_style_property (widget_class,
|
2005-05-27 21:05:26 +08:00
|
|
|
g_param_spec_int ("tab-border",
|
2001-11-30 00:44:51 +08:00
|
|
|
NULL, NULL,
|
2002-03-19 03:34:06 +08:00
|
|
|
0, G_MAXINT,
|
|
|
|
DEFAULT_TAB_BORDER,
|
2006-01-19 04:29:40 +08:00
|
|
|
GIMP_PARAM_READABLE));
|
2002-03-19 03:34:06 +08:00
|
|
|
gtk_widget_class_install_style_property (widget_class,
|
2005-05-27 21:05:26 +08:00
|
|
|
g_param_spec_enum ("tab-icon-size",
|
2002-05-10 22:50:27 +08:00
|
|
|
NULL, NULL,
|
|
|
|
GTK_TYPE_ICON_SIZE,
|
2003-03-22 03:18:52 +08:00
|
|
|
DEFAULT_TAB_ICON_SIZE,
|
2006-01-19 04:29:40 +08:00
|
|
|
GIMP_PARAM_READABLE));
|
2009-09-13 22:30:09 +08:00
|
|
|
|
|
|
|
g_type_class_add_private (klass, sizeof (GimpDockbookPrivate));
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_dockbook_init (GimpDockbook *dockbook)
|
|
|
|
{
|
2010-02-01 03:22:24 +08:00
|
|
|
GtkNotebook *notebook = GTK_NOTEBOOK (dockbook);
|
2010-05-27 00:10:31 +08:00
|
|
|
GtkWidget *image = NULL;
|
2010-02-01 03:22:24 +08:00
|
|
|
|
2009-09-13 22:30:09 +08:00
|
|
|
dockbook->p = G_TYPE_INSTANCE_GET_PRIVATE (dockbook,
|
|
|
|
GIMP_TYPE_DOCKBOOK,
|
|
|
|
GimpDockbookPrivate);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2010-05-27 00:10:31 +08:00
|
|
|
/* Various init */
|
2010-02-01 03:22:24 +08:00
|
|
|
gtk_notebook_popup_enable (notebook);
|
|
|
|
gtk_notebook_set_scrollable (notebook, TRUE);
|
|
|
|
gtk_notebook_set_show_border (notebook, FALSE);
|
2010-05-27 00:10:31 +08:00
|
|
|
gtk_notebook_set_show_tabs (notebook, TRUE);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
|
|
|
gtk_drag_dest_set (GTK_WIDGET (dockbook),
|
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
|
|
|
0,
|
2001-10-17 19:33:43 +08:00
|
|
|
dialog_target_table, G_N_ELEMENTS (dialog_target_table),
|
2001-04-11 00:03:40 +08:00
|
|
|
GDK_ACTION_MOVE);
|
2010-05-27 00:10:31 +08:00
|
|
|
|
|
|
|
/* Menu button */
|
|
|
|
dockbook->p->menu_button = gtk_button_new ();
|
|
|
|
gtk_widget_set_can_focus (dockbook->p->menu_button, FALSE);
|
|
|
|
gtk_button_set_relief (GTK_BUTTON (dockbook->p->menu_button),
|
|
|
|
GTK_RELIEF_NONE);
|
2011-11-17 07:17:46 +08:00
|
|
|
gtk_notebook_set_action_widget (notebook,
|
|
|
|
dockbook->p->menu_button,
|
|
|
|
GTK_PACK_END);
|
2010-05-27 00:10:31 +08:00
|
|
|
gtk_widget_show (dockbook->p->menu_button);
|
|
|
|
|
2017-03-05 23:01:59 +08:00
|
|
|
image = gtk_image_new_from_icon_name (GIMP_ICON_MENU_LEFT,
|
|
|
|
GTK_ICON_SIZE_MENU);
|
2014-05-07 21:30:38 +08:00
|
|
|
gtk_image_set_pixel_size (GTK_IMAGE (image), 12);
|
2017-03-05 23:01:59 +08:00
|
|
|
gtk_image_set_from_icon_name (GTK_IMAGE (image), GIMP_ICON_MENU_LEFT,
|
|
|
|
GTK_ICON_SIZE_MENU);
|
2010-05-27 00:10:31 +08:00
|
|
|
gtk_container_add (GTK_CONTAINER (dockbook->p->menu_button), image);
|
|
|
|
gtk_widget_show (image);
|
|
|
|
|
|
|
|
gimp_help_set_help_data (dockbook->p->menu_button, _("Configure this tab"),
|
|
|
|
GIMP_HELP_DOCK_TAB_MENU);
|
|
|
|
|
|
|
|
g_signal_connect_swapped (dockbook->p->menu_button, "button-press-event",
|
|
|
|
G_CALLBACK (gimp_dockbook_menu_button_press),
|
|
|
|
dockbook);
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
|
|
|
|
2007-09-17 23:40:01 +08:00
|
|
|
static void
|
|
|
|
gimp_dockbook_dispose (GObject *object)
|
|
|
|
{
|
|
|
|
GimpDockbook *dockbook = GIMP_DOCKBOOK (object);
|
|
|
|
|
|
|
|
gimp_dockbook_remove_tab_timeout (dockbook);
|
|
|
|
|
2010-06-27 05:23:50 +08:00
|
|
|
while (dockbook->p->dockables)
|
2012-02-21 07:36:18 +08:00
|
|
|
{
|
|
|
|
GimpDockable *dockable = dockbook->p->dockables->data;
|
|
|
|
|
|
|
|
g_object_ref (dockable);
|
|
|
|
gimp_dockbook_remove (dockbook, dockable);
|
|
|
|
gtk_widget_destroy (GTK_WIDGET (dockable));
|
|
|
|
g_object_unref (dockable);
|
|
|
|
}
|
2010-06-27 05:23:50 +08:00
|
|
|
|
2007-09-17 23:40:01 +08:00
|
|
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
|
|
|
}
|
|
|
|
|
2003-01-11 01:55:53 +08:00
|
|
|
static void
|
|
|
|
gimp_dockbook_finalize (GObject *object)
|
|
|
|
{
|
2003-10-06 01:26:21 +08:00
|
|
|
GimpDockbook *dockbook = GIMP_DOCKBOOK (object);
|
2003-01-11 01:55:53 +08:00
|
|
|
|
2017-07-16 00:38:01 +08:00
|
|
|
g_clear_object (&dockbook->p->ui_manager);
|
|
|
|
|
2017-03-13 01:36:16 +08:00
|
|
|
if (dockbook->p->dock)
|
|
|
|
{
|
|
|
|
g_signal_handlers_disconnect_by_func (gimp_dock_get_context (dockbook->p->dock)->gimp->config,
|
2017-07-16 00:38:01 +08:00
|
|
|
gimp_dockbook_config_size_changed,
|
2017-03-13 01:36:16 +08:00
|
|
|
dockbook);
|
|
|
|
dockbook->p->dock = NULL;
|
|
|
|
}
|
2004-04-23 01:14:22 +08:00
|
|
|
|
2003-01-11 01:55:53 +08:00
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
2010-06-12 05:18:49 +08:00
|
|
|
static void
|
|
|
|
gimp_dockbook_size_allocate (GtkWidget *widget,
|
|
|
|
GtkAllocation *allocation)
|
|
|
|
{
|
|
|
|
GimpDockbook *dockbook = GIMP_DOCKBOOK (widget);
|
|
|
|
|
|
|
|
GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
|
|
|
|
|
|
|
|
/* Update tab styles, also recreates if changed */
|
|
|
|
gimp_dockbook_update_automatic_tab_style (dockbook);
|
|
|
|
}
|
|
|
|
|
2001-11-30 00:44:51 +08:00
|
|
|
static void
|
|
|
|
gimp_dockbook_style_set (GtkWidget *widget,
|
|
|
|
GtkStyle *prev_style)
|
|
|
|
{
|
2008-03-30 07:43:39 +08:00
|
|
|
GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style);
|
2001-11-30 00:44:51 +08:00
|
|
|
|
2010-01-05 18:29:54 +08:00
|
|
|
/* Don't attempt to construct widgets that require a GimpContext if
|
|
|
|
* we are detached from a top-level, we're either on our way to
|
|
|
|
* destruction, in which case we don't care, or we will be given a
|
|
|
|
* new parent, in which case the widget style will be reset again
|
|
|
|
* anyway, i.e. this function will be called again
|
|
|
|
*/
|
|
|
|
if (! gtk_widget_is_toplevel (gtk_widget_get_toplevel (widget)))
|
|
|
|
return;
|
|
|
|
|
2010-06-12 05:18:49 +08:00
|
|
|
gimp_dockbook_recreate_tab_widgets (GIMP_DOCKBOOK (widget),
|
|
|
|
FALSE /*only_auto*/);
|
2001-11-30 00:44:51 +08:00
|
|
|
}
|
|
|
|
|
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
|
|
|
static void
|
|
|
|
gimp_dockbook_drag_leave (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
guint time)
|
|
|
|
{
|
|
|
|
gimp_highlight_widget (widget, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_dockbook_drag_motion (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
guint time)
|
|
|
|
{
|
2015-02-20 04:18:21 +08:00
|
|
|
GimpDockbook *dockbook = GIMP_DOCKBOOK (widget);
|
|
|
|
|
|
|
|
if (gimp_paned_box_will_handle_drag (dockbook->p->drag_handler,
|
|
|
|
widget,
|
|
|
|
context,
|
|
|
|
x, y,
|
|
|
|
time))
|
|
|
|
{
|
|
|
|
gdk_drag_status (context, 0, time);
|
|
|
|
gimp_highlight_widget (widget, FALSE);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gdk_drag_status (context, GDK_ACTION_MOVE, time);
|
|
|
|
gimp_highlight_widget (widget, TRUE);
|
|
|
|
|
|
|
|
/* Return TRUE so drag_leave() is called */
|
|
|
|
return TRUE;
|
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
|
|
|
}
|
|
|
|
|
2001-04-11 00:03:40 +08:00
|
|
|
static gboolean
|
|
|
|
gimp_dockbook_drag_drop (GtkWidget *widget,
|
2004-08-25 01:16:46 +08:00
|
|
|
GdkDragContext *context,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
guint time)
|
2001-04-11 00:03:40 +08:00
|
|
|
{
|
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
|
|
|
GimpDockbook *dockbook = GIMP_DOCKBOOK (widget);
|
2015-02-20 04:18:21 +08:00
|
|
|
gboolean dropped;
|
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
|
|
|
|
|
|
|
if (gimp_paned_box_will_handle_drag (dockbook->p->drag_handler,
|
|
|
|
widget,
|
|
|
|
context,
|
|
|
|
x, y,
|
|
|
|
time))
|
|
|
|
{
|
2015-02-20 04:18:21 +08:00
|
|
|
return FALSE;
|
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
|
|
|
}
|
|
|
|
|
2015-02-20 04:18:21 +08:00
|
|
|
dropped = gimp_dockbook_drop_dockable (dockbook,
|
|
|
|
gtk_drag_get_source_widget (context));
|
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
|
|
|
|
2015-02-20 04:18:21 +08:00
|
|
|
gtk_drag_finish (context, dropped, TRUE, time);
|
|
|
|
|
|
|
|
return TRUE;
|
2003-10-06 01:26:21 +08:00
|
|
|
}
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2010-05-27 00:10:31 +08:00
|
|
|
static gboolean
|
|
|
|
gimp_dockbook_popup_menu (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
return gimp_dockbook_show_menu (GIMP_DOCKBOOK (widget));
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_dockbook_menu_button_press (GimpDockbook *dockbook,
|
|
|
|
GdkEventButton *bevent,
|
|
|
|
GtkWidget *button)
|
|
|
|
{
|
|
|
|
gboolean handled = FALSE;
|
|
|
|
|
|
|
|
if (bevent->button == 1 && bevent->type == GDK_BUTTON_PRESS)
|
|
|
|
handled = gimp_dockbook_show_menu (dockbook);
|
|
|
|
|
|
|
|
return handled;
|
|
|
|
}
|
|
|
|
|
2010-06-12 17:38:15 +08:00
|
|
|
static void
|
|
|
|
gimp_dockbook_menu_position (GtkMenu *menu,
|
|
|
|
gint *x,
|
|
|
|
gint *y,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
GimpDockbook *dockbook = GIMP_DOCKBOOK (data);
|
|
|
|
|
|
|
|
gimp_button_menu_position (dockbook->p->menu_button, menu, GTK_POS_LEFT, x, y);
|
|
|
|
}
|
|
|
|
|
2010-05-27 00:10:31 +08:00
|
|
|
static gboolean
|
|
|
|
gimp_dockbook_show_menu (GimpDockbook *dockbook)
|
|
|
|
{
|
|
|
|
GimpUIManager *dockbook_ui_manager = NULL;
|
|
|
|
GimpUIManager *dialog_ui_manager = NULL;
|
|
|
|
const gchar *dialog_ui_path = NULL;
|
|
|
|
gpointer dialog_popup_data = FALSE;
|
|
|
|
GtkWidget *parent_menu_widget = NULL;
|
|
|
|
GtkAction *parent_menu_action = NULL;
|
|
|
|
GimpDockable *dockable = NULL;
|
|
|
|
gint page_num = -1;
|
|
|
|
|
2010-06-13 00:45:02 +08:00
|
|
|
dockbook_ui_manager = gimp_dockbook_get_ui_manager (dockbook);
|
2010-05-27 00:10:31 +08:00
|
|
|
|
|
|
|
if (! dockbook_ui_manager)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
parent_menu_widget =
|
|
|
|
gtk_ui_manager_get_widget (GTK_UI_MANAGER (dockbook_ui_manager),
|
|
|
|
"/dockable-popup/dockable-menu");
|
|
|
|
parent_menu_action =
|
|
|
|
gtk_ui_manager_get_action (GTK_UI_MANAGER (dockbook_ui_manager),
|
|
|
|
"/dockable-popup/dockable-menu");
|
|
|
|
|
|
|
|
if (! parent_menu_widget || ! parent_menu_action)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook));
|
|
|
|
dockable = GIMP_DOCKABLE (gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook),
|
|
|
|
page_num));
|
|
|
|
|
2010-06-13 00:45:02 +08:00
|
|
|
if (! dockable)
|
2010-05-27 00:10:31 +08:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
dialog_ui_manager = gimp_dockable_get_menu (dockable,
|
|
|
|
&dialog_ui_path,
|
|
|
|
&dialog_popup_data);
|
|
|
|
|
|
|
|
if (dialog_ui_manager && dialog_ui_path)
|
|
|
|
{
|
2010-06-13 00:45:02 +08:00
|
|
|
GtkWidget *child_menu_widget;
|
|
|
|
GtkAction *child_menu_action;
|
|
|
|
gchar *label;
|
2010-05-27 00:10:31 +08:00
|
|
|
|
|
|
|
child_menu_widget =
|
|
|
|
gtk_ui_manager_get_widget (GTK_UI_MANAGER (dialog_ui_manager),
|
|
|
|
dialog_ui_path);
|
|
|
|
|
|
|
|
if (! child_menu_widget)
|
|
|
|
{
|
2016-10-29 05:09:44 +08:00
|
|
|
g_warning ("%s: UI manager '%s' has no widget at path '%s'",
|
2010-05-27 00:10:31 +08:00
|
|
|
G_STRFUNC, dialog_ui_manager->name, dialog_ui_path);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
child_menu_action =
|
|
|
|
gtk_ui_manager_get_action (GTK_UI_MANAGER (dialog_ui_manager),
|
|
|
|
dialog_ui_path);
|
|
|
|
|
|
|
|
if (! child_menu_action)
|
|
|
|
{
|
|
|
|
g_warning ("%s: UI manager '%s' has no action at path '%s'",
|
|
|
|
G_STRFUNC, dialog_ui_manager->name, dialog_ui_path);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_object_get (child_menu_action,
|
|
|
|
"label", &label,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
g_object_set (parent_menu_action,
|
2014-05-07 21:30:38 +08:00
|
|
|
"label", label,
|
|
|
|
"icon-name", gimp_dockable_get_icon_name (dockable),
|
|
|
|
"visible", TRUE,
|
2010-05-27 00:10:31 +08:00
|
|
|
NULL);
|
|
|
|
|
2010-06-13 00:45:02 +08:00
|
|
|
g_free (label);
|
|
|
|
|
2010-05-27 00:10:31 +08:00
|
|
|
if (! GTK_IS_MENU (child_menu_widget))
|
|
|
|
{
|
|
|
|
g_warning ("%s: child_menu_widget (%p) is not a GtkMenu",
|
|
|
|
G_STRFUNC, child_menu_widget);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget *image = gimp_dockable_get_icon (dockable,
|
|
|
|
GTK_ICON_SIZE_MENU);
|
|
|
|
|
|
|
|
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (parent_menu_widget),
|
|
|
|
image);
|
2016-10-29 05:09:44 +08:00
|
|
|
gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (parent_menu_widget),
|
|
|
|
TRUE);
|
2010-05-27 00:10:31 +08:00
|
|
|
gtk_widget_show (image);
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_menu_item_set_submenu (GTK_MENU_ITEM (parent_menu_widget),
|
|
|
|
child_menu_widget);
|
|
|
|
|
|
|
|
gimp_ui_manager_update (dialog_ui_manager, dialog_popup_data);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_object_set (parent_menu_action, "visible", FALSE, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* an action callback may destroy both dockable and dockbook, so
|
|
|
|
* reference them for gimp_dockbook_menu_end()
|
|
|
|
*/
|
|
|
|
g_object_ref (dockable);
|
|
|
|
g_object_set_data_full (G_OBJECT (dockable), GIMP_DOCKABLE_DETACH_REF_KEY,
|
|
|
|
g_object_ref (dockbook),
|
|
|
|
g_object_unref);
|
|
|
|
|
|
|
|
gimp_ui_manager_update (dockbook_ui_manager, dockable);
|
|
|
|
gimp_ui_manager_ui_popup (dockbook_ui_manager, "/dockable-popup",
|
|
|
|
GTK_WIDGET (dockable),
|
2010-06-12 17:38:15 +08:00
|
|
|
gimp_dockbook_menu_position, dockbook,
|
2010-05-27 00:10:31 +08:00
|
|
|
(GDestroyNotify) gimp_dockbook_menu_end, dockable);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_dockbook_menu_end (GimpDockable *dockable)
|
|
|
|
{
|
2010-06-13 00:45:02 +08:00
|
|
|
GimpUIManager *dialog_ui_manager;
|
|
|
|
const gchar *dialog_ui_path;
|
|
|
|
gpointer dialog_popup_data;
|
2010-05-27 00:10:31 +08:00
|
|
|
|
|
|
|
dialog_ui_manager = gimp_dockable_get_menu (dockable,
|
|
|
|
&dialog_ui_path,
|
|
|
|
&dialog_popup_data);
|
|
|
|
|
|
|
|
if (dialog_ui_manager && dialog_ui_path)
|
|
|
|
{
|
|
|
|
GtkWidget *child_menu_widget =
|
|
|
|
gtk_ui_manager_get_widget (GTK_UI_MANAGER (dialog_ui_manager),
|
|
|
|
dialog_ui_path);
|
|
|
|
|
|
|
|
if (child_menu_widget)
|
|
|
|
gtk_menu_detach (GTK_MENU (child_menu_widget));
|
|
|
|
}
|
|
|
|
|
2010-06-13 00:45:02 +08:00
|
|
|
/* release gimp_dockbook_show_menu()'s references */
|
2010-05-27 00:10:31 +08:00
|
|
|
g_object_set_data (G_OBJECT (dockable), GIMP_DOCKABLE_DETACH_REF_KEY, NULL);
|
|
|
|
g_object_unref (dockable);
|
|
|
|
}
|
|
|
|
|
2003-10-06 01:26:21 +08:00
|
|
|
static void
|
|
|
|
gimp_dockbook_dockable_added (GimpDockbook *dockbook,
|
|
|
|
GimpDockable *dockable)
|
|
|
|
{
|
2005-12-30 06:07:38 +08:00
|
|
|
gtk_notebook_set_current_page (GTK_NOTEBOOK (dockbook),
|
|
|
|
gtk_notebook_page_num (GTK_NOTEBOOK (dockbook),
|
|
|
|
GTK_WIDGET (dockable)));
|
2003-10-06 01:26:21 +08:00
|
|
|
}
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2003-10-06 01:26:21 +08:00
|
|
|
static void
|
|
|
|
gimp_dockbook_dockable_removed (GimpDockbook *dockbook,
|
|
|
|
GimpDockable *dockable)
|
|
|
|
{
|
|
|
|
}
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2010-06-12 05:18:49 +08:00
|
|
|
/**
|
|
|
|
* gimp_dockbook_get_dockable_tab_width:
|
|
|
|
* @dockable:
|
|
|
|
* @tab_style:
|
|
|
|
*
|
|
|
|
* Returns: Width of tab when the dockable is using the specified tab
|
|
|
|
* style.
|
|
|
|
**/
|
|
|
|
static gint
|
|
|
|
gimp_dockbook_get_dockable_tab_width (GimpDockbook *dockbook,
|
|
|
|
GimpDockable *dockable,
|
|
|
|
GimpTabStyle tab_style)
|
|
|
|
{
|
|
|
|
GtkRequisition dockable_request;
|
|
|
|
GtkWidget *tab_widget;
|
|
|
|
|
|
|
|
tab_widget =
|
|
|
|
gimp_dockable_create_event_box_tab_widget (dockable,
|
|
|
|
gimp_dock_get_context (dockbook->p->dock),
|
|
|
|
tab_style,
|
|
|
|
gimp_dockbook_get_tab_icon_size (dockbook));
|
|
|
|
|
|
|
|
/* So font-scale is applied. We can't apply styles without having a
|
|
|
|
* GdkScreen :(
|
|
|
|
*/
|
|
|
|
gimp_dock_temp_add (dockbook->p->dock, tab_widget);
|
|
|
|
|
|
|
|
gtk_widget_size_request (tab_widget, &dockable_request);
|
|
|
|
|
|
|
|
/* Also destroys the widget */
|
|
|
|
gimp_dock_temp_remove (dockbook->p->dock, tab_widget);
|
|
|
|
|
|
|
|
return dockable_request.width;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-09-11 00:22:12 +08:00
|
|
|
* gimp_dockbook_tab_style_to_preferred:
|
2010-06-12 05:18:49 +08:00
|
|
|
* @tab_style:
|
|
|
|
* @dockable:
|
|
|
|
*
|
|
|
|
* The list of tab styles to try in automatic mode only consists of
|
|
|
|
* preview styles. For some dockables, like the tool options dockable,
|
|
|
|
* we rather want to use the icon tab styles for the automatic
|
|
|
|
* mode. This function is used to convert tab styles for such
|
|
|
|
* dockables.
|
|
|
|
*
|
|
|
|
* Returns: An icon tab style if the dockable prefers icon tab styles
|
|
|
|
* in automatic mode.
|
|
|
|
**/
|
|
|
|
static GimpTabStyle
|
2012-09-11 00:22:12 +08:00
|
|
|
gimp_dockbook_tab_style_to_preferred (GimpTabStyle tab_style,
|
2010-06-12 05:18:49 +08:00
|
|
|
GimpDockable *dockable)
|
|
|
|
{
|
|
|
|
GimpDocked *docked = GIMP_DOCKED (gtk_bin_get_child (GTK_BIN (dockable)));
|
|
|
|
|
|
|
|
if (gimp_docked_get_prefer_icon (docked))
|
|
|
|
tab_style = gimp_preview_tab_style_to_icon (tab_style);
|
|
|
|
|
|
|
|
return tab_style;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_dockbook_refresh_tab_layout_lut:
|
|
|
|
* @dockbook:
|
|
|
|
*
|
|
|
|
* For each given set of tab widgets, there is a fixed mapping between
|
|
|
|
* the width of the dockbook and the actual tab style to use for auto
|
|
|
|
* tab widgets. This function refreshes that look-up table.
|
|
|
|
**/
|
|
|
|
static void
|
|
|
|
gimp_dockbook_refresh_tab_layout_lut (GimpDockbook *dockbook)
|
|
|
|
{
|
|
|
|
GList *auto_dockables = NULL;
|
|
|
|
GList *iter = NULL;
|
|
|
|
gint fixed_tab_style_space = 0;
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
/* Calculate space taken by dockables with fixed tab styles */
|
|
|
|
fixed_tab_style_space = 0;
|
|
|
|
for (iter = dockbook->p->dockables; iter; iter = g_list_next (iter))
|
|
|
|
{
|
|
|
|
GimpDockable *dockable = GIMP_DOCKABLE (iter->data);
|
|
|
|
GimpTabStyle tab_style = gimp_dockable_get_tab_style (dockable);
|
|
|
|
|
|
|
|
if (tab_style == GIMP_TAB_STYLE_AUTOMATIC)
|
|
|
|
auto_dockables = g_list_prepend (auto_dockables, dockable);
|
|
|
|
else
|
|
|
|
fixed_tab_style_space +=
|
|
|
|
gimp_dockbook_get_dockable_tab_width (dockbook,
|
|
|
|
dockable,
|
|
|
|
tab_style);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate space taken with auto tab style for all candidates */
|
2012-02-02 03:38:10 +08:00
|
|
|
for (i = 0; i < G_N_ELEMENTS (gimp_tab_style_candidates); i++)
|
2010-06-12 05:18:49 +08:00
|
|
|
{
|
|
|
|
gint size_with_candidate = 0;
|
|
|
|
GimpTabStyle candidate = gimp_tab_style_candidates[i];
|
|
|
|
|
|
|
|
for (iter = auto_dockables; iter; iter = g_list_next (iter))
|
|
|
|
{
|
|
|
|
GimpDockable *dockable = GIMP_DOCKABLE (iter->data);
|
|
|
|
GimpTabStyle style_to_use;
|
|
|
|
|
2012-09-11 00:22:12 +08:00
|
|
|
style_to_use = gimp_dockbook_tab_style_to_preferred (candidate,
|
2010-06-12 05:18:49 +08:00
|
|
|
dockable);
|
|
|
|
size_with_candidate +=
|
|
|
|
gimp_dockbook_get_dockable_tab_width (dockbook,
|
|
|
|
dockable,
|
|
|
|
style_to_use);
|
|
|
|
}
|
|
|
|
|
|
|
|
dockbook->p->min_width_for_style[i] =
|
|
|
|
fixed_tab_style_space + size_with_candidate;
|
|
|
|
|
|
|
|
GIMP_LOG (AUTO_TAB_STYLE, "Total tab space taken for auto tab style %s = %d",
|
|
|
|
gimp_dockbook_get_tab_style_name (candidate),
|
|
|
|
dockbook->p->min_width_for_style[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_list_free (auto_dockables);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_dockbook_update_automatic_tab_style:
|
|
|
|
* @dockbook:
|
|
|
|
*
|
|
|
|
* Based on widget allocation, sets actual tab style for dockables
|
|
|
|
* with automatic tab styles. Takes care of recreating tab widgets if
|
|
|
|
* necessary.
|
|
|
|
**/
|
|
|
|
static void
|
|
|
|
gimp_dockbook_update_automatic_tab_style (GimpDockbook *dockbook)
|
|
|
|
{
|
|
|
|
GtkWidget *widget = GTK_WIDGET (dockbook);
|
|
|
|
gboolean changed = FALSE;
|
|
|
|
GList *iter = NULL;
|
|
|
|
GtkAllocation dockbook_allocation = { 0, };
|
|
|
|
GtkAllocation button_allocation = { 0, };
|
|
|
|
GimpTabStyle tab_style = 0;
|
|
|
|
int i = 0;
|
|
|
|
gint available_space = 0;
|
|
|
|
guint tab_hborder = 0;
|
|
|
|
gint xthickness = 0;
|
|
|
|
gint tab_curvature = 0;
|
|
|
|
gint focus_width = 0;
|
|
|
|
gint tab_overlap = 0;
|
|
|
|
gint tab_padding = 0;
|
|
|
|
gint border_loss = 0;
|
|
|
|
gint action_widget_size = 0;
|
|
|
|
|
|
|
|
xthickness = gtk_widget_get_style (widget)->xthickness;
|
|
|
|
g_object_get (widget,
|
|
|
|
"tab-hborder", &tab_hborder,
|
|
|
|
NULL);
|
|
|
|
gtk_widget_style_get (widget,
|
|
|
|
"tab-curvature", &tab_curvature,
|
|
|
|
"focus-line-width", &focus_width,
|
|
|
|
"tab-overlap", &tab_overlap,
|
|
|
|
NULL);
|
|
|
|
gtk_widget_get_allocation (dockbook->p->menu_button,
|
|
|
|
&button_allocation);
|
|
|
|
|
|
|
|
/* Calculate available space. Based on code in GTK+ internal
|
|
|
|
* functions gtk_notebook_size_request() and
|
|
|
|
* gtk_notebook_pages_allocate()
|
|
|
|
*/
|
|
|
|
gtk_widget_get_allocation (widget, &dockbook_allocation);
|
|
|
|
|
|
|
|
/* Border on both sides */
|
|
|
|
border_loss = gtk_container_get_border_width (GTK_CONTAINER (dockbook)) * 2;
|
|
|
|
|
|
|
|
/* Space taken by action widget */
|
|
|
|
action_widget_size = button_allocation.width + xthickness;
|
|
|
|
|
|
|
|
/* Space taken by the tabs but not the tab widgets themselves */
|
|
|
|
tab_padding = gtk_notebook_get_n_pages (GTK_NOTEBOOK (dockbook)) *
|
|
|
|
(2 * (xthickness + tab_curvature + focus_width + tab_hborder) -
|
|
|
|
tab_overlap);
|
|
|
|
|
|
|
|
available_space = dockbook_allocation.width
|
|
|
|
- border_loss
|
|
|
|
- action_widget_size
|
|
|
|
- tab_padding
|
|
|
|
- tab_overlap;
|
|
|
|
|
|
|
|
GIMP_LOG (AUTO_TAB_STYLE, "\n"
|
|
|
|
" available_space = %d where\n"
|
|
|
|
" dockbook_allocation.width = %d\n"
|
|
|
|
" border_loss = %d\n"
|
|
|
|
" action_widget_size = %d\n"
|
|
|
|
" tab_padding = %d\n"
|
|
|
|
" tab_overlap = %d\n",
|
|
|
|
available_space,
|
|
|
|
dockbook_allocation.width,
|
|
|
|
border_loss,
|
|
|
|
action_widget_size,
|
|
|
|
tab_padding,
|
|
|
|
tab_overlap);
|
|
|
|
|
|
|
|
/* Try all candidates, if we don't get any hit we still end up on
|
|
|
|
* the smallest style (which we always fall back to if we don't get
|
|
|
|
* a better match)
|
|
|
|
*/
|
2012-02-02 03:38:10 +08:00
|
|
|
for (i = 0; i < G_N_ELEMENTS (gimp_tab_style_candidates); i++)
|
2010-06-12 05:18:49 +08:00
|
|
|
{
|
|
|
|
tab_style = gimp_tab_style_candidates[i];
|
|
|
|
if (available_space > dockbook->p->min_width_for_style[i])
|
|
|
|
{
|
|
|
|
GIMP_LOG (AUTO_TAB_STYLE, "Choosing tab style %s",
|
|
|
|
gimp_dockbook_get_tab_style_name (tab_style));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (iter = dockbook->p->dockables; iter; iter = g_list_next (iter))
|
|
|
|
{
|
|
|
|
GimpDockable *dockable = GIMP_DOCKABLE (iter->data);
|
|
|
|
GimpTabStyle actual_tab_style = tab_style;
|
|
|
|
|
|
|
|
if (gimp_dockable_get_tab_style (dockable) != GIMP_TAB_STYLE_AUTOMATIC)
|
|
|
|
continue;
|
|
|
|
|
2012-09-11 00:22:12 +08:00
|
|
|
actual_tab_style = gimp_dockbook_tab_style_to_preferred (tab_style,
|
2010-06-12 05:18:49 +08:00
|
|
|
dockable);
|
|
|
|
|
|
|
|
if (gimp_dockable_set_actual_tab_style (dockable, actual_tab_style))
|
|
|
|
changed = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (changed)
|
|
|
|
gimp_dockbook_recreate_tab_widgets (dockbook,
|
|
|
|
TRUE /*only_auto*/);
|
|
|
|
}
|
|
|
|
|
2003-10-06 01:26:21 +08:00
|
|
|
GtkWidget *
|
|
|
|
gimp_dockbook_new (GimpMenuFactory *menu_factory)
|
|
|
|
{
|
|
|
|
GimpDockbook *dockbook;
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2003-10-06 01:26:21 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_MENU_FACTORY (menu_factory), NULL);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2003-10-06 01:26:21 +08:00
|
|
|
dockbook = g_object_new (GIMP_TYPE_DOCKBOOK, NULL);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2009-09-13 22:30:09 +08:00
|
|
|
dockbook->p->ui_manager = gimp_menu_factory_manager_new (menu_factory,
|
2016-11-23 14:01:41 +08:00
|
|
|
"<Dockable>",
|
|
|
|
dockbook,
|
|
|
|
FALSE);
|
2004-04-23 01:14:22 +08:00
|
|
|
|
2003-10-06 01:26:21 +08:00
|
|
|
gimp_help_connect (GTK_WIDGET (dockbook), gimp_dockbook_help_func,
|
|
|
|
GIMP_HELP_DOCK, dockbook);
|
|
|
|
|
|
|
|
return GTK_WIDGET (dockbook);
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
|
|
|
|
2009-09-13 22:30:09 +08:00
|
|
|
GimpDock *
|
|
|
|
gimp_dockbook_get_dock (GimpDockbook *dockbook)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DOCKBOOK (dockbook), NULL);
|
|
|
|
|
|
|
|
return dockbook->p->dock;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dockbook_set_dock (GimpDockbook *dockbook,
|
|
|
|
GimpDock *dock)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_DOCKBOOK (dockbook));
|
|
|
|
g_return_if_fail (dock == NULL || GIMP_IS_DOCK (dock));
|
|
|
|
|
2017-03-13 01:36:16 +08:00
|
|
|
if (dockbook->p->dock && gimp_dock_get_context (dockbook->p->dock))
|
|
|
|
g_signal_handlers_disconnect_by_func (gimp_dock_get_context (dockbook->p->dock)->gimp->config,
|
2017-03-17 12:52:20 +08:00
|
|
|
G_CALLBACK (gimp_dockbook_config_size_changed),
|
2017-03-13 01:36:16 +08:00
|
|
|
dockbook);
|
2009-09-13 22:30:09 +08:00
|
|
|
dockbook->p->dock = dock;
|
2017-03-13 01:36:16 +08:00
|
|
|
if (dock)
|
|
|
|
g_signal_connect (gimp_dock_get_context (dockbook->p->dock)->gimp->config,
|
2017-03-17 12:52:20 +08:00
|
|
|
"size-changed",
|
|
|
|
G_CALLBACK (gimp_dockbook_config_size_changed),
|
2017-03-13 01:36:16 +08:00
|
|
|
dockbook);
|
2009-09-13 22:30:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
GimpUIManager *
|
|
|
|
gimp_dockbook_get_ui_manager (GimpDockbook *dockbook)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DOCKBOOK (dockbook), NULL);
|
|
|
|
|
|
|
|
return dockbook->p->ui_manager;
|
|
|
|
}
|
|
|
|
|
2001-04-11 00:03:40 +08:00
|
|
|
void
|
|
|
|
gimp_dockbook_add (GimpDockbook *dockbook,
|
2004-08-25 01:16:46 +08:00
|
|
|
GimpDockable *dockable,
|
|
|
|
gint position)
|
2001-04-11 00:03:40 +08:00
|
|
|
{
|
|
|
|
GtkWidget *tab_widget;
|
|
|
|
GtkWidget *menu_widget;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_DOCKBOOK (dockbook));
|
2009-09-13 22:30:09 +08:00
|
|
|
g_return_if_fail (dockbook->p->dock != NULL);
|
2001-04-11 00:03:40 +08:00
|
|
|
g_return_if_fail (GIMP_IS_DOCKABLE (dockable));
|
2010-01-05 07:30:10 +08:00
|
|
|
g_return_if_fail (gimp_dockable_get_dockbook (dockable) == NULL);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
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
|
|
|
GIMP_LOG (DND, "Adding GimpDockable %p to GimpDockbook %p", dockable, dockbook);
|
|
|
|
|
2010-06-12 05:18:49 +08:00
|
|
|
/* Add to internal list before doing automatic tab style
|
|
|
|
* calculations
|
|
|
|
*/
|
|
|
|
dockbook->p->dockables = g_list_insert (dockbook->p->dockables,
|
|
|
|
dockable,
|
|
|
|
position);
|
|
|
|
|
2016-01-09 03:49:33 +08:00
|
|
|
gimp_dockbook_update_auto_tab_style (dockbook);
|
2010-06-12 05:18:49 +08:00
|
|
|
|
|
|
|
/* Create the new tab widget, it will get the correct tab style now */
|
2008-05-20 05:11:03 +08:00
|
|
|
tab_widget = gimp_dockbook_create_tab_widget (dockbook, dockable);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
2001-07-24 Michael Natterer <mitch@gimp.org>
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
* configure.in: require glib/gtk+ >= 1.3.7, commented out the
gtkxmhtml stuff.
From now on, you will need glib, pango, atk and gtk+ HEAD from CVS
to hack or use GIMP HEAD.
Beware, it crashes randomly :)
* app/core/Makefile.am
* app/core/gimpmarshal.list: new file plus rules to generate
gimpmarshal.[ch] from it.
* app/core/*
* app/tools/*
* app/widgets/*
* libgimpwidgets/*: started to use the glib object system. All
core/ objects are still gtk objects however. All signals are
created using g_signal_new(). There are many gtk+ artefacts left.
Finally, we will _not_ use the gtk_signal_foo() wrappers and
friends any more.
* app/colormaps.c
* app/devices.[ch]
* app/disp_callbacks.c
* app/errorconsole.c
* app/file-save.[ch]
* app/interface.c
* app/module_db.c
* app/nav_window.c
* app/ops_buttons.c
* app/scroll.c
* app/user_install.c
* app/gui/about-dialog.c
* app/gui/brush-editor.c
* app/gui/brushes-commands.c
* app/gui/color-notebook.c
* app/gui/colormap-dialog.c
* app/gui/dialogs-commands.c
* app/gui/dialogs-constructors.c
* app/gui/file-commands.c
* app/gui/file-dialog-utils.c
* app/gui/file-new-dialog.c
* app/gui/file-open-dialog.[ch]
* app/gui/file-save-dialog.c
* app/gui/gradient-editor.c
* app/gui/gradients-commands.c
* app/gui/image-commands.c
* app/gui/info-dialog.[ch]
* app/gui/layer-select.c
* app/gui/layers-commands.c
* app/gui/menus.c
* app/gui/offset-dialog.c
* app/gui/palette-editor.c
* app/gui/palettes-commands.c
* app/gui/patterns-commands.c
* app/gui/preferences-dialog.c
* app/gui/resize-dialog.[ch]
* app/gui/splash.c
* app/gui/tips-dialog.c
* app/gui/tool-options-dialog.c
* app/gui/toolbox.c
* app/gui/tools-commands.c
* libgimp/gimpbrushmenu.c
* libgimp/gimpmenu.c
* libgimp/gimppatternmenu.c
* libgimp/gimpui.c
* libgimpbase/gimpenv.c: tons and tons of changes like "const
gchar*", switch from GdkDeviceInfo to GdkDevice (very incomplete
and currently disables), lots of s/gtk_signal/g_signal/,
removal/replacement of deprecated stuff,
s/GtkSignalFunc/GCallback/ and lots of small changes and fixes
while I was on it, zillions of warnings left...
* modules/Makefile.am: disabled the water color selector
temporarily (XInput issues).
* plug-ins/Makefile.am
* plug-ins/common/.cvsignore
* plug-ins/common/Makefile.am
* plug-ins/common/plugin-defs.pl: simply excluded all plug-ins
which did not build (including Script-Fu). They are trivial to
fix.
2001-07-25 05:27:11 +08:00
|
|
|
g_return_if_fail (GTK_IS_WIDGET (tab_widget));
|
|
|
|
|
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
|
|
|
gimp_dockable_set_drag_handler (dockable, dockbook->p->drag_handler);
|
|
|
|
|
2010-04-18 23:42:26 +08:00
|
|
|
/* For the notebook right-click menu, always use the icon style */
|
|
|
|
menu_widget =
|
2010-04-19 10:32:18 +08:00
|
|
|
gimp_dockable_create_tab_widget (dockable,
|
|
|
|
gimp_dock_get_context (dockbook->p->dock),
|
|
|
|
GIMP_TAB_STYLE_ICON_BLURB,
|
|
|
|
MENU_WIDGET_ICON_SIZE);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
2001-07-24 Michael Natterer <mitch@gimp.org>
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
* configure.in: require glib/gtk+ >= 1.3.7, commented out the
gtkxmhtml stuff.
From now on, you will need glib, pango, atk and gtk+ HEAD from CVS
to hack or use GIMP HEAD.
Beware, it crashes randomly :)
* app/core/Makefile.am
* app/core/gimpmarshal.list: new file plus rules to generate
gimpmarshal.[ch] from it.
* app/core/*
* app/tools/*
* app/widgets/*
* libgimpwidgets/*: started to use the glib object system. All
core/ objects are still gtk objects however. All signals are
created using g_signal_new(). There are many gtk+ artefacts left.
Finally, we will _not_ use the gtk_signal_foo() wrappers and
friends any more.
* app/colormaps.c
* app/devices.[ch]
* app/disp_callbacks.c
* app/errorconsole.c
* app/file-save.[ch]
* app/interface.c
* app/module_db.c
* app/nav_window.c
* app/ops_buttons.c
* app/scroll.c
* app/user_install.c
* app/gui/about-dialog.c
* app/gui/brush-editor.c
* app/gui/brushes-commands.c
* app/gui/color-notebook.c
* app/gui/colormap-dialog.c
* app/gui/dialogs-commands.c
* app/gui/dialogs-constructors.c
* app/gui/file-commands.c
* app/gui/file-dialog-utils.c
* app/gui/file-new-dialog.c
* app/gui/file-open-dialog.[ch]
* app/gui/file-save-dialog.c
* app/gui/gradient-editor.c
* app/gui/gradients-commands.c
* app/gui/image-commands.c
* app/gui/info-dialog.[ch]
* app/gui/layer-select.c
* app/gui/layers-commands.c
* app/gui/menus.c
* app/gui/offset-dialog.c
* app/gui/palette-editor.c
* app/gui/palettes-commands.c
* app/gui/patterns-commands.c
* app/gui/preferences-dialog.c
* app/gui/resize-dialog.[ch]
* app/gui/splash.c
* app/gui/tips-dialog.c
* app/gui/tool-options-dialog.c
* app/gui/toolbox.c
* app/gui/tools-commands.c
* libgimp/gimpbrushmenu.c
* libgimp/gimpmenu.c
* libgimp/gimppatternmenu.c
* libgimp/gimpui.c
* libgimpbase/gimpenv.c: tons and tons of changes like "const
gchar*", switch from GdkDeviceInfo to GdkDevice (very incomplete
and currently disables), lots of s/gtk_signal/g_signal/,
removal/replacement of deprecated stuff,
s/GtkSignalFunc/GCallback/ and lots of small changes and fixes
while I was on it, zillions of warnings left...
* modules/Makefile.am: disabled the water color selector
temporarily (XInput issues).
* plug-ins/Makefile.am
* plug-ins/common/.cvsignore
* plug-ins/common/Makefile.am
* plug-ins/common/plugin-defs.pl: simply excluded all plug-ins
which did not build (including Script-Fu). They are trivial to
fix.
2001-07-25 05:27:11 +08:00
|
|
|
g_return_if_fail (GTK_IS_WIDGET (menu_widget));
|
|
|
|
|
2001-04-11 00:03:40 +08:00
|
|
|
if (position == -1)
|
|
|
|
{
|
|
|
|
gtk_notebook_append_page_menu (GTK_NOTEBOOK (dockbook),
|
2004-08-25 01:16:46 +08:00
|
|
|
GTK_WIDGET (dockable),
|
|
|
|
tab_widget,
|
|
|
|
menu_widget);
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_notebook_insert_page_menu (GTK_NOTEBOOK (dockbook),
|
2004-08-25 01:16:46 +08:00
|
|
|
GTK_WIDGET (dockable),
|
|
|
|
tab_widget,
|
|
|
|
menu_widget,
|
|
|
|
position);
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
gtk_widget_show (GTK_WIDGET (dockable));
|
|
|
|
|
2010-01-05 07:30:10 +08:00
|
|
|
gimp_dockable_set_dockbook (dockable, dockbook);
|
2001-04-24 00:58:18 +08:00
|
|
|
|
2009-09-13 22:30:09 +08:00
|
|
|
gimp_dockable_set_context (dockable, gimp_dock_get_context (dockbook->p->dock));
|
2003-05-03 19:59:44 +08:00
|
|
|
|
2008-05-20 05:11:03 +08:00
|
|
|
g_signal_connect (dockable, "notify::locked",
|
|
|
|
G_CALLBACK (gimp_dockbook_tab_locked_notify),
|
|
|
|
dockbook);
|
|
|
|
|
2003-05-03 19:59:44 +08:00
|
|
|
g_signal_emit (dockbook, dockbook_signals[DOCKABLE_ADDED], 0, dockable);
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
|
|
|
|
2011-07-03 22:36:38 +08:00
|
|
|
/**
|
|
|
|
* gimp_dockbook_add_from_dialog_factory:
|
|
|
|
* @dockbook: The #DockBook
|
|
|
|
* @identifiers: The dockable identifier(s)
|
|
|
|
* @position: The insert position
|
|
|
|
*
|
|
|
|
* Add a dockable from the dialog factory associated wth the dockbook.
|
|
|
|
**/
|
|
|
|
GtkWidget *
|
|
|
|
gimp_dockbook_add_from_dialog_factory (GimpDockbook *dockbook,
|
|
|
|
const gchar *identifiers,
|
|
|
|
gint position)
|
|
|
|
{
|
|
|
|
GtkWidget *dockable;
|
|
|
|
GimpDock *dock;
|
|
|
|
gchar *identifier;
|
|
|
|
gchar *p;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GIMP_IS_DOCKBOOK (dockbook), NULL);
|
|
|
|
g_return_val_if_fail (identifiers != NULL, NULL);
|
|
|
|
|
|
|
|
identifier = g_strdup (identifiers);
|
|
|
|
|
|
|
|
p = strchr (identifier, '|');
|
|
|
|
|
|
|
|
if (p)
|
|
|
|
*p = '\0';
|
|
|
|
|
|
|
|
dock = gimp_dockbook_get_dock (dockbook);
|
|
|
|
dockable = gimp_dialog_factory_dockable_new (gimp_dock_get_dialog_factory (dock),
|
|
|
|
dock,
|
|
|
|
identifier, -1);
|
|
|
|
|
|
|
|
g_free (identifier);
|
|
|
|
|
|
|
|
/* Maybe gimp_dialog_factory_dockable_new() returned an already
|
|
|
|
* existing singleton dockable, so check if it already is
|
|
|
|
* attached to a dockbook.
|
|
|
|
*/
|
|
|
|
if (dockable && ! gimp_dockable_get_dockbook (GIMP_DOCKABLE (dockable)))
|
|
|
|
gimp_dockbook_add (dockbook, GIMP_DOCKABLE (dockable), position);
|
|
|
|
|
|
|
|
return dockable;
|
|
|
|
}
|
|
|
|
|
2001-04-11 00:03:40 +08:00
|
|
|
void
|
|
|
|
gimp_dockbook_remove (GimpDockbook *dockbook,
|
2004-08-25 01:16:46 +08:00
|
|
|
GimpDockable *dockable)
|
2001-04-11 00:03:40 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_DOCKBOOK (dockbook));
|
|
|
|
g_return_if_fail (GIMP_IS_DOCKABLE (dockable));
|
2010-01-05 07:30:10 +08:00
|
|
|
g_return_if_fail (gimp_dockable_get_dockbook (dockable) == dockbook);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
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
|
|
|
GIMP_LOG (DND, "Removing GimpDockable %p from GimpDockbook %p", dockable, dockbook);
|
|
|
|
|
|
|
|
gimp_dockable_set_drag_handler (dockable, NULL);
|
|
|
|
|
2003-05-03 19:59:44 +08:00
|
|
|
g_object_ref (dockable);
|
|
|
|
|
2008-05-20 05:11:03 +08:00
|
|
|
g_signal_handlers_disconnect_by_func (dockable,
|
|
|
|
G_CALLBACK (gimp_dockbook_tab_locked_notify),
|
|
|
|
dockbook);
|
|
|
|
|
2009-09-13 22:30:09 +08:00
|
|
|
if (dockbook->p->tab_hover_dockable == dockable)
|
2007-09-17 23:40:01 +08:00
|
|
|
gimp_dockbook_remove_tab_timeout (dockbook);
|
|
|
|
|
2010-01-05 07:30:10 +08:00
|
|
|
gimp_dockable_set_dockbook (dockable, NULL);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2001-05-07 00:14:34 +08:00
|
|
|
gimp_dockable_set_context (dockable, NULL);
|
|
|
|
|
2001-04-11 00:03:40 +08:00
|
|
|
gtk_container_remove (GTK_CONTAINER (dockbook), GTK_WIDGET (dockable));
|
2010-06-12 05:18:49 +08:00
|
|
|
dockbook->p->dockables = g_list_remove (dockbook->p->dockables,
|
|
|
|
dockable);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2003-05-03 19:59:44 +08:00
|
|
|
g_signal_emit (dockbook, dockbook_signals[DOCKABLE_REMOVED], 0, dockable);
|
|
|
|
|
|
|
|
g_object_unref (dockable);
|
|
|
|
|
2010-06-27 05:23:50 +08:00
|
|
|
if (dockbook->p->dock)
|
|
|
|
{
|
|
|
|
GList *children = gtk_container_get_children (GTK_CONTAINER (dockbook));
|
2001-09-03 21:03:34 +08:00
|
|
|
|
2010-06-27 05:23:50 +08:00
|
|
|
if (children)
|
|
|
|
gimp_dockbook_update_auto_tab_style (dockbook);
|
|
|
|
else
|
|
|
|
gimp_dock_remove_book (dockbook->p->dock, dockbook);
|
2001-09-03 21:03:34 +08:00
|
|
|
|
2010-06-27 05:23:50 +08:00
|
|
|
g_list_free (children);
|
|
|
|
}
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
|
|
|
|
2010-01-06 20:33:47 +08:00
|
|
|
/**
|
|
|
|
* gimp_dockbook_update_with_context:
|
|
|
|
* @dockbook:
|
|
|
|
* @context:
|
|
|
|
*
|
|
|
|
* Set @context on all dockables in @dockbook.
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_dockbook_update_with_context (GimpDockbook *dockbook,
|
|
|
|
GimpContext *context)
|
|
|
|
{
|
|
|
|
GList *children = gtk_container_get_children (GTK_CONTAINER (dockbook));
|
|
|
|
GList *iter = NULL;
|
|
|
|
|
|
|
|
for (iter = children;
|
|
|
|
iter;
|
|
|
|
iter = g_list_next (iter))
|
|
|
|
{
|
|
|
|
GimpDockable *dockable = GIMP_DOCKABLE (iter->data);
|
|
|
|
|
|
|
|
gimp_dockable_set_context (dockable, context);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_list_free (children);
|
|
|
|
}
|
|
|
|
|
2003-07-08 23:07:56 +08:00
|
|
|
GtkWidget *
|
2008-05-20 05:11:03 +08:00
|
|
|
gimp_dockbook_create_tab_widget (GimpDockbook *dockbook,
|
|
|
|
GimpDockable *dockable)
|
2002-03-20 20:57:59 +08:00
|
|
|
{
|
2009-09-15 13:58:14 +08:00
|
|
|
GtkWidget *tab_widget;
|
|
|
|
GimpDockWindow *dock_window;
|
2010-05-23 18:36:24 +08:00
|
|
|
GtkAction *action = NULL;
|
2002-03-20 20:57:59 +08:00
|
|
|
|
2010-04-18 23:42:26 +08:00
|
|
|
tab_widget =
|
2010-06-11 13:35:07 +08:00
|
|
|
gimp_dockable_create_event_box_tab_widget (dockable,
|
|
|
|
gimp_dock_get_context (dockbook->p->dock),
|
2010-06-12 05:18:49 +08:00
|
|
|
gimp_dockable_get_actual_tab_style (dockable),
|
2010-06-11 13:35:07 +08:00
|
|
|
gimp_dockbook_get_tab_icon_size (dockbook));
|
2002-03-20 20:57:59 +08:00
|
|
|
|
2005-10-31 02:41:18 +08:00
|
|
|
/* EEK */
|
2009-09-15 13:58:14 +08:00
|
|
|
dock_window = gimp_dock_window_from_dock (dockbook->p->dock);
|
2011-05-14 00:56:03 +08:00
|
|
|
if (dock_window &&
|
|
|
|
gimp_dock_container_get_ui_manager (GIMP_DOCK_CONTAINER (dock_window)))
|
2005-10-31 02:41:18 +08:00
|
|
|
{
|
|
|
|
const gchar *dialog_id;
|
|
|
|
|
|
|
|
dialog_id = g_object_get_data (G_OBJECT (dockable),
|
|
|
|
"gimp-dialog-identifier");
|
|
|
|
|
|
|
|
if (dialog_id)
|
|
|
|
{
|
2011-05-14 00:56:03 +08:00
|
|
|
GimpDockContainer *dock_container;
|
|
|
|
GimpActionGroup *group;
|
|
|
|
|
|
|
|
dock_container = GIMP_DOCK_CONTAINER (dock_window);
|
2005-10-31 02:41:18 +08:00
|
|
|
|
|
|
|
group = gimp_ui_manager_get_action_group
|
2011-05-14 00:56:03 +08:00
|
|
|
(gimp_dock_container_get_ui_manager (dock_container), "dialogs");
|
2005-10-31 02:41:18 +08:00
|
|
|
|
|
|
|
if (group)
|
|
|
|
{
|
|
|
|
GList *actions;
|
|
|
|
GList *list;
|
|
|
|
|
|
|
|
actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group));
|
|
|
|
|
|
|
|
for (list = actions; list; list = g_list_next (list))
|
|
|
|
{
|
|
|
|
if (GIMP_IS_STRING_ACTION (list->data) &&
|
|
|
|
strstr (GIMP_STRING_ACTION (list->data)->value,
|
|
|
|
dialog_id))
|
|
|
|
{
|
|
|
|
action = list->data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_list_free (actions);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (action)
|
|
|
|
gimp_widget_set_accel_help (tab_widget, action);
|
|
|
|
else
|
2010-01-05 07:30:10 +08:00
|
|
|
gimp_help_set_help_data (tab_widget,
|
|
|
|
gimp_dockable_get_blurb (dockable),
|
|
|
|
gimp_dockable_get_help_id (dockable));
|
2002-03-20 20:57:59 +08:00
|
|
|
|
|
|
|
g_object_set_data (G_OBJECT (tab_widget), "gimp-dockable", dockable);
|
|
|
|
|
2008-05-20 05:11:03 +08:00
|
|
|
gimp_dockbook_tab_drag_source_setup (tab_widget, dockable);
|
|
|
|
|
2010-01-05 17:26:07 +08:00
|
|
|
g_signal_connect_object (tab_widget, "drag-begin",
|
|
|
|
G_CALLBACK (gimp_dockbook_tab_drag_begin),
|
|
|
|
dockable, 0);
|
|
|
|
g_signal_connect_object (tab_widget, "drag-end",
|
|
|
|
G_CALLBACK (gimp_dockbook_tab_drag_end),
|
|
|
|
dockable, 0);
|
|
|
|
|
|
|
|
g_signal_connect_object (dockable, "drag-begin",
|
|
|
|
G_CALLBACK (gimp_dockbook_tab_drag_begin),
|
|
|
|
dockable, 0);
|
|
|
|
g_signal_connect_object (dockable, "drag-end",
|
|
|
|
G_CALLBACK (gimp_dockbook_tab_drag_end),
|
|
|
|
dockable, 0);
|
2003-10-06 01:26:21 +08:00
|
|
|
|
2008-05-20 05:11:03 +08:00
|
|
|
gtk_drag_dest_set (tab_widget,
|
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
|
|
|
0,
|
2002-03-20 20:57:59 +08:00
|
|
|
dialog_target_table, G_N_ELEMENTS (dialog_target_table),
|
|
|
|
GDK_ACTION_MOVE);
|
2010-01-05 17:26:07 +08:00
|
|
|
g_signal_connect_object (tab_widget, "drag-leave",
|
|
|
|
G_CALLBACK (gimp_dockbook_tab_drag_leave),
|
|
|
|
dockable, 0);
|
|
|
|
g_signal_connect_object (tab_widget, "drag-motion",
|
|
|
|
G_CALLBACK (gimp_dockbook_tab_drag_motion),
|
|
|
|
dockable, 0);
|
|
|
|
g_signal_connect_object (tab_widget, "drag-drop",
|
|
|
|
G_CALLBACK (gimp_dockbook_tab_drag_drop),
|
|
|
|
dockbook, 0);
|
2002-03-20 20:57:59 +08:00
|
|
|
|
|
|
|
return tab_widget;
|
|
|
|
}
|
|
|
|
|
2010-06-12 05:18:49 +08:00
|
|
|
/**
|
|
|
|
* gimp_dockbook_update_auto_tab_style:
|
|
|
|
* @dockbook:
|
|
|
|
*
|
|
|
|
* Refresh the table that we use to map dockbook width to actual auto
|
|
|
|
* tab style, then update auto tabs (also recreate tab widgets if
|
|
|
|
* necessary).
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_dockbook_update_auto_tab_style (GimpDockbook *dockbook)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_DOCKBOOK (dockbook));
|
|
|
|
|
|
|
|
gimp_dockbook_refresh_tab_layout_lut (dockbook);
|
|
|
|
gimp_dockbook_update_automatic_tab_style (dockbook);
|
|
|
|
}
|
|
|
|
|
2003-10-06 01:26:21 +08:00
|
|
|
gboolean
|
|
|
|
gimp_dockbook_drop_dockable (GimpDockbook *dockbook,
|
|
|
|
GtkWidget *drag_source)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DOCKBOOK (dockbook), FALSE);
|
|
|
|
|
|
|
|
if (drag_source)
|
|
|
|
{
|
2009-10-26 06:02:05 +08:00
|
|
|
GimpDockable *dockable =
|
|
|
|
gimp_dockbook_drag_source_to_dockable (drag_source);
|
2003-10-06 01:26:21 +08:00
|
|
|
|
|
|
|
if (dockable)
|
|
|
|
{
|
2010-01-05 07:30:10 +08:00
|
|
|
if (gimp_dockable_get_dockbook (dockable) == dockbook)
|
2006-04-12 20:49:29 +08:00
|
|
|
{
|
|
|
|
gtk_notebook_reorder_child (GTK_NOTEBOOK (dockbook),
|
2006-03-29 03:19:55 +08:00
|
|
|
GTK_WIDGET (dockable), -1);
|
2006-04-12 20:49:29 +08:00
|
|
|
}
|
|
|
|
else
|
2003-10-06 01:26:21 +08:00
|
|
|
{
|
|
|
|
g_object_ref (dockable);
|
|
|
|
|
2010-01-05 07:30:10 +08:00
|
|
|
gimp_dockbook_remove (gimp_dockable_get_dockbook (dockable), dockable);
|
2003-10-06 01:26:21 +08:00
|
|
|
gimp_dockbook_add (dockbook, dockable, -1);
|
|
|
|
|
|
|
|
g_object_unref (dockable);
|
|
|
|
}
|
2006-03-29 03:19:55 +08:00
|
|
|
|
2006-04-12 20:49:29 +08:00
|
|
|
return TRUE;
|
2003-10-06 01:26:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
/**
|
|
|
|
* gimp_dockable_set_drag_handler:
|
|
|
|
* @dockable:
|
|
|
|
* @handler:
|
|
|
|
*
|
|
|
|
* Set a drag handler that will be asked if it will handle drag events
|
|
|
|
* before the dockbook handles the event itself.
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
gimp_dockbook_set_drag_handler (GimpDockbook *dockbook,
|
|
|
|
GimpPanedBox *drag_handler)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_DOCKBOOK (dockbook));
|
|
|
|
|
|
|
|
dockbook->p->drag_handler = drag_handler;
|
|
|
|
}
|
|
|
|
|
2009-10-26 06:02:05 +08:00
|
|
|
/**
|
|
|
|
* gimp_dockbook_drag_source_to_dockable:
|
|
|
|
* @drag_source: A drag-and-drop source widget
|
|
|
|
*
|
|
|
|
* Gets the dockable associated with a drag-and-drop source. If
|
2013-01-27 23:52:38 +08:00
|
|
|
* successful, the function will also cleanup the dockable.
|
2009-10-26 06:02:05 +08:00
|
|
|
*
|
|
|
|
* Returns: The dockable
|
|
|
|
**/
|
|
|
|
GimpDockable *
|
|
|
|
gimp_dockbook_drag_source_to_dockable (GtkWidget *drag_source)
|
|
|
|
{
|
|
|
|
GimpDockable *dockable = NULL;
|
|
|
|
|
|
|
|
if (GIMP_IS_DOCKABLE (drag_source))
|
|
|
|
dockable = GIMP_DOCKABLE (drag_source);
|
|
|
|
else
|
|
|
|
dockable = g_object_get_data (G_OBJECT (drag_source),
|
|
|
|
"gimp-dockable");
|
|
|
|
if (dockable)
|
|
|
|
g_object_set_data (G_OBJECT (dockable),
|
|
|
|
"gimp-dock-drag-widget", NULL);
|
|
|
|
|
|
|
|
return dockable;
|
|
|
|
}
|
2007-09-17 23:40:01 +08:00
|
|
|
|
|
|
|
/* tab DND source side */
|
|
|
|
|
2010-05-23 01:31:27 +08:00
|
|
|
static void
|
2010-06-12 05:18:49 +08:00
|
|
|
gimp_dockbook_recreate_tab_widgets (GimpDockbook *dockbook,
|
|
|
|
gboolean only_auto)
|
2010-05-23 01:31:27 +08:00
|
|
|
{
|
|
|
|
GList *dockables = gtk_container_get_children (GTK_CONTAINER (dockbook));
|
|
|
|
GList *iter = NULL;
|
|
|
|
|
2017-03-11 09:42:10 +08:00
|
|
|
g_object_set (dockbook,
|
|
|
|
"tab-border", gimp_dockbook_get_tab_border (dockbook),
|
|
|
|
NULL);
|
|
|
|
|
2010-05-23 01:31:27 +08:00
|
|
|
for (iter = dockables; iter; iter = g_list_next (iter))
|
|
|
|
{
|
|
|
|
GimpDockable *dockable = GIMP_DOCKABLE (iter->data);
|
|
|
|
GtkWidget *tab_widget;
|
|
|
|
|
2010-06-12 05:18:49 +08:00
|
|
|
if (only_auto &&
|
2013-06-17 02:14:35 +08:00
|
|
|
! (gimp_dockable_get_tab_style (dockable) == GIMP_TAB_STYLE_AUTOMATIC))
|
2010-06-12 05:18:49 +08:00
|
|
|
continue;
|
|
|
|
|
2010-05-23 01:31:27 +08:00
|
|
|
tab_widget = gimp_dockbook_create_tab_widget (dockbook, dockable);
|
|
|
|
|
|
|
|
gtk_notebook_set_tab_label (GTK_NOTEBOOK (dockbook),
|
|
|
|
GTK_WIDGET (dockable),
|
|
|
|
tab_widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_list_free (dockables);
|
|
|
|
}
|
|
|
|
|
2008-05-20 05:11:03 +08:00
|
|
|
static void
|
|
|
|
gimp_dockbook_tab_drag_source_setup (GtkWidget *widget,
|
|
|
|
GimpDockable *dockable)
|
|
|
|
{
|
|
|
|
if (gimp_dockable_is_locked (dockable))
|
|
|
|
{
|
|
|
|
if (widget)
|
|
|
|
gtk_drag_source_unset (widget);
|
|
|
|
|
|
|
|
gtk_drag_source_unset (GTK_WIDGET (dockable));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (widget)
|
|
|
|
gtk_drag_source_set (widget,
|
|
|
|
GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
|
|
|
|
dialog_target_table,
|
|
|
|
G_N_ELEMENTS (dialog_target_table),
|
|
|
|
GDK_ACTION_MOVE);
|
|
|
|
|
|
|
|
gtk_drag_source_set (GTK_WIDGET (dockable),
|
|
|
|
GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
|
|
|
|
dialog_target_table,
|
|
|
|
G_N_ELEMENTS (dialog_target_table),
|
|
|
|
GDK_ACTION_MOVE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-04-11 00:03:40 +08:00
|
|
|
static void
|
|
|
|
gimp_dockbook_tab_drag_begin (GtkWidget *widget,
|
2004-08-25 01:16:46 +08:00
|
|
|
GdkDragContext *context,
|
2005-12-30 00:42:45 +08:00
|
|
|
GimpDockable *dockable)
|
2001-04-11 00:03:40 +08:00
|
|
|
{
|
2011-05-02 05:23:19 +08:00
|
|
|
GtkAllocation allocation;
|
|
|
|
GtkWidget *window;
|
|
|
|
GtkWidget *view;
|
|
|
|
GtkRequisition requisition;
|
|
|
|
gint drag_x;
|
|
|
|
gint drag_y;
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2010-01-15 22:33:08 +08:00
|
|
|
gtk_widget_get_allocation (widget, &allocation);
|
|
|
|
|
2007-10-16 21:56:34 +08:00
|
|
|
window = gtk_window_new (GTK_WINDOW_POPUP);
|
|
|
|
gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DND);
|
|
|
|
gtk_window_set_screen (GTK_WINDOW (window), gtk_widget_get_screen (widget));
|
|
|
|
|
2010-04-19 10:32:18 +08:00
|
|
|
view = gimp_dockable_create_drag_widget (dockable);
|
2005-12-29 12:05:50 +08:00
|
|
|
gtk_container_add (GTK_CONTAINER (window), view);
|
2004-08-25 01:16:46 +08:00
|
|
|
gtk_widget_show (view);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2005-12-29 11:48:35 +08:00
|
|
|
gtk_widget_size_request (view, &requisition);
|
|
|
|
|
2010-01-15 22:33:08 +08:00
|
|
|
if (requisition.width < allocation.width)
|
|
|
|
gtk_widget_set_size_request (view, allocation.width, -1);
|
2005-12-29 11:48:35 +08:00
|
|
|
|
2001-04-11 00:03:40 +08:00
|
|
|
gtk_widget_show (window);
|
|
|
|
|
2001-07-25 07:11:30 +08:00
|
|
|
g_object_set_data_full (G_OBJECT (dockable), "gimp-dock-drag-widget",
|
|
|
|
window,
|
|
|
|
(GDestroyNotify) gtk_widget_destroy);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2010-01-05 07:30:10 +08:00
|
|
|
gimp_dockable_get_drag_pos (dockable, &drag_x, &drag_y);
|
|
|
|
gtk_drag_set_icon_widget (context, window, drag_x, drag_y);
|
2005-12-30 00:42:45 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the source dockable insensitive to give a visual clue that
|
|
|
|
* it's the dockable that's being dragged around
|
|
|
|
*/
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (dockable), FALSE);
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_dockbook_tab_drag_end (GtkWidget *widget,
|
2004-08-25 01:16:46 +08:00
|
|
|
GdkDragContext *context,
|
2005-12-30 00:42:45 +08:00
|
|
|
GimpDockable *dockable)
|
2001-04-11 00:03:40 +08:00
|
|
|
{
|
2011-05-02 05:23:19 +08:00
|
|
|
GtkWidget *drag_widget;
|
|
|
|
|
|
|
|
drag_widget = g_object_get_data (G_OBJECT (dockable),
|
|
|
|
"gimp-dock-drag-widget");
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2001-07-27 07:35:00 +08:00
|
|
|
/* finding the drag_widget means the drop was not successful, so
|
|
|
|
* pop up a new dock and move the dockable there
|
|
|
|
*/
|
2001-04-11 00:03:40 +08:00
|
|
|
if (drag_widget)
|
|
|
|
{
|
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
2001-07-24 Michael Natterer <mitch@gimp.org>
Port to glib/gtk+ 2.0 episode I (every segfault has it's beginning)
* configure.in: require glib/gtk+ >= 1.3.7, commented out the
gtkxmhtml stuff.
From now on, you will need glib, pango, atk and gtk+ HEAD from CVS
to hack or use GIMP HEAD.
Beware, it crashes randomly :)
* app/core/Makefile.am
* app/core/gimpmarshal.list: new file plus rules to generate
gimpmarshal.[ch] from it.
* app/core/*
* app/tools/*
* app/widgets/*
* libgimpwidgets/*: started to use the glib object system. All
core/ objects are still gtk objects however. All signals are
created using g_signal_new(). There are many gtk+ artefacts left.
Finally, we will _not_ use the gtk_signal_foo() wrappers and
friends any more.
* app/colormaps.c
* app/devices.[ch]
* app/disp_callbacks.c
* app/errorconsole.c
* app/file-save.[ch]
* app/interface.c
* app/module_db.c
* app/nav_window.c
* app/ops_buttons.c
* app/scroll.c
* app/user_install.c
* app/gui/about-dialog.c
* app/gui/brush-editor.c
* app/gui/brushes-commands.c
* app/gui/color-notebook.c
* app/gui/colormap-dialog.c
* app/gui/dialogs-commands.c
* app/gui/dialogs-constructors.c
* app/gui/file-commands.c
* app/gui/file-dialog-utils.c
* app/gui/file-new-dialog.c
* app/gui/file-open-dialog.[ch]
* app/gui/file-save-dialog.c
* app/gui/gradient-editor.c
* app/gui/gradients-commands.c
* app/gui/image-commands.c
* app/gui/info-dialog.[ch]
* app/gui/layer-select.c
* app/gui/layers-commands.c
* app/gui/menus.c
* app/gui/offset-dialog.c
* app/gui/palette-editor.c
* app/gui/palettes-commands.c
* app/gui/patterns-commands.c
* app/gui/preferences-dialog.c
* app/gui/resize-dialog.[ch]
* app/gui/splash.c
* app/gui/tips-dialog.c
* app/gui/tool-options-dialog.c
* app/gui/toolbox.c
* app/gui/tools-commands.c
* libgimp/gimpbrushmenu.c
* libgimp/gimpmenu.c
* libgimp/gimppatternmenu.c
* libgimp/gimpui.c
* libgimpbase/gimpenv.c: tons and tons of changes like "const
gchar*", switch from GdkDeviceInfo to GdkDevice (very incomplete
and currently disables), lots of s/gtk_signal/g_signal/,
removal/replacement of deprecated stuff,
s/GtkSignalFunc/GCallback/ and lots of small changes and fixes
while I was on it, zillions of warnings left...
* modules/Makefile.am: disabled the water color selector
temporarily (XInput issues).
* plug-ins/Makefile.am
* plug-ins/common/.cvsignore
* plug-ins/common/Makefile.am
* plug-ins/common/plugin-defs.pl: simply excluded all plug-ins
which did not build (including Script-Fu). They are trivial to
fix.
2001-07-25 05:27:11 +08:00
|
|
|
g_object_set_data (G_OBJECT (dockable), "gimp-dock-drag-widget", NULL);
|
2003-10-07 20:24:01 +08:00
|
|
|
gimp_dockable_detach (dockable);
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
2005-12-30 00:42:45 +08:00
|
|
|
|
2010-01-05 07:30:10 +08:00
|
|
|
gimp_dockable_set_drag_pos (dockable,
|
|
|
|
GIMP_DOCKABLE_DRAG_OFFSET,
|
|
|
|
GIMP_DOCKABLE_DRAG_OFFSET);
|
2005-12-30 00:42:45 +08:00
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (dockable), TRUE);
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
|
|
|
|
2007-09-17 23:40:01 +08:00
|
|
|
|
|
|
|
/* tab DND target side */
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_dockbook_tab_drag_leave (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
guint time,
|
|
|
|
GimpDockable *dockable)
|
|
|
|
{
|
2010-01-05 07:30:10 +08:00
|
|
|
GimpDockbook *dockbook = gimp_dockable_get_dockbook (dockable);
|
2007-09-17 23:40:01 +08:00
|
|
|
|
|
|
|
gimp_dockbook_remove_tab_timeout (dockbook);
|
|
|
|
|
2009-11-29 02:12:39 +08:00
|
|
|
gimp_highlight_widget (widget, FALSE);
|
2007-09-17 23:40:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_dockbook_tab_drag_motion (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
guint time,
|
|
|
|
GimpDockable *dockable)
|
|
|
|
{
|
2010-01-05 07:30:10 +08:00
|
|
|
GimpDockbook *dockbook = gimp_dockable_get_dockbook (dockable);
|
2007-09-17 23:40:01 +08:00
|
|
|
GtkTargetList *target_list;
|
|
|
|
GdkAtom target_atom;
|
2015-02-20 04:18:21 +08:00
|
|
|
gboolean handle;
|
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
|
|
|
|
|
|
|
if (gimp_paned_box_will_handle_drag (dockbook->p->drag_handler,
|
|
|
|
widget,
|
|
|
|
context,
|
|
|
|
x, y,
|
|
|
|
time))
|
|
|
|
{
|
2015-02-20 04:18:21 +08:00
|
|
|
gdk_drag_status (context, 0, time);
|
|
|
|
gimp_highlight_widget (widget, FALSE);
|
|
|
|
|
|
|
|
return FALSE;
|
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
|
|
|
}
|
2007-09-17 23:40:01 +08:00
|
|
|
|
2009-09-13 22:30:09 +08:00
|
|
|
if (! dockbook->p->tab_hover_timeout ||
|
|
|
|
dockbook->p->tab_hover_dockable != dockable)
|
2007-09-17 23:40:01 +08:00
|
|
|
{
|
|
|
|
gint page_num;
|
|
|
|
|
|
|
|
gimp_dockbook_remove_tab_timeout (dockbook);
|
|
|
|
|
|
|
|
page_num = gtk_notebook_page_num (GTK_NOTEBOOK (dockbook),
|
|
|
|
GTK_WIDGET (dockable));
|
|
|
|
|
|
|
|
if (page_num != gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook)))
|
|
|
|
gimp_dockbook_add_tab_timeout (dockbook, dockable);
|
|
|
|
}
|
|
|
|
|
|
|
|
target_list = gtk_drag_dest_get_target_list (widget);
|
|
|
|
target_atom = gtk_drag_dest_find_target (widget, context, target_list);
|
|
|
|
|
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
|
|
|
handle = gtk_target_list_find (target_list, target_atom, NULL);
|
2007-09-17 23:40:01 +08:00
|
|
|
|
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
|
|
|
gdk_drag_status (context, handle ? GDK_ACTION_MOVE : 0, time);
|
|
|
|
gimp_highlight_widget (widget, handle);
|
2015-02-20 04:18:21 +08:00
|
|
|
|
|
|
|
/* Return TRUE so drag_leave() is called */
|
|
|
|
return TRUE;
|
2007-09-17 23:40:01 +08:00
|
|
|
}
|
|
|
|
|
2001-04-11 00:03:40 +08:00
|
|
|
static gboolean
|
|
|
|
gimp_dockbook_tab_drag_drop (GtkWidget *widget,
|
2004-08-25 01:16:46 +08:00
|
|
|
GdkDragContext *context,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
2005-12-30 00:42:45 +08:00
|
|
|
guint time)
|
2001-04-11 00:03:40 +08:00
|
|
|
{
|
|
|
|
GimpDockable *dest_dockable;
|
|
|
|
GtkWidget *source;
|
2015-02-20 04:18:21 +08:00
|
|
|
gboolean dropped = FALSE;
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2003-10-06 01:26:21 +08:00
|
|
|
dest_dockable = g_object_get_data (G_OBJECT (widget), "gimp-dockable");
|
2001-04-11 00:03:40 +08:00
|
|
|
|
|
|
|
source = gtk_drag_get_source_widget (context);
|
|
|
|
|
2010-01-05 07:30:10 +08:00
|
|
|
if (gimp_paned_box_will_handle_drag (gimp_dockable_get_drag_handler (dest_dockable),
|
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
|
|
|
widget,
|
|
|
|
context,
|
|
|
|
x, y,
|
|
|
|
time))
|
|
|
|
{
|
2015-02-20 04:18:21 +08:00
|
|
|
return FALSE;
|
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
|
|
|
}
|
|
|
|
|
2001-05-07 00:14:34 +08:00
|
|
|
if (dest_dockable && source)
|
2001-04-11 00:03:40 +08:00
|
|
|
{
|
2009-10-26 06:02:05 +08:00
|
|
|
GimpDockable *src_dockable =
|
|
|
|
gimp_dockbook_drag_source_to_dockable (source);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
|
|
|
if (src_dockable)
|
2004-08-25 01:16:46 +08:00
|
|
|
{
|
|
|
|
gint dest_index;
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2004-08-25 01:16:46 +08:00
|
|
|
dest_index =
|
2010-01-05 07:30:10 +08:00
|
|
|
gtk_notebook_page_num (GTK_NOTEBOOK (gimp_dockable_get_dockbook (dest_dockable)),
|
2004-08-25 01:16:46 +08:00
|
|
|
GTK_WIDGET (dest_dockable));
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2010-01-05 07:30:10 +08:00
|
|
|
if (gimp_dockable_get_dockbook (src_dockable) !=
|
|
|
|
gimp_dockable_get_dockbook (dest_dockable))
|
2004-08-25 01:16:46 +08:00
|
|
|
{
|
|
|
|
g_object_ref (src_dockable);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2010-01-05 07:30:10 +08:00
|
|
|
gimp_dockbook_remove (gimp_dockable_get_dockbook (src_dockable), src_dockable);
|
|
|
|
gimp_dockbook_add (gimp_dockable_get_dockbook (dest_dockable), src_dockable,
|
2004-08-25 01:16:46 +08:00
|
|
|
dest_index);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2004-08-25 01:16:46 +08:00
|
|
|
g_object_unref (src_dockable);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2015-02-20 04:18:21 +08:00
|
|
|
dropped = TRUE;
|
2004-08-25 01:16:46 +08:00
|
|
|
}
|
|
|
|
else if (src_dockable != dest_dockable)
|
|
|
|
{
|
2010-01-05 07:30:10 +08:00
|
|
|
gtk_notebook_reorder_child (GTK_NOTEBOOK (gimp_dockable_get_dockbook (src_dockable)),
|
2004-08-25 01:16:46 +08:00
|
|
|
GTK_WIDGET (src_dockable),
|
|
|
|
dest_index);
|
2001-04-11 00:03:40 +08:00
|
|
|
|
2010-01-05 07:30:10 +08:00
|
|
|
g_signal_emit (gimp_dockable_get_dockbook (src_dockable),
|
2003-05-03 19:59:44 +08:00
|
|
|
dockbook_signals[DOCKABLE_REORDERED], 0,
|
|
|
|
src_dockable);
|
|
|
|
|
2015-02-20 04:18:21 +08:00
|
|
|
dropped = TRUE;
|
2004-08-25 01:16:46 +08:00
|
|
|
}
|
|
|
|
}
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
|
|
|
|
2015-02-20 04:18:21 +08:00
|
|
|
gtk_drag_finish (context, dropped, TRUE, time);
|
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
|
|
|
|
2015-02-20 04:18:21 +08:00
|
|
|
return TRUE;
|
2001-04-11 00:03:40 +08:00
|
|
|
}
|
2003-08-26 18:07:01 +08:00
|
|
|
|
2010-06-11 13:35:07 +08:00
|
|
|
static GtkWidget *
|
|
|
|
gimp_dockable_create_event_box_tab_widget (GimpDockable *dockable,
|
|
|
|
GimpContext *context,
|
|
|
|
GimpTabStyle tab_style,
|
|
|
|
GtkIconSize size)
|
|
|
|
{
|
|
|
|
GtkWidget *tab_widget;
|
|
|
|
|
|
|
|
tab_widget =
|
|
|
|
gimp_dockable_create_tab_widget (dockable,
|
|
|
|
context,
|
|
|
|
tab_style,
|
|
|
|
size);
|
|
|
|
|
|
|
|
if (! GIMP_IS_VIEW (tab_widget))
|
|
|
|
{
|
|
|
|
GtkWidget *event_box;
|
|
|
|
|
|
|
|
event_box = gtk_event_box_new ();
|
|
|
|
gtk_event_box_set_visible_window (GTK_EVENT_BOX (event_box), FALSE);
|
|
|
|
gtk_event_box_set_above_child (GTK_EVENT_BOX (event_box), TRUE);
|
|
|
|
gtk_container_add (GTK_CONTAINER (event_box), tab_widget);
|
|
|
|
gtk_widget_show (tab_widget);
|
|
|
|
|
|
|
|
tab_widget = event_box;
|
|
|
|
}
|
|
|
|
|
|
|
|
return tab_widget;
|
|
|
|
}
|
|
|
|
|
2010-05-23 18:36:24 +08:00
|
|
|
static GtkIconSize
|
|
|
|
gimp_dockbook_get_tab_icon_size (GimpDockbook *dockbook)
|
|
|
|
{
|
2017-03-10 13:04:20 +08:00
|
|
|
Gimp *gimp;
|
|
|
|
GimpIconSize size;
|
|
|
|
GtkIconSize tab_size = DEFAULT_TAB_ICON_SIZE;
|
2012-02-21 07:36:18 +08:00
|
|
|
|
2017-03-10 13:04:20 +08:00
|
|
|
gimp = gimp_dock_get_context (dockbook->p->dock)->gimp;
|
|
|
|
|
2017-03-17 12:52:20 +08:00
|
|
|
size = gimp_gui_config_detect_icon_size (GIMP_GUI_CONFIG (gimp->config));
|
2017-03-10 13:04:20 +08:00
|
|
|
/* Match GimpIconSize with GtkIconSize. */
|
|
|
|
switch (size)
|
|
|
|
{
|
|
|
|
case GIMP_ICON_SIZE_SMALL:
|
|
|
|
case GIMP_ICON_SIZE_MEDIUM:
|
|
|
|
tab_size = GTK_ICON_SIZE_MENU;
|
|
|
|
break;
|
|
|
|
case GIMP_ICON_SIZE_LARGE:
|
|
|
|
tab_size = GTK_ICON_SIZE_LARGE_TOOLBAR;
|
|
|
|
break;
|
|
|
|
case GIMP_ICON_SIZE_HUGE:
|
|
|
|
tab_size = GTK_ICON_SIZE_DND;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* GIMP_ICON_SIZE_DEFAULT:
|
|
|
|
* let's use the size set by the theme. */
|
|
|
|
gtk_widget_style_get (GTK_WIDGET (dockbook),
|
|
|
|
"tab-icon-size", &tab_size,
|
|
|
|
NULL);
|
|
|
|
break;
|
|
|
|
}
|
2010-05-23 18:36:24 +08:00
|
|
|
|
|
|
|
return tab_size;
|
|
|
|
}
|
|
|
|
|
2017-03-11 09:42:10 +08:00
|
|
|
static gint
|
|
|
|
gimp_dockbook_get_tab_border (GimpDockbook *dockbook)
|
|
|
|
{
|
|
|
|
Gimp *gimp;
|
|
|
|
GimpIconSize size;
|
|
|
|
gint tab_border = DEFAULT_TAB_BORDER;
|
|
|
|
|
|
|
|
gimp = gimp_dock_get_context (dockbook->p->dock)->gimp;
|
|
|
|
|
|
|
|
gtk_widget_style_get (GTK_WIDGET (dockbook),
|
|
|
|
"tab-border", &tab_border,
|
|
|
|
NULL);
|
|
|
|
|
2017-03-17 12:52:20 +08:00
|
|
|
size = gimp_gui_config_detect_icon_size (GIMP_GUI_CONFIG (gimp->config));
|
2017-03-11 09:42:10 +08:00
|
|
|
/* Match GimpIconSize with GtkIconSize. */
|
|
|
|
switch (size)
|
|
|
|
{
|
|
|
|
case GIMP_ICON_SIZE_SMALL:
|
|
|
|
tab_border /= 2;
|
|
|
|
break;
|
|
|
|
case GIMP_ICON_SIZE_LARGE:
|
2017-03-11 10:35:14 +08:00
|
|
|
tab_border *= 2;
|
2017-03-11 09:42:10 +08:00
|
|
|
break;
|
|
|
|
case GIMP_ICON_SIZE_HUGE:
|
2017-03-11 10:35:14 +08:00
|
|
|
tab_border *= 3;
|
2017-03-11 09:42:10 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* GIMP_ICON_SIZE_MEDIUM and GIMP_ICON_SIZE_DEFAULT:
|
|
|
|
* let's use the size set by the theme. */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return tab_border;
|
|
|
|
}
|
|
|
|
|
2007-09-17 23:40:01 +08:00
|
|
|
static void
|
|
|
|
gimp_dockbook_add_tab_timeout (GimpDockbook *dockbook,
|
|
|
|
GimpDockable *dockable)
|
|
|
|
{
|
2009-09-13 22:30:09 +08:00
|
|
|
dockbook->p->tab_hover_timeout =
|
2007-09-17 23:40:01 +08:00
|
|
|
g_timeout_add (TAB_HOVER_TIMEOUT,
|
|
|
|
(GSourceFunc) gimp_dockbook_tab_timeout,
|
|
|
|
dockbook);
|
2008-03-11 00:01:48 +08:00
|
|
|
|
2009-09-13 22:30:09 +08:00
|
|
|
dockbook->p->tab_hover_dockable = dockable;
|
2007-09-17 23:40:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_dockbook_remove_tab_timeout (GimpDockbook *dockbook)
|
|
|
|
{
|
2009-09-13 22:30:09 +08:00
|
|
|
if (dockbook->p->tab_hover_timeout)
|
2007-09-17 23:40:01 +08:00
|
|
|
{
|
2009-09-13 22:30:09 +08:00
|
|
|
g_source_remove (dockbook->p->tab_hover_timeout);
|
|
|
|
dockbook->p->tab_hover_timeout = 0;
|
|
|
|
dockbook->p->tab_hover_dockable = NULL;
|
2007-09-17 23:40:01 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_dockbook_tab_timeout (GimpDockbook *dockbook)
|
|
|
|
{
|
|
|
|
gint page_num;
|
|
|
|
|
|
|
|
GDK_THREADS_ENTER ();
|
|
|
|
|
|
|
|
page_num = gtk_notebook_page_num (GTK_NOTEBOOK (dockbook),
|
2009-09-13 22:30:09 +08:00
|
|
|
GTK_WIDGET (dockbook->p->tab_hover_dockable));
|
2007-09-17 23:40:01 +08:00
|
|
|
gtk_notebook_set_current_page (GTK_NOTEBOOK (dockbook), page_num);
|
|
|
|
|
2009-09-13 22:30:09 +08:00
|
|
|
dockbook->p->tab_hover_timeout = 0;
|
|
|
|
dockbook->p->tab_hover_dockable = NULL;
|
2007-09-17 23:40:01 +08:00
|
|
|
|
|
|
|
GDK_THREADS_LEAVE ();
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2008-05-20 05:11:03 +08:00
|
|
|
static void
|
|
|
|
gimp_dockbook_tab_locked_notify (GimpDockable *dockable,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
GimpDockbook *dockbook)
|
|
|
|
{
|
|
|
|
GtkWidget *tab_widget;
|
|
|
|
|
|
|
|
tab_widget = gtk_notebook_get_tab_label (GTK_NOTEBOOK (dockbook),
|
|
|
|
GTK_WIDGET (dockable));
|
|
|
|
|
|
|
|
gimp_dockbook_tab_drag_source_setup (tab_widget, dockable);
|
|
|
|
}
|
|
|
|
|
2003-08-26 18:07:01 +08:00
|
|
|
static void
|
|
|
|
gimp_dockbook_help_func (const gchar *help_id,
|
|
|
|
gpointer help_data)
|
|
|
|
{
|
2008-05-20 05:11:03 +08:00
|
|
|
GimpDockbook *dockbook = GIMP_DOCKBOOK (help_data);
|
2003-08-26 18:07:01 +08:00
|
|
|
GtkWidget *dockable;
|
|
|
|
gint page_num;
|
|
|
|
|
|
|
|
page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook));
|
|
|
|
|
|
|
|
dockable = gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook), page_num);
|
|
|
|
|
|
|
|
if (GIMP_IS_DOCKABLE (dockable))
|
2010-01-05 07:30:10 +08:00
|
|
|
gimp_standard_help_func (gimp_dockable_get_help_id (GIMP_DOCKABLE (dockable)),
|
|
|
|
NULL);
|
2003-08-26 18:07:01 +08:00
|
|
|
else
|
|
|
|
gimp_standard_help_func (GIMP_HELP_DOCK, NULL);
|
|
|
|
}
|
2010-06-12 05:18:49 +08:00
|
|
|
|
|
|
|
static const gchar *
|
|
|
|
gimp_dockbook_get_tab_style_name (GimpTabStyle tab_style)
|
|
|
|
{
|
|
|
|
return g_enum_get_value (g_type_class_peek (GIMP_TYPE_TAB_STYLE),
|
2016-01-09 03:49:33 +08:00
|
|
|
tab_style)->value_name;
|
2010-06-12 05:18:49 +08:00
|
|
|
}
|
2017-03-10 13:04:20 +08:00
|
|
|
|
|
|
|
static void
|
2017-03-17 12:52:20 +08:00
|
|
|
gimp_dockbook_config_size_changed (GimpGuiConfig *config,
|
|
|
|
GimpDockbook *dockbook)
|
2017-03-10 13:04:20 +08:00
|
|
|
{
|
|
|
|
gimp_dockbook_recreate_tab_widgets (dockbook, TRUE);
|
|
|
|
}
|