send a GtkWidget** instead of a GtkNotebookPage* when doing tabs DnD, this

2006-03-22  Carlos Garnacho  <carlosg@gnome.org>

        * gtk/gtknotebook.c: send a GtkWidget** instead of a GtkNotebookPage*
        when doing tabs DnD, this allows DnD interaction with other widgets,
        added some docs for this too.
        * tests/testnotebookdnd.c: add some code to test it.
This commit is contained in:
Carlos Garnacho 2006-03-22 16:11:48 +00:00 committed by Carlos Garnacho
parent 0047b0b98d
commit f77c0fb15e
4 changed files with 145 additions and 30 deletions

View File

@ -1,3 +1,10 @@
2006-03-22 Carlos Garnacho <carlosg@gnome.org>
* gtk/gtknotebook.c: send a GtkWidget** instead of a GtkNotebookPage*
when doing tabs DnD, this allows DnD interaction with other widgets,
added some docs for this too.
* tests/testnotebookdnd.c: add some code to test it.
2006-03-22 Matthias Clasen <mclasen@redhat.com>
* gtk/gtk.symbols:

View File

@ -1,3 +1,10 @@
2006-03-22 Carlos Garnacho <carlosg@gnome.org>
* gtk/gtknotebook.c: send a GtkWidget** instead of a GtkNotebookPage*
when doing tabs DnD, this allows DnD interaction with other widgets,
added some docs for this too.
* tests/testnotebookdnd.c: add some code to test it.
2006-03-22 Matthias Clasen <mclasen@redhat.com>
* gtk/gtk.symbols:

View File

