diff options
Diffstat (limited to 'lib/egg')
-rwxr-xr-x | lib/egg/egg-editable-toolbar.c | 420 | ||||
-rwxr-xr-x | lib/egg/egg-toolbar-editor.c | 18 |
2 files changed, 301 insertions, 137 deletions
diff --git a/lib/egg/egg-editable-toolbar.c b/lib/egg/egg-editable-toolbar.c index f04746164..8e76a57e2 100755 --- a/lib/egg/egg-editable-toolbar.c +++ b/lib/egg/egg-editable-toolbar.c @@ -73,6 +73,7 @@ struct EggEditableToolbarPrivate EggToolbarsModel *model; gboolean edit_mode; GtkWidget *selected_toolbar; + GtkWidget *dragged_item; }; GType @@ -167,45 +168,6 @@ find_action (EggEditableToolbar *t, } static void -drag_data_received_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time_, - EggEditableToolbar *etoolbar) -{ - int pos, toolbar_pos; - - g_return_if_fail (IS_EGG_EDITABLE_TOOLBAR (etoolbar)); - - pos = gtk_toolbar_get_drop_index (GTK_TOOLBAR (widget), x, y); - toolbar_pos = get_toolbar_position (etoolbar, widget); - - if (strcmp (selection_data->data, "separator") == 0) - { - egg_toolbars_model_add_separator (etoolbar->priv->model, - toolbar_pos, pos); - } - else - { - GdkAtom target; - char *type; - char *id; - - target = gtk_drag_dest_find_target (widget, context, NULL); - type = egg_toolbars_model_get_item_type (etoolbar->priv->model, target); - id = egg_toolbars_model_get_item_id (etoolbar->priv->model, type, - selection_data->data); - egg_toolbars_model_add_item (etoolbar->priv->model, - toolbar_pos, pos, id, type); - g_free (type); - g_free (id); - } -} - -static void drag_data_delete_cb (GtkWidget *widget, GdkDragContext *context, EggEditableToolbar *etoolbar) @@ -223,6 +185,22 @@ drag_data_delete_cb (GtkWidget *widget, } static void +drag_begin_cb (GtkWidget *widget, + GdkDragContext *context, + EggEditableToolbar *etoolbar) +{ + gtk_widget_hide (widget); +} + +static void +drag_end_cb (GtkWidget *widget, + GdkDragContext *context, + EggEditableToolbar *etoolbar) +{ + gtk_widget_show (widget); +} + +static void drag_data_get_cb (GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, @@ -251,77 +229,31 @@ drag_data_get_cb (GtkWidget *widget, } static void -remove_toolbar_cb (GtkWidget *menuitem, - EggEditableToolbar *etoolbar) +set_drag_cursor (GtkWidget *widget) { - int pos; + if (widget->window) + { + GdkCursor *cursor; + GdkPixbuf *pixbuf; - pos = get_toolbar_position (etoolbar, etoolbar->priv->selected_toolbar); - egg_toolbars_model_remove_toolbar (etoolbar->priv->model, pos); + pixbuf = gdk_pixbuf_new_from_file (CURSOR_DIR "/art/hand-open.png", NULL); + cursor = gdk_cursor_new_from_pixbuf (gdk_display_get_default (), + pixbuf, 0, 0); + gdk_window_set_cursor (widget->window, cursor); + gdk_cursor_unref (cursor); + g_object_unref (pixbuf); + } } static void -popup_toolbar_context_menu_cb (GtkWidget *toolbar, - gint x, - gint y, - gint button_number, - EggEditableToolbar *t) +unset_drag_cursor (GtkWidget *widget) { - GtkWidget *menu; - GtkWidget *item; - GtkWidget *image; - - if (t->priv->edit_mode) + if (widget->window) { - EggTbModelFlags flags; - int position; - - t->priv->selected_toolbar = toolbar; - - menu = gtk_menu_new (); - - item = gtk_image_menu_item_new_with_mnemonic (_("_Remove Toolbar")); - gtk_widget_show (item); - image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU); - gtk_widget_show (image); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (item, "activate", - G_CALLBACK (remove_toolbar_cb), - t); - - position = get_toolbar_position (t, toolbar); - flags = egg_toolbars_model_get_flags (t->priv->model, position); - if (flags && EGG_TB_MODEL_NOT_REMOVABLE) - { - gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE); - } - - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 2, - gtk_get_current_event_time ()); + gdk_window_set_cursor (widget->window, NULL); } } -static GtkWidget * -create_toolbar (EggEditableToolbar *t) -{ - GtkWidget *toolbar; - - toolbar = gtk_toolbar_new (); - gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), TRUE); - - gtk_widget_show (toolbar); - gtk_drag_dest_set (toolbar, GTK_DEST_DEFAULT_DROP, - dest_drag_types, n_dest_drag_types, - GDK_ACTION_MOVE | GDK_ACTION_COPY); - g_signal_connect (toolbar, "drag_data_received", - G_CALLBACK (drag_data_received_cb), t); - g_signal_connect (toolbar, "popup_context_menu", - G_CALLBACK (popup_toolbar_context_menu_cb), t); - - return toolbar; -} - static void set_item_drag_source (GtkWidget *item, GtkAction *action, @@ -355,47 +287,14 @@ set_item_drag_source (GtkWidget *item, } } -static void -set_drag_cursor (GtkWidget *widget) -{ - if (widget->window) - { - GdkCursor *cursor; - GdkPixbuf *pixbuf; - - pixbuf = gdk_pixbuf_new_from_file (CURSOR_DIR "/art/hand-open.png", NULL); - cursor = gdk_cursor_new_from_pixbuf (gdk_display_get_default (), - pixbuf, 0, 0); - gdk_window_set_cursor (widget->window, cursor); - gdk_cursor_unref (cursor); - g_object_unref (pixbuf); - } -} - -static void -unset_drag_cursor (GtkWidget *widget) -{ - if (widget->window) - { - gdk_window_set_cursor (widget->window, NULL); - } -} - static GtkWidget * -create_item (EggEditableToolbar *t, - EggToolbarsModel *model, - int toolbar_position, - int position) +create_item_from_action (EggEditableToolbar *t, + const char *action_name, + gboolean is_separator) { GtkWidget *item; - const char *action_name; - gboolean is_separator; GtkAction *action; - action_name = egg_toolbars_model_item_nth - (model, toolbar_position, position, - &is_separator); - if (is_separator) { item = GTK_WIDGET (gtk_separator_tool_item_new ()); @@ -411,6 +310,10 @@ create_item (EggEditableToolbar *t, gtk_widget_show (item); + g_signal_connect (item, "drag_begin", + G_CALLBACK (drag_begin_cb), t); + g_signal_connect (item, "drag_end", + G_CALLBACK (drag_end_cb), t); g_signal_connect (item, "drag_data_get", G_CALLBACK (drag_data_get_cb), t); g_signal_connect (item, "drag_data_delete", @@ -427,6 +330,248 @@ create_item (EggEditableToolbar *t, return item; } +static GtkWidget * +create_item (EggEditableToolbar *t, + EggToolbarsModel *model, + int toolbar_position, + int position) +{ + const char *action_name; + gboolean is_separator; + + action_name = egg_toolbars_model_item_nth + (model, toolbar_position, position, + &is_separator); + return create_item_from_action (t, action_name, is_separator); +} + +static gboolean +data_is_separator (const char *data) +{ + return strcmp (data, "separator") == 0; +} + +static void +set_status_pending (GdkDragContext *context, + GdkDragAction suggested_action) +{ + g_object_set_data (G_OBJECT (context), + "gtk-calendar-status-pending", + GINT_TO_POINTER (suggested_action)); +} + +static GdkDragAction +get_status_pending (GdkDragContext *context) +{ + return GPOINTER_TO_INT (g_object_get_data (G_OBJECT (context), + "gtk-calendar-status-pending")); +} + +static void +drag_data_received_cb (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time, + EggEditableToolbar *etoolbar) +{ + GdkDragAction suggested_action; + int pos, toolbar_pos; + + suggested_action = get_status_pending (context); + + if (suggested_action) + { + set_status_pending (context, 0); + etoolbar->priv->dragged_item = + create_item_from_action (etoolbar, selection_data->data, + data_is_separator (selection_data->data)); + gdk_drag_status (context, suggested_action, time); + return; + } + + pos = gtk_toolbar_get_drop_index (GTK_TOOLBAR (widget), x, y); + toolbar_pos = get_toolbar_position (etoolbar, widget); + + if (data_is_separator (selection_data->data)) + { + egg_toolbars_model_add_separator (etoolbar->priv->model, + toolbar_pos, pos); + } + else + { + GdkAtom target; + char *type; + char *id; + + target = gtk_drag_dest_find_target (widget, context, NULL); + type = egg_toolbars_model_get_item_type (etoolbar->priv->model, target); + id = egg_toolbars_model_get_item_id (etoolbar->priv->model, type, + selection_data->data); + egg_toolbars_model_add_item (etoolbar->priv->model, + toolbar_pos, pos, id, type); + g_free (type); + g_free (id); + } + + gtk_drag_finish (context, TRUE, context->action == GDK_ACTION_MOVE, time); +} + +static void +remove_toolbar_cb (GtkWidget *menuitem, + EggEditableToolbar *etoolbar) +{ + int pos; + + pos = get_toolbar_position (etoolbar, etoolbar->priv->selected_toolbar); + egg_toolbars_model_remove_toolbar (etoolbar->priv->model, pos); +} + +static void +popup_toolbar_context_menu_cb (GtkWidget *toolbar, + gint x, + gint y, + gint button_number, + EggEditableToolbar *t) +{ + GtkWidget *menu; + GtkWidget *item; + GtkWidget *image; + + if (t->priv->edit_mode) + { + EggTbModelFlags flags; + int position; + + t->priv->selected_toolbar = toolbar; + + menu = gtk_menu_new (); + + item = gtk_image_menu_item_new_with_mnemonic (_("_Remove Toolbar")); + gtk_widget_show (item); + image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU); + gtk_widget_show (image); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + g_signal_connect (item, "activate", + G_CALLBACK (remove_toolbar_cb), + t); + + position = get_toolbar_position (t, toolbar); + flags = egg_toolbars_model_get_flags (t->priv->model, position); + if (flags && EGG_TB_MODEL_NOT_REMOVABLE) + { + gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE); + } + + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 2, + gtk_get_current_event_time ()); + } +} + +static void +free_dragged_item (EggEditableToolbar *etoolbar) +{ + if (etoolbar->priv->dragged_item) + { + gtk_widget_destroy (etoolbar->priv->dragged_item); + etoolbar->priv->dragged_item = NULL; + } +} + +static gboolean +toolbar_drag_drop_cb (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time, + EggEditableToolbar *etoolbar) +{ + GdkAtom target; + + free_dragged_item (etoolbar); + + target = gtk_drag_dest_find_target (widget, context, NULL); + if (target != GDK_NONE) + { + gtk_drag_get_data (widget, context, + target, + time); + return TRUE; + } + + return FALSE; +} + +static gboolean +toolbar_drag_motion_cb (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time, + EggEditableToolbar *etoolbar) +{ + GdkAtom target; + GtkRequisition req; + + target = gtk_drag_dest_find_target (widget, context, NULL); + if (target == GDK_NONE) + { + gdk_drag_status (context, 0, time); + } + else + { + set_status_pending (context, context->suggested_action); + gtk_drag_get_data (widget, context, target, time); + } + + gtk_widget_size_request (etoolbar->priv->dragged_item, &req); + gtk_toolbar_highlight_drop_location (GTK_TOOLBAR (widget), x, y, + req.width, req.height); + + return TRUE; +} + +static void +toolbar_drag_leave_cb (GtkToolbar *toolbar, + GdkDragContext *context, + guint time, + EggEditableToolbar *etoolbar) +{ + free_dragged_item (etoolbar); + gtk_toolbar_unhighlight_drop_location (toolbar); +} + +static GtkWidget * +create_toolbar (EggEditableToolbar *t) +{ + GtkWidget *toolbar; + + toolbar = gtk_toolbar_new (); + gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), TRUE); + + gtk_widget_show (toolbar); + gtk_drag_dest_set (toolbar, 0, + dest_drag_types, n_dest_drag_types, + GDK_ACTION_MOVE | GDK_ACTION_COPY); + + g_signal_connect (toolbar, "drag_drop", + G_CALLBACK (toolbar_drag_drop_cb), t); + g_signal_connect (toolbar, "drag_motion", + G_CALLBACK (toolbar_drag_motion_cb), t); + g_signal_connect (toolbar, "drag_leave", + G_CALLBACK (toolbar_drag_leave_cb), t); + + g_signal_connect (toolbar, "drag_data_received", + G_CALLBACK (drag_data_received_cb), t); + g_signal_connect (toolbar, "popup_context_menu", + G_CALLBACK (popup_toolbar_context_menu_cb), t); + + return toolbar; +} + static void toolbar_changed_cb (EggToolbarsModel *model, int position, @@ -501,6 +646,7 @@ item_removed_cb (EggToolbarsModel *model, toolbar = get_toolbar_nth (t, toolbar_position); item = GTK_WIDGET (gtk_toolbar_get_nth_item (GTK_TOOLBAR (toolbar), position)); + g_return_if_fail (item != NULL); gtk_container_remove (GTK_CONTAINER (toolbar), item); if (egg_toolbars_model_n_items (model, toolbar_position) == 0) @@ -836,7 +982,7 @@ egg_editable_toolbar_set_drag_dest (EggEditableToolbar *etoolbar, GtkWidget *widget = get_toolbar_nth (etoolbar, i); gtk_drag_dest_unset (widget); - gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_DROP, + gtk_drag_dest_set (widget, 0, targets, n_targets, GDK_ACTION_MOVE | GDK_ACTION_COPY); } diff --git a/lib/egg/egg-toolbar-editor.c b/lib/egg/egg-toolbar-editor.c index 7cf431350..d5f8f718e 100755 --- a/lib/egg/egg-toolbar-editor.c +++ b/lib/egg/egg-toolbar-editor.c @@ -232,6 +232,20 @@ egg_toolbar_editor_new (GtkUIManager *merge, } static void +drag_begin_cb (GtkWidget *widget, + GdkDragContext *context) +{ + gtk_widget_hide (widget); +} + +static void +drag_end_cb (GtkWidget *widget, + GdkDragContext *context) +{ + gtk_widget_show (widget); +} + +static void editor_drag_data_received_cb (GtkWidget *widget, GdkDragContext *context, gint x, @@ -345,6 +359,10 @@ editor_create_item (EggToolbarEditor *editor, gtk_drag_source_set (event_box, GDK_BUTTON1_MASK, source_drag_types, n_source_drag_types, action); + g_signal_connect (event_box, "drag_begin", + G_CALLBACK (drag_begin_cb), NULL); + g_signal_connect (event_box, "drag_end", + G_CALLBACK (drag_end_cb), NULL); g_signal_connect (event_box, "drag_data_get", G_CALLBACK (drag_data_get_cb), editor); g_signal_connect (event_box, "drag_data_delete", |