Add row_draggable() vfunc, and wrapper function.

Mon Nov  5 22:34:29 2001  Owen Taylor  <otaylor@redhat.com>

	* gtk/gtktreednd.[ch] (struct _GtkTreeDragSourceIface):
	Add row_draggable() vfunc, and wrapper function.

	* gtk/gtktreednd.[ch] (struct _GtkTreeDragDestIface): Make
	row_drop_possible take a GtkSelectionData, rather than
	model/row pair.

	* gtk/gtktreestore.c gtk/gtkliststore.c: Update for
	new DND interfaces.

	* gtk/gtktreeview.[ch]: Remove the row_draggable_func
	location_dropable_func from gtk_tree_view_set_rows_drag_source/dest.
	and rename them to enable_model_drag_source/dest.

	* gtk/treeviewcolumn.c: Add DND of columns between rows.
	Still can't drop _to_ the left tree, but other places
	work.

	* gtk/gtktreeview.c (unset_reorderable): Unset the
	reorderable property if unset/enable_model_drag_source/dest
	are called manually.

	* gtk/gtktreestore.c (gtk_tree_store_row_drop_possible):
	Correct for change in depth count handling.

	* gtk/gtktreeview.c (gtk_tree_view_create_row_drag_icon):
	Pass in a expose area to gtk_tree_view_column_cell_render()
This commit is contained in:
Owen Taylor 2001-11-06 19:10:03 +00:00 committed by Owen Taylor
parent 9bb17278c4
commit 57479a86be
15 changed files with 638 additions and 215 deletions

View File

@ -1,3 +1,33 @@
Mon Nov 5 22:34:29 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtktreednd.[ch] (struct _GtkTreeDragSourceIface):
Add row_draggable() vfunc, and wrapper function.
* gtk/gtktreednd.[ch] (struct _GtkTreeDragDestIface): Make
row_drop_possible take a GtkSelectionData, rather than
model/row pair.
* gtk/gtktreestore.c gtk/gtkliststore.c: Update for
new DND interfaces.
* gtk/gtktreeview.[ch]: Remove the row_draggable_func
location_dropable_func from gtk_tree_view_set_rows_drag_source/dest.
and rename them to enable_model_drag_source/dest.
* gtk/treeviewcolumn.c: Add DND of columns between rows.
Still can't drop _to_ the left tree, but other places
work.
* gtk/gtktreeview.c (unset_reorderable): Unset the
reorderable property if unset/enable_model_drag_source/dest
are called manually.
* gtk/gtktreestore.c (gtk_tree_store_row_drop_possible):
Correct for change in depth count handling.
* gtk/gtktreeview.c (gtk_tree_view_create_row_drag_icon):
Pass in a expose area to gtk_tree_view_column_cell_render()
2001-11-06 Havoc Pennington <hp@redhat.com>
* demos/gtk-demo/textview.c (easter_egg_callback): wacky easter egg

View File

@ -1,3 +1,33 @@
Mon Nov 5 22:34:29 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtktreednd.[ch] (struct _GtkTreeDragSourceIface):
Add row_draggable() vfunc, and wrapper function.
* gtk/gtktreednd.[ch] (struct _GtkTreeDragDestIface): Make
row_drop_possible take a GtkSelectionData, rather than
model/row pair.
* gtk/gtktreestore.c gtk/gtkliststore.c: Update for
new DND interfaces.
* gtk/gtktreeview.[ch]: Remove the row_draggable_func
location_dropable_func from gtk_tree_view_set_rows_drag_source/dest.
and rename them to enable_model_drag_source/dest.
* gtk/treeviewcolumn.c: Add DND of columns between rows.
Still can't drop _to_ the left tree, but other places
work.
* gtk/gtktreeview.c (unset_reorderable): Unset the
reorderable property if unset/enable_model_drag_source/dest
are called manually.
* gtk/gtktreestore.c (gtk_tree_store_row_drop_possible):
Correct for change in depth count handling.
* gtk/gtktreeview.c (gtk_tree_view_create_row_drag_icon):
Pass in a expose area to gtk_tree_view_column_cell_render()
2001-11-06 Havoc Pennington <hp@redhat.com>
* demos/gtk-demo/textview.c (easter_egg_callback): wacky easter egg

View File

@ -1,3 +1,33 @@
Mon Nov 5 22:34:29 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtktreednd.[ch] (struct _GtkTreeDragSourceIface):
Add row_draggable() vfunc, and wrapper function.
* gtk/gtktreednd.[ch] (struct _GtkTreeDragDestIface): Make
row_drop_possible take a GtkSelectionData, rather than
model/row pair.
* gtk/gtktreestore.c gtk/gtkliststore.c: Update for
new DND interfaces.
* gtk/gtktreeview.[ch]: Remove the row_draggable_func
location_dropable_func from gtk_tree_view_set_rows_drag_source/dest.
and rename them to enable_model_drag_source/dest.
* gtk/treeviewcolumn.c: Add DND of columns between rows.
Still can't drop _to_ the left tree, but other places
work.
* gtk/gtktreeview.c (unset_reorderable): Unset the
reorderable property if unset/enable_model_drag_source/dest
are called manually.
* gtk/gtktreestore.c (gtk_tree_store_row_drop_possible):
Correct for change in depth count handling.
* gtk/gtktreeview.c (gtk_tree_view_create_row_drag_icon):
Pass in a expose area to gtk_tree_view_column_cell_render()
2001-11-06 Havoc Pennington <hp@redhat.com>
* demos/gtk-demo/textview.c (easter_egg_callback): wacky easter egg

