Re: [gtk-list] Re: drag and drop



Owen Taylor <otaylor@redhat.com> writes:

> hubert.fauque@wanadoo.fr writes:

> > I have found that the drop on a tree doesn't work well:
> > If I call gtk_drag_dest_set on the tree_items, the drop succeeds
> > only when it is on the first tree_item, and not when I try
> > to drop on the other tree_items; in fact the drop succeeds
> > in this case when the cursor is at some distance below the
> > tree_item;
> > I have traced the problem to gtkdnd.c in the function
> > gtk_drag_find_widget; 
> > the problem  comes from the fact that the tree
> > which is in a tree_item is not drawn inside the tree_item;
> > and this function seems to assume that the children of a
> > widget are always drawn inside this widget;
> 
> That is an accurate assumption as far as GTK+ goes -
> the children of a widget _are_ drawn inside this
> widget.
> 
> So, basically, GtkTree is broken. The only correct
> fix is to make it compute its allocations so that
> the tree is inside the GtkTreeItem. I do _not_
> want to special case GtkTree inside gtkdnd.c.
 
I have a better fix:
Here is gtk_tree_forall and gtk_tree_item_forall:

gtk_tree_forall (GtkContainer *container,
		 gboolean      include_internals,
		 GtkCallback   callback,
		 gpointer      callback_data)
{
  GtkTree *tree;
  GtkWidget *child;
  GList *children;
  
  
  g_return_if_fail (container != NULL);
  g_return_if_fail (GTK_IS_TREE (container));
  g_return_if_fail (callback != NULL);
  
  tree = GTK_TREE (container);
  children = tree->children;
  
  while (children)
    {
      child = children->data;
      children = children->next;
      
      (* callback) (child, callback_data);
    }
}

gtk_tree_item_forall (GtkContainer *container,
		      gboolean      include_internals,
		      GtkCallback   callback,
		      gpointer      callback_data)
{
  GtkBin *bin;
  GtkTreeItem *tree_item;

  g_return_if_fail (container != NULL);
  g_return_if_fail (GTK_IS_TREE_ITEM (container));
  g_return_if_fail (callback != NULL);

  bin = GTK_BIN (container);
  tree_item = GTK_TREE_ITEM (container);

  if (bin->child)
    (* callback) (bin->child, callback_data);
  if (include_internals && tree_item->subtree)
    (* callback) (tree_item->subtree, callback_data);
}


the callback on the subtree is done in gtk_tree_item_forall
which is not logical because the parent of the subtree is
the tree, not the tree_item; and the problem with the drag and drop
comes from here because the subtree is _not_ drawn in the tree_item
window but in his parent window;

If I suppress the callback on the subtree in gtk_tree_item_forall
and I put it in gtk_tree_forall:

      if (include_internals && GTK_TREE_ITEM(child)->subtree)
      (* callback) (GTK_TREE_ITEM(child)->subtree, callback_data);

the drop on the tree works; 
I don't know if this change would break existing code, but if
someone wants to do a drag and drop on a tree, this is a solution;

Hubert




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