static gboolean toolbar_drag_motion (GtkToolbar *toolbar, GdkDragContext *context, gint x, gint y, guint time, gpointer null) { gint index; if (!drag_item) { drag_item = gtk_tool_button_new (NULL, "A quite long button"); gtk_object_sink (GTK_OBJECT (g_object_ref (drag_item))); } gdk_drag_status (context, GDK_ACTION_MOVE, time); index = gtk_toolbar_get_drop_index (toolbar, x, y); gtk_toolbar_set_drop_highlight_item (toolbar, drag_item, index); return TRUE; }
static void toolbar_drag_data_received_cb (GtkToolbar *toolbar, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, EggEditableToolbar *etoolbar) { /* This function can be called for two reasons * * (1) drag_motion() needs an item to pass to * gtk_toolbar_set_drop_highlight_item(). We can * recognize this case by etoolbar->priv->pending being TRUE * We should just create an item and return. * * (2) The drag has finished, and drag_drop() wants us to * actually add a new item to the toolbar. */ GdkAtom type = gtk_selection_data_get_data_type (selection_data); const char *data = (char *)gtk_selection_data_get_data (selection_data); int ipos = -1; char *name = NULL; gboolean used = FALSE; /* Find out where the drop is occuring, and the name of what is being dropped. */ if (gtk_selection_data_get_length (selection_data) >= 0) { ipos = gtk_toolbar_get_drop_index (toolbar, x, y); name = egg_toolbars_model_get_name (etoolbar->priv->model, type, data, FALSE); if (name != NULL) { used = ((egg_toolbars_model_get_name_flags (etoolbar->priv->model, name) & EGG_TB_MODEL_NAME_USED) != 0); } } /* If we just want a highlight item, then . */ if (etoolbar->priv->dnd_pending > 0) { etoolbar->priv->dnd_pending--; if (name != NULL && etoolbar->priv->dnd_toolbar == toolbar && !used) { etoolbar->priv->dnd_toolitem = create_item_from_action (etoolbar, name); gtk_toolbar_set_drop_highlight_item (etoolbar->priv->dnd_toolbar, etoolbar->priv->dnd_toolitem, ipos); } } else { gtk_toolbar_set_drop_highlight_item (toolbar, NULL, 0); etoolbar->priv->dnd_toolbar = NULL; etoolbar->priv->dnd_toolitem = NULL; /* If we don't have a name to use yet, try to create one. */ if (name == NULL && gtk_selection_data_get_length (selection_data) >= 0) { name = egg_toolbars_model_get_name (etoolbar->priv->model, type, data, TRUE); } if (name != NULL && !used) { gint tpos = get_toolbar_position (etoolbar, GTK_WIDGET (toolbar)); egg_toolbars_model_add_item (etoolbar->priv->model, tpos, ipos, name); gtk_drag_finish (context, TRUE, context->action == GDK_ACTION_MOVE, time); } else { gtk_drag_finish (context, FALSE, context->action == GDK_ACTION_MOVE, time); } } g_free (name); }
/** * called when a widget is dropped onto the toolbar */ gboolean nsgtk_toolbar_data(GtkWidget *widget, GdkDragContext *gdc, gint x, gint y, guint time, gpointer data) { nsgtk_scaffolding *g = (nsgtk_scaffolding *)data; int ind = gtk_toolbar_get_drop_index(nsgtk_scaffolding_toolbar(g), x, y); int q, i; if (window->currentbutton == -1) return TRUE; struct nsgtk_theme *theme = nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR); if (theme == NULL) { warn_user(messages_get("NoMemory"), 0); return TRUE; } if (nsgtk_scaffolding_button(g, window->currentbutton)->location != -1) { /* widget was already in the toolbar; so replace */ if (nsgtk_scaffolding_button(g, window->currentbutton)-> location < ind) ind--; gtk_container_remove(GTK_CONTAINER( nsgtk_scaffolding_toolbar(g)), GTK_WIDGET( nsgtk_scaffolding_button(g, window->currentbutton)->button)); /* 'move' all widgets further right than the original location, * one place to the left in logical schema */ for (i = nsgtk_scaffolding_button(g, window->currentbutton)-> location + 1; i < PLACEHOLDER_BUTTON; i++) { q = nsgtk_toolbar_get_id_at_location(g, i); if (q == -1) continue; nsgtk_scaffolding_button(g, q)->location--; } nsgtk_scaffolding_button(g, window->currentbutton)-> location = -1; } nsgtk_scaffolding_button(g, window->currentbutton)->button = GTK_TOOL_ITEM(nsgtk_toolbar_make_widget(g, window->currentbutton, theme)); free(theme); if (nsgtk_scaffolding_button(g, window->currentbutton)->button == NULL) { warn_user("NoMemory", 0); return TRUE; } /* update logical schema */ nsgtk_scaffolding_reset_offset(g); /* 'move' all widgets further right than the new location, one place to * the right in logical schema */ for (i = PLACEHOLDER_BUTTON - 1; i >= ind; i--) { q = nsgtk_toolbar_get_id_at_location(g, i); if (q == -1) continue; nsgtk_scaffolding_button(g, q)->location++; } nsgtk_scaffolding_button(g, window->currentbutton)->location = ind; /* complete action */ gtk_toolbar_insert(nsgtk_scaffolding_toolbar(g), nsgtk_scaffolding_button(g, window->currentbutton)->button, ind); gtk_tool_item_set_use_drag_window(GTK_TOOL_ITEM( nsgtk_scaffolding_button(g, window->currentbutton)->button), TRUE); gtk_drag_source_set(GTK_WIDGET( nsgtk_scaffolding_button(g, window->currentbutton)->button), GDK_BUTTON1_MASK, &entry, 1, GDK_ACTION_COPY); nsgtk_toolbar_temp_connect(g, window->currentbutton); gtk_widget_show_all(GTK_WIDGET( nsgtk_scaffolding_button(g, window->currentbutton)->button)); window->currentbutton = -1; return TRUE; }
static VALUE rg_drop_index(VALUE self, VALUE x, VALUE y) { return INT2NUM(gtk_toolbar_get_drop_index(_SELF(self), NUM2INT(x), NUM2INT(y))); }