View File

@ -1,3 +1,33 @@
Mon Nov 5 22:34:29 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtktreednd.[ch] (struct _GtkTreeDragSourceIface):
Add row_draggable() vfunc, and wrapper function.
* gtk/gtktreednd.[ch] (struct _GtkTreeDragDestIface): Make
row_drop_possible take a GtkSelectionData, rather than
model/row pair.
* gtk/gtktreestore.c gtk/gtkliststore.c: Update for
new DND interfaces.
* gtk/gtktreeview.[ch]: Remove the row_draggable_func
location_dropable_func from gtk_tree_view_set_rows_drag_source/dest.
and rename them to enable_model_drag_source/dest.
* gtk/treeviewcolumn.c: Add DND of columns between rows.
Still can't drop _to_ the left tree, but other places
work.
* gtk/gtktreeview.c (unset_reorderable): Unset the
reorderable property if unset/enable_model_drag_source/dest
are called manually.
* gtk/gtktreestore.c (gtk_tree_store_row_drop_possible):
Correct for change in depth count handling.
* gtk/gtktreeview.c (gtk_tree_view_create_row_drag_icon):
Pass in a expose area to gtk_tree_view_column_cell_render()
2001-11-06 Havoc Pennington <hp@redhat.com>
* demos/gtk-demo/textview.c (easter_egg_callback): wacky easter egg

View File

@ -1,3 +1,33 @@
Mon Nov 5 22:34:29 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtktreednd.[ch] (struct _GtkTreeDragSourceIface):
Add row_draggable() vfunc, and wrapper function.
* gtk/gtktreednd.[ch] (struct _GtkTreeDragDestIface): Make
row_drop_possible take a GtkSelectionData, rather than
model/row pair.
* gtk/gtktreestore.c gtk/gtkliststore.c: Update for
new DND interfaces.
* gtk/gtktreeview.[ch]: Remove the row_draggable_func
location_dropable_func from gtk_tree_view_set_rows_drag_source/dest.
and rename them to enable_model_drag_source/dest.
* gtk/treeviewcolumn.c: Add DND of columns between rows.
Still can't drop _to_ the left tree, but other places
work.
* gtk/gtktreeview.c (unset_reorderable): Unset the
reorderable property if unset/enable_model_drag_source/dest
are called manually.
* gtk/gtktreestore.c (gtk_tree_store_row_drop_possible):
Correct for change in depth count handling.
* gtk/gtktreeview.c (gtk_tree_view_create_row_drag_icon):
Pass in a expose area to gtk_tree_view_column_cell_render()
2001-11-06 Havoc Pennington <hp@redhat.com>
* demos/gtk-demo/textview.c (easter_egg_callback): wacky easter egg

View File

@ -1,3 +1,33 @@
Mon Nov 5 22:34:29 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtktreednd.[ch] (struct _GtkTreeDragSourceIface):
Add row_draggable() vfunc, and wrapper function.
* gtk/gtktreednd.[ch] (struct _GtkTreeDragDestIface): Make
row_drop_possible take a GtkSelectionData, rather than
model/row pair.
* gtk/gtktreestore.c gtk/gtkliststore.c: Update for
new DND interfaces.
* gtk/gtktreeview.[ch]: Remove the row_draggable_func
location_dropable_func from gtk_tree_view_set_rows_drag_source/dest.
and rename them to enable_model_drag_source/dest.
* gtk/treeviewcolumn.c: Add DND of columns between rows.
Still can't drop _to_ the left tree, but other places
work.
* gtk/gtktreeview.c (unset_reorderable): Unset the
reorderable property if unset/enable_model_drag_source/dest
are called manually.
* gtk/gtktreestore.c (gtk_tree_store_row_drop_possible):
Correct for change in depth count handling.
* gtk/gtktreeview.c (gtk_tree_view_create_row_drag_icon):
Pass in a expose area to gtk_tree_view_column_cell_render()
2001-11-06 Havoc Pennington <hp@redhat.com>
* demos/gtk-demo/textview.c (easter_egg_callback): wacky easter egg

View File

@ -1,3 +1,33 @@
Mon Nov 5 22:34:29 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtktreednd.[ch] (struct _GtkTreeDragSourceIface):
Add row_draggable() vfunc, and wrapper function.
* gtk/gtktreednd.[ch] (struct _GtkTreeDragDestIface): Make
row_drop_possible take a GtkSelectionData, rather than
model/row pair.
* gtk/gtktreestore.c gtk/gtkliststore.c: Update for
new DND interfaces.
* gtk/gtktreeview.[ch]: Remove the row_draggable_func
location_dropable_func from gtk_tree_view_set_rows_drag_source/dest.
and rename them to enable_model_drag_source/dest.
* gtk/treeviewcolumn.c: Add DND of columns between rows.
Still can't drop _to_ the left tree, but other places
work.
* gtk/gtktreeview.c (unset_reorderable): Unset the
reorderable property if unset/enable_model_drag_source/dest
are called manually.
* gtk/gtktreestore.c (gtk_tree_store_row_drop_possible):
Correct for change in depth count handling.
* gtk/gtktreeview.c (gtk_tree_view_create_row_drag_icon):
Pass in a expose area to gtk_tree_view_column_cell_render()
2001-11-06 Havoc Pennington <hp@redhat.com>
* demos/gtk-demo/textview.c (easter_egg_callback): wacky easter egg