@ -40,7 +40,6 @@
#include "gtkalias.h"
#include "gtkdnd.h"
#define ARROW_SIZE 12
#define ARROW_SPACING 0
#define SCROLL_DELAY_FACTOR 5
@ -2847,33 +2846,36 @@ gtk_notebook_drag_drop (GtkWidget *widget,
static void
do_detach_tab (GtkNotebook *from,
GtkNotebook *to,
GtkNotebookPage *page_info,
GtkWidget *child,
gint x,
gint y)
{
GtkWidget *child, *tab_label, *menu_label;
GtkWidget *tab_label, *menu_label;
gboolean tab_expand, tab_fill, reorderable, detachable;
GList *element;
guint tab_pack;
gint page_num;
menu_label = tab_label = child = NULL;
menu_label = gtk_notebook_get_menu_label (from, child);
if (page_info->menu_label)
menu_label = g_object_ref (page_info->menu_label);
if (menu_label)
g_object_ref (menu_label);
if (page_info->tab_label)
tab_label = g_object_ref (page_info->tab_label);
tab_label = gtk_notebook_get_tab_label (from, child);
if (tab_label)
g_object_ref (tab_label);
if (page_info->child)
child = g_object_ref (page_info->child);
g_object_ref (child);
/* preserve properties */
tab_expand = page_info->expand;
tab_fill = page_info->fill;
tab_pack = page_info->pack;
reorderable = page_info->reorderable;
detachable = page_info->detachable;
gtk_container_child_get (GTK_CONTAINER (from),
child,
"tab-expand", &tab_expand,
"tab-fill", &tab_fill,
"tab-pack", &tab_pack,
"reorderable", &reorderable,
"detachable", &detachable,
NULL);
gtk_container_remove (GTK_CONTAINER (from), child);
@ -2912,7 +2914,6 @@ gtk_notebook_drag_data_get (GtkWidget *widget,
guint time)
{
GtkNotebook *dest_notebook, *notebook;
gint page_num;
if (data->target != gdk_atom_intern_static_string ("GTK_NOTEBOOK_TAB") &&
(data->target != gdk_atom_intern_static_string ("application/x-rootwindow-drop") ||
@ -2920,15 +2921,14 @@ gtk_notebook_drag_data_get (GtkWidget *widget,
return;
notebook = GTK_NOTEBOOK (widget);
page_num = g_list_index (notebook->children, notebook->cur_page);
if (data->target == gdk_atom_intern_static_string ("GTK_NOTEBOOK_TAB"))
{
gtk_selection_data_set (data,
data->target,
8,
(void*) notebook->cur_page,
sizeof (GtkNotebookPage));
(void*) &notebook->cur_page->child,
sizeof (gpointer));
}
else
{
@ -2944,7 +2944,7 @@ gtk_notebook_drag_data_get (GtkWidget *widget,
window_creation_hook_data);
if (dest_notebook)
do_detach_tab (notebook, dest_notebook, notebook->cur_page, 0, 0);
do_detach_tab (notebook, dest_notebook, notebook->cur_page->child, 0, 0);
}
}
@ -2959,7 +2959,7 @@ gtk_notebook_drag_data_received (GtkWidget *widget,
{
GtkNotebook *notebook;
GtkWidget *source_widget;
GtkNotebookPage *page_info;
GtkWidget **child;
notebook = GTK_NOTEBOOK (widget);
source_widget = gtk_drag_get_source_widget (context);
@ -2967,13 +2967,13 @@ gtk_notebook_drag_data_received (GtkWidget *widget,
if (source_widget &&
data->target == gdk_atom_intern_static_string ("GTK_NOTEBOOK_TAB"))
{
page_info = (void*) data->data;
child = (void*) data->data;
do_detach_tab (GTK_NOTEBOOK (source_widget), notebook, page_info, x, y);
do_detach_tab (GTK_NOTEBOOK (source_widget), notebook, *child, x, y);
gtk_drag_finish (context, TRUE, FALSE, time);
}
gtk_drag_finish (context, FALSE, FALSE, time);
else
gtk_drag_finish (context, FALSE, FALSE, time);
}
/* Private GtkContainer Methods :
@ -6920,10 +6920,43 @@ gtk_notebook_get_tab_detachable (GtkNotebook *notebook,
* @child: a child #GtkWidget
* @detachable: whether the tab is detachable or not
*
* Sets whether the tab can be detached from @notebook to another notebook.
* Sets whether the tab can be detached from @notebook to another
* notebook or widget.
*
* Note that 2 notebooks must share a common group identificator
* (see gtk_notebook_set_group_id ()) to allow tabs interchange between them.
* (see gtk_notebook_set_group_id ()) to allow automatic tabs
* interchange between them.
*
* If you want a widget to interact with a notebook through DnD
* (i.e.: accept dragged tabs from it) it must be set as a drop
* destination and accept the target "GTK_NOTEBOOK_TAB". The notebook
* will fill the selection with a GtkWidget** pointing to the child
* widget that corresponds to the dropped tab.
*
* <informalexample><programlisting>
* static void
* on_drop_zone_drag_data_received (GtkWidget *widget,
* GdkDragContext *context,
* gint x,
* gint y,
* GtkSelectionData *selection_data,
* guint info,
* guint time,
* gpointer user_data)
* {
* GtkWidget *notebook;
* GtkWidget **child;
*
* notebook = gtk_drag_get_source_widget (context);
* child = (void*) selection_data->data;
*
* process_widget (*child);
* gtk_container_remove (GTK_CONTAINER (notebook), *child);
* }
* </programlisting></informalexample>
*
* If you want a notebook to accept drags from other widgets,
* you will have to set your own DnD code to do it.
*
* Since: 2.10
**/

View File

@ -1,3 +1,4 @@
/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
/*
* GTK - The GIMP Toolkit
* Copyright (C) 2006 Carlos Garnacho Parro <carlosg@gnome.org>
@ -64,6 +65,10 @@ gchar *tabs4 [] = {
NULL
};
static const GtkTargetEntry button_targets[] = {
{ "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, 0 },
};
static GtkNotebook*
window_creation_function (GtkNotebook *source_notebook,
GtkWidget *child,
@ -94,6 +99,46 @@ on_page_reordered (GtkNotebook *notebook, GtkWidget *child, guint page_num, gpoi
g_print ("page %d reordered\n", page_num);
}
static void
on_notebook_drag_begin (GtkWidget *widget,
GdkDragContext *context,
gpointer data)
{
GdkPixbuf *pixbuf;
guint page_num;
page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (widget));
pixbuf = gtk_widget_render_icon (widget,
(page_num % 2) ? GTK_STOCK_HELP : GTK_STOCK_STOP,
GTK_ICON_SIZE_DND, NULL);
gtk_drag_set_icon_pixbuf (context, pixbuf, 0, 0);
g_object_unref (pixbuf);
}
static void
on_button_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *data,
guint info,
guint time,
gpointer user_data)
{
GtkWidget *source, *tab_label;
GtkWidget **child;
source = gtk_drag_get_source_widget (context);
child = (void*) data->data;
tab_label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (source), *child);
g_print ("Removing tab: %s\n", gtk_label_get_text (GTK_LABEL (tab_label)));
gtk_container_remove (GTK_CONTAINER (source), *child);
}
static GtkWidget*
create_notebook (gchar **labels,
gint group_id,
@ -131,10 +176,29 @@ create_notebook (gchar **labels,
g_signal_connect (GTK_NOTEBOOK (notebook), "page-reordered",
G_CALLBACK (on_page_reordered), NULL);
g_signal_connect_after (G_OBJECT (notebook), "drag-begin",
G_CALLBACK (on_notebook_drag_begin), NULL);
return notebook;
}
static GtkWidget*
create_trash_button (void)
{
GtkWidget *button;
button = gtk_button_new_from_stock (GTK_STOCK_DELETE);
gtk_drag_dest_set (button,
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
button_targets,
G_N_ELEMENTS (button_targets),
GDK_ACTION_MOVE);
g_signal_connect_after (G_OBJECT (button), "drag-data-received",
G_CALLBACK (on_button_drag_data_received), NULL);
return button;
}
gint
main (gint argc, gchar *argv[])
{
@ -143,7 +207,7 @@ main (gint argc, gchar *argv[])
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
table = gtk_table_new (2, 2, TRUE);
table = gtk_table_new (3, 2, FALSE);
gtk_notebook_set_window_creation_hook (window_creation_function, NULL);
@ -163,6 +227,10 @@ main (gint argc, gchar *argv[])
create_notebook (tabs4, GROUP_A, PACK_ALTERNATE, GTK_POS_RIGHT),
1, 2, 1, 2);
gtk_table_attach (GTK_TABLE (table),
create_trash_button (), 1, 2, 2, 3,
GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
gtk_container_add (GTK_CONTAINER (window), table);
gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
gtk_widget_show_all (window);