View File

@ -84,9 +84,8 @@ static gboolean gtk_list_store_drag_data_received (GtkTreeDragDest *drag_dest,
GtkTreePath *dest,
GtkSelectionData *selection_data);
static gboolean gtk_list_store_row_drop_possible (GtkTreeDragDest *drag_dest,
GtkTreeModel *src_model,
GtkTreePath *src_path,
GtkTreePath *dest_path);
GtkTreePath *dest_path,
GtkSelectionData *selection_data);
/* sortable */
@ -1407,29 +1406,39 @@ gtk_list_store_drag_data_received (GtkTreeDragDest *drag_dest,
}
static gboolean
gtk_list_store_row_drop_possible (GtkTreeDragDest *drag_dest,
GtkTreeModel *src_model,
GtkTreePath *src_path,
GtkTreePath *dest_path)
gtk_list_store_row_drop_possible (GtkTreeDragDest *drag_dest,
GtkTreePath *dest_path,
GtkSelectionData *selection_data)
{
gint *indices;
GtkTreeModel *src_model = NULL;
GtkTreePath *src_path = NULL;
gboolean retval = FALSE;
g_return_val_if_fail (GTK_IS_LIST_STORE (drag_dest), FALSE);
if (!gtk_tree_get_row_drag_data (selection_data,
&src_model,
&src_path))
goto out;
if (src_model != GTK_TREE_MODEL (drag_dest))
return FALSE;
goto out;
if (gtk_tree_path_get_depth (dest_path) != 1)
return FALSE;
goto out;
/* can drop before any existing node, or before one past any existing. */
indices = gtk_tree_path_get_indices (dest_path);
if (indices[0] <= GTK_LIST_STORE (drag_dest)->length)
return TRUE;
else
return FALSE;
retval = TRUE;
out:
gtk_tree_path_free (src_path);
return retval;
}

View File

@ -73,6 +73,31 @@ gtk_tree_drag_dest_get_type (void)
return our_type;
}
/**
* gtk_tree_drag_source_row_draggable:
* @drag_source: a #GtkTreeDragSource
* @path: row on which user is initiating a drag
*
* Asks the #GtkTreeDragSource whether a particular row can be used as
* the source of a DND operation. If the source doesn't implement
* this interface, the row is assumed draggable.
*
* Return value: %TRUE if the row can be dragged
**/
gboolean
gtk_tree_drag_source_row_draggable (GtkTreeDragSource *drag_source,
GtkTreePath *path)
{
GtkTreeDragSourceIface *iface = GTK_TREE_DRAG_SOURCE_GET_IFACE (drag_source);
g_return_val_if_fail (path != NULL, FALSE);
if (iface->row_draggable)
return (* iface->row_draggable) (drag_source, path);
else
return TRUE;
}
/**
* gtk_tree_drag_source_drag_data_delete:
@ -159,13 +184,12 @@ gtk_tree_drag_dest_drag_data_received (GtkTreeDragDest *drag_dest,
/**
* gtk_tree_drag_dest_drop_possible:
* @drag_dest: a #GtkTreeDragDest
* @src_model: #GtkTreeModel being dragged from
* @src_path: row being dragged
* @dest_path: destination row
* @selection_data: the data being dragged
*
* Determines whether a drop is possible before the given @dest_path,
* at the same depth as @dest_path. i.e., can we drop @src_model such
* that it now resides at @dest_path. @dest_path does not have to
* at the same depth as @dest_path. i.e., can we drop the data in
* @selection_data at that location. @dest_path does not have to
* exist; the return value will almost certainly be %FALSE if the
* parent of @dest_path doesn't exist, though.
*
@ -173,18 +197,16 @@ gtk_tree_drag_dest_drag_data_received (GtkTreeDragDest *drag_dest,
**/
gboolean
gtk_tree_drag_dest_row_drop_possible (GtkTreeDragDest *drag_dest,
GtkTreeModel *src_model,
GtkTreePath *src_path,
GtkTreePath *dest_path)
GtkTreePath *dest_path,
GtkSelectionData *selection_data)
{
GtkTreeDragDestIface *iface = GTK_TREE_DRAG_DEST_GET_IFACE (drag_dest);
g_return_val_if_fail (iface->row_drop_possible != NULL, FALSE);
g_return_val_if_fail (GTK_IS_TREE_MODEL (src_model), FALSE);
g_return_val_if_fail (src_path != NULL, FALSE);
g_return_val_if_fail (selection_data != NULL, FALSE);
g_return_val_if_fail (dest_path != NULL, FALSE);
return (* iface->row_drop_possible) (drag_dest, src_model, src_path, dest_path);
return (* iface->row_drop_possible) (drag_dest, dest_path, selection_data);
}
typedef struct _TreeRowData TreeRowData;

View File

@ -41,6 +41,9 @@ struct _GtkTreeDragSourceIface
/* VTable - not signals */
gboolean (* row_draggable) (GtkTreeDragSource *drag_source,
GtkTreePath *path);
gboolean (* drag_data_get) (GtkTreeDragSource *drag_source,
GtkTreePath *path,
GtkSelectionData *selection_data);
@ -51,6 +54,10 @@ struct _GtkTreeDragSourceIface
GType gtk_tree_drag_source_get_type (void) G_GNUC_CONST;
/* Returns whether the given row can be dragged */
gboolean gtk_tree_drag_source_row_draggable (GtkTreeDragSource *drag_source,
GtkTreePath *path);
/* Deletes the given row, or returns FALSE if it can't */
gboolean gtk_tree_drag_source_drag_data_delete (GtkTreeDragSource *drag_source,
GtkTreePath *path);
@ -81,9 +88,8 @@ struct _GtkTreeDragDestIface
GtkSelectionData *selection_data);
gboolean (* row_drop_possible) (GtkTreeDragDest *drag_dest,
GtkTreeModel *src_model,
GtkTreePath *src_path,
GtkTreePath *dest_path);
GtkTreePath *dest_path,
GtkSelectionData *selection_data);
};
GType gtk_tree_drag_dest_get_type (void) G_GNUC_CONST;
@ -98,9 +104,8 @@ gboolean gtk_tree_drag_dest_drag_data_received (GtkTreeDragDest *drag_dest,
/* Returns TRUE if we can drop before path; path may not exist. */
gboolean gtk_tree_drag_dest_row_drop_possible (GtkTreeDragDest *drag_dest,
GtkTreeModel *src_model,
GtkTreePath *src_path,
GtkTreePath *dest_path);
GtkTreePath *dest_path,
GtkSelectionData *selection_data);
/* The selection data would normally have target type GTK_TREE_MODEL_ROW in this

View File

@ -83,9 +83,8 @@ static gboolean gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest,
GtkTreePath *dest,
GtkSelectionData *selection_data);
static gboolean gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
GtkTreeModel *src_model,
GtkTreePath *src_path,
GtkTreePath *dest_path);
GtkTreePath *dest_path,
GtkSelectionData *selection_data);
/* Sortable Interfaces */
@ -1587,45 +1586,55 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest,
}
static gboolean
gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
GtkTreeModel *src_model,
GtkTreePath *src_path,
GtkTreePath *dest_path)
gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
GtkTreePath *dest_path,
GtkSelectionData *selection_data)
{
GtkTreeModel *src_model = NULL;
GtkTreePath *src_path = NULL;
GtkTreePath *tmp = NULL;
gboolean retval = FALSE;
if (!gtk_tree_get_row_drag_data (selection_data,
&src_model,
&src_path))
goto out;
/* can only drag to ourselves */
if (src_model != GTK_TREE_MODEL (drag_dest))
return FALSE;
goto out;
/* Can't drop into ourself. */
if (gtk_tree_path_is_ancestor (src_path,
dest_path))
return FALSE;
goto out;
/* Can't drop if dest_path's parent doesn't exist */
{
GtkTreeIter iter;
GtkTreePath *tmp = gtk_tree_path_copy (dest_path);
/* if we can't go up, we know the parent exists, the root
* always exists.
*/
if (gtk_tree_path_up (tmp))
if (gtk_tree_path_get_depth (dest_path) > 1)
{
if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest),
&iter, tmp))
{
if (tmp)
gtk_tree_path_free (tmp);
return FALSE;
}
tmp = gtk_tree_path_copy (dest_path);
gtk_tree_path_up (tmp);
if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest),
&iter, tmp))
goto out;
}
if (tmp)
gtk_tree_path_free (tmp);
}
/* Can otherwise drop anywhere. */
return TRUE;
retval = TRUE;
out:
if (src_path)
gtk_tree_path_free (src_path);
if (tmp)
gtk_tree_path_free (tmp);
return retval;
}
/* Sorting */

View File

@ -77,10 +77,8 @@ struct _TreeViewDragInfo
GdkModifierType start_button_mask;
GtkTargetList *source_target_list;
GdkDragAction source_actions;
GClosure *row_draggable_closure;
GtkTargetList *dest_target_list;
GClosure *location_droppable_closure;
guint source_set : 1;
guint dest_set : 1;
@ -2463,6 +2461,9 @@ gtk_tree_view_motion (GtkWidget *widget,
/* Warning: Very scary function.
* Modify at your own risk
*
* KEEP IN SYNC WITH gtk_tree_view_create_row_drag_icon()!
* FIXME: It's not...
*/
static gboolean
gtk_tree_view_bin_expose (GtkWidget *widget,
@ -3127,23 +3128,15 @@ clear_source_info (TreeViewDragInfo *di)
if (di->source_target_list)
gtk_target_list_unref (di->source_target_list);
if (di->row_draggable_closure)
g_closure_unref (di->row_draggable_closure);
di->source_target_list = NULL;
di->row_draggable_closure = NULL;
}
static void
clear_dest_info (TreeViewDragInfo *di)
{
if (di->location_droppable_closure)
g_closure_unref (di->location_droppable_closure);
if (di->dest_target_list)
gtk_target_list_unref (di->dest_target_list);
di->location_droppable_closure = NULL;
di->dest_target_list = NULL;
}
@ -3464,25 +3457,26 @@ gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view,
gint button;
gint cell_x, cell_y;
GtkTreeModel *model;
gboolean retval = FALSE;
di = get_info (tree_view);
if (di == NULL)
return FALSE;
goto out;
if (tree_view->priv->pressed_button < 0)
return FALSE;
goto out;
if (!gtk_drag_check_threshold (GTK_WIDGET (tree_view),
tree_view->priv->press_start_x,
tree_view->priv->press_start_y,
event->x, event->y))
return FALSE;
goto out;
model = gtk_tree_view_get_model (tree_view);
if (model == NULL)
return FALSE;
goto out;
button = tree_view->priv->pressed_button;
tree_view->priv->pressed_button = -1;
@ -3497,16 +3491,21 @@ gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view,
&cell_y);
if (path == NULL)
return FALSE;
goto out;
/* FIXME if the path doesn't match the row_draggable predicate,
* return FALSE and free path
*/
if (!GTK_IS_TREE_DRAG_SOURCE (model) ||
!gtk_tree_drag_source_row_draggable (GTK_TREE_DRAG_SOURCE (model),
path))
goto out;
/* FIXME Check whether we're a start button, if not return FALSE and
* free path
*/
/* Now we can begin the drag */
retval = TRUE;
context = gtk_drag_begin (GTK_WIDGET (tree_view),
di->source_target_list,
di->source_actions,
@ -3533,9 +3532,12 @@ gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view,
}
set_source_row (context, model, path);
gtk_tree_path_free (path);
return TRUE;
out:
if (path)
gtk_tree_path_free (path);
return retval;
}
@ -3822,24 +3824,10 @@ gtk_tree_view_drag_data_received (GtkWidget *widget,
if (suggested_action)
{
GtkTreeModel *src_model = NULL;
GtkTreePath *src_path = NULL;
if (!gtk_tree_get_row_drag_data (selection_data,
&src_model,
&src_path))
suggested_action = 0;
if (suggested_action)
{
if (!gtk_tree_drag_dest_row_drop_possible (GTK_TREE_DRAG_DEST (model),
src_model,
src_path,
path))
suggested_action = 0;
gtk_tree_path_free (src_path);
}
if (!gtk_tree_drag_dest_row_drop_possible (GTK_TREE_DRAG_DEST (model),
path,
selection_data))
suggested_action = 0;
}
gdk_drag_status (context, suggested_action, time);
@ -7996,17 +7984,15 @@ gtk_tree_view_set_reorderable (GtkTreeView *tree_view,
if (reorderable)
{
gtk_tree_view_set_rows_drag_source (tree_view,
GDK_BUTTON1_MASK,
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE,
NULL, NULL);
gtk_tree_view_set_rows_drag_dest (tree_view,
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE,
NULL, NULL);
gtk_tree_view_enable_model_drag_source (tree_view,
GDK_BUTTON1_MASK,
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE);
gtk_tree_view_enable_model_drag_dest (tree_view,
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE);
}
else
{
@ -8475,15 +8461,22 @@ gtk_tree_view_tree_to_widget_coords (GtkTreeView *tree_view,
*wy = ty - tree_view->priv->vadjustment->value;
}
static void
unset_reorderable (GtkTreeView *tree_view)
{
if (tree_view->priv->reorderable)
{
tree_view->priv->reorderable = FALSE;
g_object_notify (G_OBJECT (tree_view), "reorderable");
}
}
void
gtk_tree_view_set_rows_drag_source (GtkTreeView *tree_view,
GdkModifierType start_button_mask,
const GtkTargetEntry *targets,
gint n_targets,
GdkDragAction actions,
GtkTreeViewDraggableFunc row_draggable_func,
gpointer user_data)
gtk_tree_view_enable_model_drag_source (GtkTreeView *tree_view,
GdkModifierType start_button_mask,
const GtkTargetEntry *targets,
gint n_targets,
GdkDragAction actions)
{
TreeViewDragInfo *di;
@ -8496,24 +8489,16 @@ gtk_tree_view_set_rows_drag_source (GtkTreeView *tree_view,
di->source_target_list = gtk_target_list_new (targets, n_targets);
di->source_actions = actions;
if (row_draggable_func)
{
di->row_draggable_closure = g_cclosure_new ((GCallback) row_draggable_func,
user_data, NULL);
g_closure_ref (di->row_draggable_closure);
g_closure_sink (di->row_draggable_closure);
}
di->source_set = TRUE;
unset_reorderable (tree_view);
}
void
gtk_tree_view_set_rows_drag_dest (GtkTreeView *tree_view,
const GtkTargetEntry *targets,
gint n_targets,
GdkDragAction actions,
GtkTreeViewDroppableFunc location_droppable_func,
gpointer user_data)
gtk_tree_view_enable_model_drag_dest (GtkTreeView *tree_view,
const GtkTargetEntry *targets,
gint n_targets,
GdkDragAction actions)
{
TreeViewDragInfo *di;
@ -8531,15 +8516,9 @@ gtk_tree_view_set_rows_drag_dest (GtkTreeView *tree_view,
if (targets)
di->dest_target_list = gtk_target_list_new (targets, n_targets);
if (location_droppable_func)
{
di->location_droppable_closure = g_cclosure_new ((GCallback) location_droppable_func,
user_data, NULL);
g_closure_ref (di->location_droppable_closure);
g_closure_sink (di->location_droppable_closure);
}
di->dest_set = TRUE;
unset_reorderable (tree_view);
}
void
@ -8562,6 +8541,8 @@ gtk_tree_view_unset_rows_drag_source (GtkTreeView *tree_view)
if (!di->dest_set && !di->source_set)
remove_info (tree_view);
}
unset_reorderable (tree_view);
}
void
@ -8585,6 +8566,8 @@ gtk_tree_view_unset_rows_drag_dest (GtkTreeView *tree_view)
if (!di->dest_set && !di->source_set)
remove_info (tree_view);
}
unset_reorderable (tree_view);
}
void
@ -8754,6 +8737,7 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view,
gint cell_offset;
GList *list;
GdkRectangle background_area;
GdkRectangle expose_area;
GtkWidget *widget;
gint depth;
/* start drawing inside the black outline */
@ -8791,6 +8775,11 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view,
background_area.height + 2,
-1);
expose_area.x = 0;
expose_area.y = 0;
expose_area.width = bin_window_width + 2;
expose_area.height = background_area.height + 2;
gdk_draw_rectangle (drawable,
widget->style->base_gc [GTK_WIDGET_STATE (widget)],
TRUE,
@ -8839,7 +8828,7 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view,
drawable,
&background_area,
&cell_area,
NULL,
&expose_area,
0);
cell_offset += column->width;

View File

@ -108,18 +108,9 @@ typedef gboolean (* GtkTreeViewColumnDropFunc) (GtkTreeView *tree_vi
GtkTreeViewColumn *prev_column,
GtkTreeViewColumn *next_column,
gpointer data);
typedef gboolean (* GtkTreeViewDraggableFunc) (GtkTreeView *tree_view,
GdkDragContext *context,
GtkTreePath *path,
gpointer user_data);
typedef void (* GtkTreeViewMappingFunc) (GtkTreeView *tree_view,
GtkTreePath *path,
gpointer user_data);
typedef gboolean (* GtkTreeViewDroppableFunc) (GtkTreeView *tree_view,
GdkDragContext *context,
GtkTreePath *path,
GtkTreeViewDropPosition *pos,
gpointer user_data);
typedef gboolean (*GtkTreeViewSearchEqualFunc) (GtkTreeModel *model,
gint column,
const gchar *key,
@ -255,19 +246,15 @@ void gtk_tree_view_tree_to_widget_coords (GtkTreeView
gint *wy);
/* Drag-and-Drop support */
void gtk_tree_view_set_rows_drag_source (GtkTreeView *tree_view,
void gtk_tree_view_enable_model_drag_source (GtkTreeView *tree_view,
GdkModifierType start_button_mask,
const GtkTargetEntry *targets,
gint n_targets,
GdkDragAction actions,
GtkTreeViewDraggableFunc row_draggable_func,
gpointer user_data);
void gtk_tree_view_set_rows_drag_dest (GtkTreeView *tree_view,
GdkDragAction actions);
void gtk_tree_view_enable_model_drag_dest (GtkTreeView *tree_view,
const GtkTargetEntry *targets,
gint n_targets,
GdkDragAction actions,
GtkTreeViewDroppableFunc location_droppable_func,
gpointer user_data);
GdkDragAction actions);
void gtk_tree_view_unset_rows_drag_source (GtkTreeView *tree_view);
void gtk_tree_view_unset_rows_drag_dest (GtkTreeView *tree_view);

View File

@ -33,7 +33,10 @@ GtkWidget *sample_tree_view_bottom;
#define column_data "my_column_data"
static void move_row (GtkTreeModel *src,
GtkTreeIter *src_iter,
GtkTreeModel *dest,
GtkTreeIter *dest_iter);
/* Kids, don't try this at home. */
@ -246,6 +249,102 @@ view_column_model_tree_model_init (GtkTreeModelIface *iface)
iface->iter_parent = view_column_model_iter_parent;
}
static gboolean
view_column_model_drag_data_get (GtkTreeDragSource *drag_source,
GtkTreePath *path,
GtkSelectionData *selection_data)
{
if (gtk_tree_set_row_drag_data (selection_data,
GTK_TREE_MODEL (drag_source),
path))
return TRUE;
else
return FALSE;
}
static gboolean
view_column_model_drag_data_delete (GtkTreeDragSource *drag_source,
GtkTreePath *path)
{
/* Nothing -- we handle moves on the dest side */
return TRUE;
}
static gboolean
view_column_model_row_drop_possible (GtkTreeDragDest *drag_dest,
GtkTreePath *dest_path,
GtkSelectionData *selection_data)
{
GtkTreeModel *src_model;
if (gtk_tree_get_row_drag_data (selection_data,
&src_model,
NULL))
{
if (src_model == left_tree_model ||
src_model == top_right_tree_model ||
src_model == bottom_right_tree_model)
return TRUE;
}
return FALSE;
}
static gboolean
view_column_model_drag_data_received (GtkTreeDragDest *drag_dest,
GtkTreePath *dest,
GtkSelectionData *selection_data)
{
GtkTreeModel *src_model;
GtkTreePath *src_path = NULL;
gboolean retval = FALSE;
if (gtk_tree_get_row_drag_data (selection_data,
&src_model,
&src_path))
{
GtkTreeIter src_iter;
GtkTreeIter dest_iter;
gboolean have_dest;
/* We are a little lazy here, and assume if we can't convert dest
* to an iter, we need to append. See gtkliststore.c for a more
* careful handling of this.
*/
have_dest = gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest), &dest_iter, dest);
if (gtk_tree_model_get_iter (src_model, &src_iter, src_path))
{
if (src_model == left_tree_model ||
src_model == top_right_tree_model ||
src_model == bottom_right_tree_model)
{
move_row (src_model, &src_iter, GTK_TREE_MODEL (drag_dest),
have_dest ? &dest_iter : NULL);
retval = TRUE;
}
}
gtk_tree_path_free (src_path);
}
return retval;
}
static void
view_column_model_drag_source_init (GtkTreeDragSourceIface *iface)
{
iface->drag_data_get = view_column_model_drag_data_get;
iface->drag_data_delete = view_column_model_drag_data_delete;
}
static void
view_column_model_drag_dest_init (GtkTreeDragDestIface *iface)
{
iface->drag_data_received = view_column_model_drag_data_received;
iface->row_drop_possible = view_column_model_row_drop_possible;
}
GType
view_column_model_get_type (void)
@ -274,10 +373,30 @@ view_column_model_get_type (void)
NULL
};
static const GInterfaceInfo drag_source_info =
{
(GInterfaceInitFunc) view_column_model_drag_source_init,
NULL,
NULL
};
static const GInterfaceInfo drag_dest_info =
{
(GInterfaceInitFunc) view_column_model_drag_dest_init,
NULL,
NULL
};
view_column_model_type = g_type_register_static (G_TYPE_OBJECT, "ViewModelColumn", &view_column_model_info, 0);
g_type_add_interface_static (view_column_model_type,
GTK_TYPE_TREE_MODEL,
&tree_model_info);
g_type_add_interface_static (view_column_model_type,
GTK_TYPE_TREE_DRAG_SOURCE,
&drag_source_info);
g_type_add_interface_static (view_column_model_type,
GTK_TYPE_TREE_DRAG_DEST,
&drag_dest_info);
}
return view_column_model_type;
@ -470,20 +589,18 @@ set_visible (GtkCellRendererToggle *cell,
}
static void
add_left_clicked (GtkWidget *button,
gpointer data)
move_to_left (GtkTreeModel *src,
GtkTreeIter *src_iter,
GtkTreeIter *dest_iter)
{
GtkTreeIter iter;
gchar *label;
GtkTreeViewColumn *column;
GtkTreeSelection *selection;
gchar *label;
GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data));
gtk_tree_model_get (src, src_iter, 0, &label, 1, &column, -1);
gtk_tree_selection_get_selected (selection, NULL, &iter);
gtk_tree_model_get (gtk_tree_view_get_model (GTK_TREE_VIEW (data)),
&iter, 0, &label, 1, &column, -1);
if (GTK_WIDGET (data) == top_right_tree_view)
if (src == top_right_tree_model)
gtk_tree_view_remove_column (GTK_TREE_VIEW (sample_tree_view_top), column);
else
gtk_tree_view_remove_column (GTK_TREE_VIEW (sample_tree_view_bottom), column);
@ -491,33 +608,116 @@ add_left_clicked (GtkWidget *button,
/* gtk_list_store_remove (GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (data))), &iter);*/
/* Put it back on the left */
gtk_list_store_append (GTK_LIST_STORE (left_tree_model), &iter);
if (dest_iter)
gtk_list_store_insert_before (GTK_LIST_STORE (left_tree_model),
&iter, dest_iter);
else
gtk_list_store_append (GTK_LIST_STORE (left_tree_model), &iter);
gtk_list_store_set (GTK_LIST_STORE (left_tree_model), &iter, 0, label, 1, column, -1);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (left_tree_view));
gtk_tree_selection_select_iter (selection, &iter);
g_free (label);
}
static void
move_to_right (GtkTreeIter *src_iter,
GtkTreeModel *dest,
GtkTreeIter *dest_iter)
{
gchar *label;
GtkTreeViewColumn *column;
gint before = -1;
gtk_tree_model_get (GTK_TREE_MODEL (left_tree_model),
src_iter, 0, &label, 1, &column, -1);
gtk_list_store_remove (GTK_LIST_STORE (left_tree_model), src_iter);
if (dest_iter)
{
GtkTreePath *path = gtk_tree_model_get_path (dest, dest_iter);
before = (gtk_tree_path_get_indices (path))[0];
gtk_tree_path_free (path);
}
if (dest == top_right_tree_model)
gtk_tree_view_insert_column (GTK_TREE_VIEW (sample_tree_view_top), column, before);
else
gtk_tree_view_insert_column (GTK_TREE_VIEW (sample_tree_view_bottom), column, before);
g_free (label);
}
static void
move_up_or_down (GtkTreeModel *src,
GtkTreeIter *src_iter,
GtkTreeModel *dest,
GtkTreeIter *dest_iter)
{
GtkTreeViewColumn *column;
gchar *label;
gint before = -1;
gtk_tree_model_get (src, src_iter, 0, &label, 1, &column, -1);
if (dest_iter)
{
GtkTreePath *path = gtk_tree_model_get_path (dest, dest_iter);
before = (gtk_tree_path_get_indices (path))[0];
gtk_tree_path_free (path);
}
if (src == top_right_tree_model)
gtk_tree_view_remove_column (GTK_TREE_VIEW (sample_tree_view_top), column);
else
gtk_tree_view_remove_column (GTK_TREE_VIEW (sample_tree_view_bottom), column);
if (dest == top_right_tree_model)
gtk_tree_view_insert_column (GTK_TREE_VIEW (sample_tree_view_top), column, before);
else
gtk_tree_view_insert_column (GTK_TREE_VIEW (sample_tree_view_bottom), column, before);
g_free (label);
}
static void
move_row (GtkTreeModel *src,
GtkTreeIter *src_iter,
GtkTreeModel *dest,
GtkTreeIter *dest_iter)
{
if (src == left_tree_model)
move_to_right (src_iter, dest, dest_iter);
else if (dest == left_tree_model)
move_to_left (src, src_iter, dest_iter);
else
move_up_or_down (src, src_iter, dest, dest_iter);
}
static void
add_left_clicked (GtkWidget *button,
gpointer data)
{
GtkTreeIter iter;
GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data));
gtk_tree_selection_get_selected (selection, NULL, &iter);
move_to_left (gtk_tree_view_get_model (GTK_TREE_VIEW (data)), &iter, NULL);
}
static void
add_right_clicked (GtkWidget *button, gpointer data)
{
GtkTreeIter iter;
gchar *label;
GtkTreeViewColumn *column;
GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (left_tree_view));
gtk_tree_selection_get_selected (selection, NULL, &iter);
gtk_tree_model_get (GTK_TREE_MODEL (left_tree_model),
&iter, 0, &label, 1, &column, -1);
gtk_list_store_remove (GTK_LIST_STORE (left_tree_model), &iter);
if (GTK_WIDGET (data) == top_right_tree_view)
gtk_tree_view_append_column (GTK_TREE_VIEW (sample_tree_view_top), column);
else
gtk_tree_view_append_column (GTK_TREE_VIEW (sample_tree_view_bottom), column);
g_free (label);
move_to_right (&iter, gtk_tree_view_get_model (GTK_TREE_VIEW (data)), NULL);
}
static void
@ -689,41 +889,35 @@ main (int argc, char *argv[])
/* Drag and Drop */
gtk_tree_view_set_rows_drag_source (GTK_TREE_VIEW (left_tree_view),
GDK_BUTTON1_MASK,
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE,
NULL, NULL);
gtk_tree_view_set_rows_drag_dest (GTK_TREE_VIEW (left_tree_view),
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE,
NULL, NULL);
gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (left_tree_view),
GDK_BUTTON1_MASK,
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE);
gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (left_tree_view),
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE);
gtk_tree_view_set_rows_drag_source (GTK_TREE_VIEW (top_right_tree_view),
GDK_BUTTON1_MASK,
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE,
NULL, NULL);
gtk_tree_view_set_rows_drag_dest (GTK_TREE_VIEW (top_right_tree_view),
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE,
NULL, NULL);
gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (top_right_tree_view),
GDK_BUTTON1_MASK,
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE);
gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (top_right_tree_view),
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE);
gtk_tree_view_set_rows_drag_source (GTK_TREE_VIEW (bottom_right_tree_view),
GDK_BUTTON1_MASK,
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE,
NULL, NULL);
gtk_tree_view_set_rows_drag_dest (GTK_TREE_VIEW (bottom_right_tree_view),
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE,
NULL, NULL);
gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (bottom_right_tree_view),
GDK_BUTTON1_MASK,
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE);
gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (bottom_right_tree_view),
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE);
gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, 0);

View File

@ -656,18 +656,16 @@ main (int argc,
tv = gtk_tree_view_new_with_model (models[0]);
gtk_tree_view_set_rows_drag_source (GTK_TREE_VIEW (tv),
GDK_BUTTON1_MASK,
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE | GDK_ACTION_COPY,
NULL, NULL);
gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (tv),
GDK_BUTTON1_MASK,
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE | GDK_ACTION_COPY);
gtk_tree_view_set_rows_drag_dest (GTK_TREE_VIEW (tv),
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE | GDK_ACTION_COPY,
NULL, NULL);
gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (tv),
row_targets,
G_N_ELEMENTS (row_targets),
GDK_ACTION_MOVE | GDK_ACTION_COPY);
/* Model menu */