diff --git a/app/widgets/gimpcolormapeditor.c b/app/widgets/gimpcolormapeditor.c index 8a2152822a..c27f5af97f 100644 --- a/app/widgets/gimpcolormapeditor.c +++ b/app/widgets/gimpcolormapeditor.c @@ -58,7 +58,11 @@ static void gimp_colormap_editor_color_update (GimpColorDialog *dialog GimpColorDialogState state, GimpColormapEditor *editor); -static void gimp_colormap_editor_entry_popup (GimpEditor *editor); +static gboolean gimp_colormap_editor_entry_button_press (GtkWidget *widget, + GdkEvent *event, + gpointer user_data); +static gboolean gimp_colormap_editor_entry_popup (GtkWidget *widget, + gpointer user_data); static void gimp_colormap_editor_color_clicked (GimpColormapEditor *editor, GimpPaletteEntry *entry, GdkModifierType state); @@ -177,15 +181,18 @@ gimp_colormap_editor_set_context (GimpDocked *docked, gtk_box_pack_start (GTK_BOX (editor), editor->selection, TRUE, TRUE, 0); gtk_widget_show (editor->selection); - g_signal_connect_swapped (editor->selection, "color-context", - G_CALLBACK (gimp_colormap_editor_entry_popup), - editor); g_signal_connect_swapped (editor->selection, "color-clicked", G_CALLBACK (gimp_colormap_editor_color_clicked), editor); g_signal_connect_swapped (editor->selection, "color-activated", G_CALLBACK (gimp_colormap_editor_edit_color), editor); + g_signal_connect (editor->selection, "button-press-event", + G_CALLBACK (gimp_colormap_editor_entry_button_press), + editor); + g_signal_connect (editor->selection, "popup-menu", + G_CALLBACK (gimp_colormap_editor_entry_popup), + editor); } } @@ -361,10 +368,38 @@ gimp_colormap_editor_color_update (GimpColorDialog *dialog, } } -static void -gimp_colormap_editor_entry_popup (GimpEditor *editor) +static gboolean +gimp_colormap_editor_entry_button_press (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) { - gimp_editor_popup_menu (editor, NULL, NULL); + if (gdk_event_triggers_context_menu (event)) + { + gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (user_data), event); + return GDK_EVENT_STOP; + } + + return GDK_EVENT_PROPAGATE; +} + +static gboolean +gimp_colormap_editor_entry_popup (GtkWidget *widget, + gpointer user_data) +{ + GimpColormapEditor *editor = GIMP_COLORMAP_EDITOR (user_data); + GimpColormapSelection *selection = GIMP_COLORMAP_SELECTION (widget); + GimpPaletteEntry *selected; + GdkRectangle rect; + + selected = gimp_colormap_selection_get_selected_entry (selection); + if (!selected) + return GDK_EVENT_PROPAGATE; + + gimp_colormap_selection_get_entry_rect (selection, selected, &rect); + return gimp_editor_popup_menu_at_rect (GIMP_EDITOR (editor), + gtk_widget_get_window (widget), + &rect, GDK_GRAVITY_CENTER, GDK_GRAVITY_NORTH_WEST, + NULL); } static void diff --git a/app/widgets/gimpcolormapselection.c b/app/widgets/gimpcolormapselection.c index 7d582fac0c..22db9804b7 100644 --- a/app/widgets/gimpcolormapselection.c +++ b/app/widgets/gimpcolormapselection.c @@ -58,7 +58,6 @@ enum enum { - COLOR_CONTEXT, COLOR_CLICKED, COLOR_ACTIVATED, LAST_SIGNAL @@ -106,9 +105,6 @@ static void gimp_colormap_selection_entry_selected (GimpPaletteView *vi static void gimp_colormap_selection_entry_activated (GimpPaletteView *view, GimpPaletteEntry *entry, GimpColormapSelection *selection); -static void gimp_colormap_selection_entry_context (GimpPaletteView *view, - GimpPaletteEntry *entry, - GimpColormapSelection *selection); static void gimp_colormap_selection_color_dropped (GimpPaletteView *view, GimpPaletteEntry *entry, const GimpRGB *color, @@ -137,14 +133,6 @@ gimp_colormap_selection_class_init (GimpColormapSelectionClass* klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - signals[COLOR_CONTEXT] = - g_signal_new ("color-context", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GimpColormapSelectionClass, color_context), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - G_TYPE_POINTER); signals[COLOR_CLICKED] = g_signal_new ("color-clicked", G_TYPE_FROM_CLASS (klass), @@ -215,9 +203,6 @@ gimp_colormap_selection_init (GimpColormapSelection *selection) g_signal_connect (selection->view, "entry-activated", G_CALLBACK (gimp_colormap_selection_entry_activated), selection); - g_signal_connect (selection->view, "entry-context", - G_CALLBACK (gimp_colormap_selection_entry_context), - selection); g_signal_connect (selection->view, "color-dropped", G_CALLBACK (gimp_colormap_selection_color_dropped), selection); @@ -471,6 +456,32 @@ gimp_colormap_selection_max_index (GimpColormapSelection *selection) return MAX (0, gimp_image_get_colormap_size (image) - 1); } +GimpPaletteEntry * +gimp_colormap_selection_get_selected_entry (GimpColormapSelection *selection) +{ + g_return_val_if_fail (GIMP_IS_COLORMAP_SELECTION (selection), NULL); + + return gimp_palette_view_get_selected_entry (GIMP_PALETTE_VIEW (selection->view)); +} + +void +gimp_colormap_selection_get_entry_rect (GimpColormapSelection *selection, + GimpPaletteEntry *entry, + GdkRectangle *rect) +{ + GtkAllocation allocation; + + g_return_if_fail (GIMP_IS_COLORMAP_SELECTION (selection)); + g_return_if_fail (entry); + g_return_if_fail (rect); + + gimp_palette_view_get_entry_rect (GIMP_PALETTE_VIEW (selection->view), + entry, rect); + gtk_widget_get_allocation (GTK_WIDGET (selection), &allocation); + /* rect->x += allocation.x; */ + /* rect->y += allocation.y; */ +} + /* private functions */ @@ -603,16 +614,6 @@ gimp_colormap_selection_entry_activated (GimpPaletteView *view, g_signal_emit (selection, signals[COLOR_ACTIVATED], 0, entry); } -static void -gimp_colormap_selection_entry_context (GimpPaletteView *view, - GimpPaletteEntry *entry, - GimpColormapSelection *selection) -{ - gimp_colormap_selection_set_index (selection, entry->position, NULL); - - g_signal_emit (selection, signals[COLOR_CONTEXT], 0, entry); -} - static void gimp_colormap_selection_color_dropped (GimpPaletteView *view, GimpPaletteEntry *entry, diff --git a/app/widgets/gimpcolormapselection.h b/app/widgets/gimpcolormapselection.h index e524d1b42f..d500ba1bbb 100644 --- a/app/widgets/gimpcolormapselection.h +++ b/app/widgets/gimpcolormapselection.h @@ -54,8 +54,6 @@ struct _GimpColormapSelectionClass { GtkBoxClass parent_class; - void (* color_context) (GimpColormapSelection *selection, - GimpPaletteEntry *entry); void (* color_clicked) (GimpColormapSelection *selection, GimpPaletteEntry *entry, GdkModifierType state); @@ -76,6 +74,11 @@ gboolean gimp_colormap_selection_set_index (GimpColormapSelection *selection gint gimp_colormap_selection_max_index (GimpColormapSelection *selection); +GimpPaletteEntry * gimp_colormap_selection_get_selected_entry (GimpColormapSelection *selection); + +void gimp_colormap_selection_get_entry_rect (GimpColormapSelection *selection, + GimpPaletteEntry *entry, + GdkRectangle *rect); #endif /* __GIMP_COLORMAP_SELECTION_H__ */ diff --git a/app/widgets/gimpcontainereditor.c b/app/widgets/gimpcontainereditor.c index cbfe1d037b..ae5f59277c 100644 --- a/app/widgets/gimpcontainereditor.c +++ b/app/widgets/gimpcontainereditor.c @@ -93,12 +93,6 @@ static void gimp_container_editor_activate_item (GtkWidget *widge GimpViewable *viewable, gpointer insert_data, GimpContainerEditor *editor); -static void gimp_container_editor_context_item (GtkWidget *widget, - GimpViewable *viewable, - gpointer insert_data, - GimpContainerEditor *editor); -static void gimp_container_editor_real_context_item(GimpContainerEditor *editor, - GimpViewable *viewable); static GtkWidget * gimp_container_editor_get_preview (GimpDocked *docked, GimpContext *context, @@ -136,7 +130,6 @@ gimp_container_editor_class_init (GimpContainerEditorClass *klass) klass->select_item = NULL; klass->activate_item = NULL; - klass->context_item = gimp_container_editor_real_context_item; g_object_class_install_property (object_class, PROP_VIEW_TYPE, g_param_spec_enum ("view-type", @@ -288,9 +281,9 @@ gimp_container_editor_constructed (GObject *object) g_signal_connect_object (editor->view, "activate-item", G_CALLBACK (gimp_container_editor_activate_item), editor, 0); - g_signal_connect_object (editor->view, "context-item", - G_CALLBACK (gimp_container_editor_context_item), - editor, 0); + /* g_signal_connect_object (editor->view, "context-item", XXX maybe listen to popup-menu? */ + /* G_CALLBACK (gimp_container_editor_context_item), */ + /* editor, 0); */ { GimpObject *object = gimp_context_get_by_type (editor->priv->context, @@ -461,30 +454,6 @@ gimp_container_editor_activate_item (GtkWidget *widget, klass->activate_item (editor, viewable); } -static void -gimp_container_editor_context_item (GtkWidget *widget, - GimpViewable *viewable, - gpointer insert_data, - GimpContainerEditor *editor) -{ - GimpContainerEditorClass *klass = GIMP_CONTAINER_EDITOR_GET_CLASS (editor); - - if (klass->context_item) - klass->context_item (editor, viewable); -} - -static void -gimp_container_editor_real_context_item (GimpContainerEditor *editor, - GimpViewable *viewable) -{ - GimpContainer *container = gimp_container_view_get_container (editor->view); - - if (viewable && gimp_container_have (container, GIMP_OBJECT (viewable))) - { - gimp_editor_popup_menu (GIMP_EDITOR (editor->view), NULL, NULL); - } -} - static GtkWidget * gimp_container_editor_get_preview (GimpDocked *docked, GimpContext *context, diff --git a/app/widgets/gimpcontainereditor.h b/app/widgets/gimpcontainereditor.h index 728d604e30..3d16dc4de2 100644 --- a/app/widgets/gimpcontainereditor.h +++ b/app/widgets/gimpcontainereditor.h @@ -50,8 +50,6 @@ struct _GimpContainerEditorClass GimpViewable *object); void (* activate_item) (GimpContainerEditor *editor, GimpViewable *object); - void (* context_item) (GimpContainerEditor *editor, - GimpViewable *object); }; diff --git a/app/widgets/gimpcontainericonview.c b/app/widgets/gimpcontainericonview.c index ecc89176a6..c0e9d0c221 100644 --- a/app/widgets/gimpcontainericonview.c +++ b/app/widgets/gimpcontainericonview.c @@ -241,68 +241,25 @@ gimp_container_icon_view_unmap (GtkWidget *widget) GTK_WIDGET_CLASS (parent_class)->unmap (widget); } -static void -gimp_container_icon_view_menu_position (GtkMenu *menu, - gint *x, - gint *y, - gpointer data) -{ - GimpContainerIconView *icon_view = GIMP_CONTAINER_ICON_VIEW (data); - GtkWidget *widget = GTK_WIDGET (icon_view->view); - GtkAllocation allocation; -#if 0 - GtkTreeIter selected_iter; -#endif - - gtk_widget_get_allocation (widget, &allocation); - - gdk_window_get_origin (gtk_widget_get_window (widget), x, y); - - if (! gtk_widget_get_has_window (widget)) - { - *x += allocation.x; - *y += allocation.y; - } - -#if 0 - if (gimp_container_icon_view_get_selected_single (icon_view, &selected_iter)) - { - GtkTreePath *path; - GdkRectangle cell_rect; - gint center; - - path = gtk_tree_model_get_path (icon_view->model, &selected_iter); - gtk_icon_view_get_cell_area (icon_view->view, path, - icon_view->main_column, &cell_rect); - gtk_tree_path_free (path); - - center = cell_rect.y + cell_rect.height / 2; - center = CLAMP (center, 0, allocation.height); - - *x += allocation.width / 2; - *y += center; - } - else -#endif - { - GtkStyleContext *style = gtk_widget_get_style_context (widget); - GtkBorder border; - - gtk_style_context_get_border (style, 0, &border); - - *x += border.left; - *y += border.top; - } - - gimp_menu_position (menu, x, y); -} - static gboolean gimp_container_icon_view_popup_menu (GtkWidget *widget) { - return gimp_editor_popup_menu (GIMP_EDITOR (widget), - gimp_container_icon_view_menu_position, - widget); + GimpContainerIconView *icon_view = GIMP_CONTAINER_ICON_VIEW (widget); + GtkTreeIter iter; + GtkTreePath *path; + GdkRectangle rect; + + if (!gimp_container_icon_view_get_selected_single (icon_view, &iter)) + return FALSE; + + path = gtk_tree_model_get_path (icon_view->model, &iter); + gtk_icon_view_get_cell_rect (icon_view->view, path, NULL, &rect); + gtk_tree_path_free (path); + + return gimp_editor_popup_menu_at_rect (GIMP_EDITOR (widget), + gtk_widget_get_window (GTK_WIDGET (icon_view->view)), + &rect, GDK_GRAVITY_CENTER, GDK_GRAVITY_NORTH_WEST, + NULL); } GtkWidget * @@ -638,7 +595,8 @@ gimp_container_icon_view_button_press (GtkWidget *widget, GdkEventButton *bevent, GimpContainerIconView *icon_view) { - GtkTreePath *path; + GimpContainerView *container_view = GIMP_CONTAINER_VIEW (icon_view); + GtkTreePath *path; icon_view->priv->dnd_renderer = NULL; @@ -658,10 +616,32 @@ gimp_container_icon_view_button_press (GtkWidget *widget, icon_view->priv->dnd_renderer = renderer; + if (gdk_event_triggers_context_menu ((GdkEvent *) bevent)) + { + /* If the clicked item is not selected, it becomes the new + * selection. Otherwise, we use the current selection. This + * allows to not break multiple selection when right-clicking. + */ + if (! gimp_container_view_is_item_selected (container_view, renderer->viewable)) + gimp_container_view_item_selected (container_view, renderer->viewable); + /* Show the context menu. */ + if (gimp_container_view_get_container (container_view)) + gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (icon_view), (GdkEvent *) bevent); + } + g_object_unref (renderer); gtk_tree_path_free (path); } + else + { + if (gdk_event_triggers_context_menu ((GdkEvent *) bevent)) + { + gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (icon_view), (GdkEvent *) bevent); + } + + return TRUE; + } return FALSE; } diff --git a/app/widgets/gimpcontainertreeview.c b/app/widgets/gimpcontainertreeview.c index af1c335a4d..dd8c57d282 100644 --- a/app/widgets/gimpcontainertreeview.c +++ b/app/widgets/gimpcontainertreeview.c @@ -420,64 +420,26 @@ gimp_container_tree_view_unmap (GtkWidget *widget) GTK_WIDGET_CLASS (parent_class)->unmap (widget); } -static void -gimp_container_tree_view_menu_position (GtkMenu *menu, - gint *x, - gint *y, - gpointer data) -{ - GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (data); - GtkWidget *widget = GTK_WIDGET (tree_view->view); - GtkAllocation allocation; - GtkTreeIter selected_iter; - - gtk_widget_get_allocation (widget, &allocation); - - gdk_window_get_origin (gtk_widget_get_window (widget), x, y); - - if (! gtk_widget_get_has_window (widget)) - { - *x += allocation.x; - *y += allocation.y; - } - - if (gimp_container_tree_view_get_selected_single (tree_view, &selected_iter)) - { - GtkTreePath *path; - GdkRectangle cell_rect; - gint center; - - path = gtk_tree_model_get_path (tree_view->model, &selected_iter); - gtk_tree_view_get_cell_area (tree_view->view, path, - tree_view->main_column, &cell_rect); - gtk_tree_path_free (path); - - center = cell_rect.y + cell_rect.height / 2; - center = CLAMP (center, 0, allocation.height); - - *x += allocation.width / 2; - *y += center; - } - else - { - GtkStyleContext *style = gtk_widget_get_style_context (widget); - GtkBorder border; - - gtk_style_context_get_border (style, 0, &border); - - *x += border.left; - *y += border.top; - } - - gimp_menu_position (menu, x, y); -} - static gboolean gimp_container_tree_view_popup_menu (GtkWidget *widget) { - return gimp_editor_popup_menu (GIMP_EDITOR (widget), - gimp_container_tree_view_menu_position, - widget); + GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (widget); + GtkTreeIter iter; + GtkTreePath *path; + GdkRectangle rect; + + if (!gimp_container_tree_view_get_selected_single (tree_view, &iter)) + return FALSE; + + path = gtk_tree_model_get_path (tree_view->model, &iter); + gtk_tree_view_get_cell_area (tree_view->view, path, + tree_view->main_column, &rect); + gtk_tree_path_free (path); + + return gimp_editor_popup_menu_at_rect (GIMP_EDITOR (widget), + gtk_tree_view_get_bin_window (tree_view->view), + &rect, GDK_GRAVITY_CENTER, GDK_GRAVITY_NORTH_WEST, + NULL); } GtkWidget * @@ -1484,7 +1446,7 @@ gimp_container_tree_view_button (GtkWidget *widget, gimp_container_view_item_selected (container_view, renderer->viewable); /* Show the context menu. */ if (gimp_container_view_get_container (container_view)) - gimp_container_view_item_context (container_view, renderer->viewable); + gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (tree_view), (GdkEvent *) bevent); } else if (bevent->button == 1) { diff --git a/app/widgets/gimpcontainerview.c b/app/widgets/gimpcontainerview.c index e6bbed0e4d..eac2c20020 100644 --- a/app/widgets/gimpcontainerview.c +++ b/app/widgets/gimpcontainerview.c @@ -48,7 +48,6 @@ enum SELECT_ITEM, SELECT_ITEMS, ACTIVATE_ITEM, - CONTEXT_ITEM, LAST_SIGNAL }; @@ -191,21 +190,9 @@ gimp_container_view_default_init (GimpContainerViewInterface *iface) GIMP_TYPE_OBJECT, G_TYPE_POINTER); - view_signals[CONTEXT_ITEM] = - g_signal_new ("context-item", - G_TYPE_FROM_INTERFACE (iface), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GimpContainerViewInterface, context_item), - NULL, NULL, - gimp_marshal_VOID__OBJECT_POINTER, - G_TYPE_NONE, 2, - GIMP_TYPE_OBJECT, - G_TYPE_POINTER); - iface->select_item = NULL; iface->select_items = NULL; iface->activate_item = NULL; - iface->context_item = NULL; iface->set_container = gimp_container_view_real_set_container; iface->set_context = gimp_container_view_real_set_context; @@ -709,27 +696,6 @@ gimp_container_view_activate_item (GimpContainerView *view, viewable, insert_data); } -void -gimp_container_view_context_item (GimpContainerView *view, - GimpViewable *viewable) -{ - GimpContainerViewPrivate *private; - gpointer insert_data; - - g_return_if_fail (GIMP_IS_CONTAINER_VIEW (view)); - g_return_if_fail (GIMP_IS_VIEWABLE (viewable)); - - private = GIMP_CONTAINER_VIEW_GET_PRIVATE (view); - - if (gimp_container_frozen (private->container)) - return; - - insert_data = g_hash_table_lookup (private->item_hash, viewable); - - g_signal_emit (view, view_signals[CONTEXT_ITEM], 0, - viewable, insert_data); -} - gpointer gimp_container_view_lookup (GimpContainerView *view, GimpViewable *viewable) @@ -975,16 +941,6 @@ gimp_container_view_item_activated (GimpContainerView *view, gimp_container_view_activate_item (view, viewable); } -void -gimp_container_view_item_context (GimpContainerView *view, - GimpViewable *viewable) -{ - g_return_if_fail (GIMP_IS_CONTAINER_VIEW (view)); - g_return_if_fail (GIMP_IS_VIEWABLE (viewable)); - - gimp_container_view_context_item (view, viewable); -} - void gimp_container_view_set_property (GObject *object, guint property_id, diff --git a/app/widgets/gimpcontainerview.h b/app/widgets/gimpcontainerview.h index 0b5ad9ba01..3094710ac0 100644 --- a/app/widgets/gimpcontainerview.h +++ b/app/widgets/gimpcontainerview.h @@ -54,9 +54,6 @@ struct _GimpContainerViewInterface void (* activate_item) (GimpContainerView *view, GimpViewable *object, gpointer insert_data); - void (* context_item) (GimpContainerView *view, - GimpViewable *object, - gpointer insert_data); /* virtual functions */ void (* set_container) (GimpContainerView *view, @@ -133,8 +130,6 @@ gboolean gimp_container_view_select_item (GimpContainerView *v GimpViewable *viewable); void gimp_container_view_activate_item (GimpContainerView *view, GimpViewable *viewable); -void gimp_container_view_context_item (GimpContainerView *view, - GimpViewable *viewable); gint gimp_container_view_get_selected (GimpContainerView *view, GList **items, GList **items_data); @@ -156,8 +151,6 @@ gboolean gimp_container_view_multi_selected (GimpContainerView *v GList *paths); void gimp_container_view_item_activated (GimpContainerView *view, GimpViewable *item); -void gimp_container_view_item_context (GimpContainerView *view, - GimpViewable *item); /* convenience functions */ diff --git a/app/widgets/gimpeditor.c b/app/widgets/gimpeditor.c index c84cd5718e..a70ddccc3a 100644 --- a/app/widgets/gimpeditor.c +++ b/app/widgets/gimpeditor.c @@ -482,6 +482,28 @@ gimp_editor_popup_menu_at_pointer (GimpEditor *editor, return FALSE; } +gboolean +gimp_editor_popup_menu_at_rect (GimpEditor *editor, + GdkWindow *window, + const GdkRectangle *rect, + GdkGravity rect_anchor, + GdkGravity menu_anchor, + const GdkEvent *trigger_event) +{ + g_return_val_if_fail (GIMP_IS_EDITOR (editor), FALSE); + + if (editor->priv->ui_manager && editor->priv->ui_path) + { + gimp_ui_manager_update (editor->priv->ui_manager, editor->priv->popup_data); + gimp_ui_manager_ui_popup_at_rect (editor->priv->ui_manager, editor->priv->ui_path, + window, rect, rect_anchor, menu_anchor, + trigger_event, NULL, NULL); + return TRUE; + } + + return FALSE; +} + GtkWidget * gimp_editor_add_button (GimpEditor *editor, const gchar *icon_name, diff --git a/app/widgets/gimpeditor.h b/app/widgets/gimpeditor.h index 0ba60b96eb..1cecb2e5f0 100644 --- a/app/widgets/gimpeditor.h +++ b/app/widgets/gimpeditor.h @@ -61,6 +61,12 @@ gboolean gimp_editor_popup_menu (GimpEditor *editor, gboolean gimp_editor_popup_menu_at_pointer (GimpEditor *editor, const GdkEvent *trigger_event); +gboolean gimp_editor_popup_menu_at_rect (GimpEditor *editor, + GdkWindow *window, + const GdkRectangle *rect, + GdkGravity rect_anchor, + GdkGravity menu_anchor, + const GdkEvent *trigger_event); GtkWidget * gimp_editor_add_button (GimpEditor *editor, const gchar *icon_name, diff --git a/app/widgets/gimpitemtreeview.c b/app/widgets/gimpitemtreeview.c index 5f163db569..8850fe380a 100644 --- a/app/widgets/gimpitemtreeview.c +++ b/app/widgets/gimpitemtreeview.c @@ -134,9 +134,6 @@ static gboolean gimp_item_tree_view_select_items (GimpContainerView *view, static void gimp_item_tree_view_activate_item (GimpContainerView *view, GimpViewable *item, gpointer insert_data); -static void gimp_item_tree_view_context_item (GimpContainerView *view, - GimpViewable *item, - gpointer insert_data); static gboolean gimp_item_tree_view_drop_possible (GimpContainerTreeView *view, GimpDndType src_type, @@ -307,7 +304,6 @@ gimp_item_tree_view_view_iface_init (GimpContainerViewInterface *iface) iface->select_item = gimp_item_tree_view_select_item; iface->select_items = gimp_item_tree_view_select_items; iface->activate_item = gimp_item_tree_view_activate_item; - iface->context_item = gimp_item_tree_view_context_item; } static void @@ -1182,17 +1178,6 @@ gimp_item_tree_view_activate_item (GimpContainerView *view, } } -static void -gimp_item_tree_view_context_item (GimpContainerView *view, - GimpViewable *item, - gpointer insert_data) -{ - if (parent_view_iface->context_item) - parent_view_iface->context_item (view, item, insert_data); - - gimp_editor_popup_menu (GIMP_EDITOR (view), NULL, NULL); -} - static gboolean gimp_item_tree_view_drop_possible (GimpContainerTreeView *tree_view, GimpDndType src_type, diff --git a/app/widgets/gimppaletteeditor.c b/app/widgets/gimppaletteeditor.c index 6abee86f45..2335dad337 100644 --- a/app/widgets/gimppaletteeditor.c +++ b/app/widgets/gimppaletteeditor.c @@ -106,9 +106,11 @@ static void palette_editor_entry_selected (GimpPaletteView *view, static void palette_editor_entry_activated (GimpPaletteView *view, GimpPaletteEntry *entry, GimpPaletteEditor *editor); -static void palette_editor_entry_context (GimpPaletteView *view, - GimpPaletteEntry *entry, - GimpPaletteEditor *editor); +static gboolean palette_editor_button_press_event (GtkWidget *widget, + GdkEvent *event, + gpointer user_data); +static gboolean palette_editor_popup_menu (GtkWidget *widget, + gpointer user_data); static void palette_editor_color_dropped (GimpPaletteView *view, GimpPaletteEntry *entry, const GimpRGB *color, @@ -219,12 +221,15 @@ gimp_palette_editor_init (GimpPaletteEditor *editor) g_signal_connect (editor->view, "entry-activated", G_CALLBACK (palette_editor_entry_activated), editor); - g_signal_connect (editor->view, "entry-context", - G_CALLBACK (palette_editor_entry_context), - editor); g_signal_connect (editor->view, "color-dropped", G_CALLBACK (palette_editor_color_dropped), editor); + g_signal_connect (editor->view, "button-press-event", + G_CALLBACK (palette_editor_button_press_event), + editor); + g_signal_connect (editor->view, "popup-menu", + G_CALLBACK (palette_editor_popup_menu), + editor); gimp_dnd_viewable_dest_add (editor->view, GIMP_TYPE_PALETTE, @@ -825,12 +830,39 @@ palette_editor_entry_activated (GimpPaletteView *view, } } -static void -palette_editor_entry_context (GimpPaletteView *view, - GimpPaletteEntry *entry, - GimpPaletteEditor *editor) +static gboolean +palette_editor_button_press_event (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) { - gimp_editor_popup_menu (GIMP_EDITOR (editor), NULL, NULL); + GimpPaletteEditor *editor = GIMP_PALETTE_EDITOR (user_data); + + if (gdk_event_triggers_context_menu (event)) + { + gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (editor), event); + return GDK_EVENT_STOP; + } + + return GDK_EVENT_PROPAGATE; +} + +static gboolean +palette_editor_popup_menu (GtkWidget *widget, + gpointer user_data) +{ + GimpPaletteEditor *editor = GIMP_PALETTE_EDITOR (user_data); + GimpPaletteEntry *selected; + GdkRectangle rect; + + selected = gimp_palette_view_get_selected_entry (GIMP_PALETTE_VIEW (editor->view)); + if (!selected) + return GDK_EVENT_PROPAGATE; + + gimp_palette_view_get_entry_rect (GIMP_PALETTE_VIEW (editor->view), selected, &rect); + return gimp_editor_popup_menu_at_rect (GIMP_EDITOR (editor), + gtk_widget_get_window (GTK_WIDGET (editor->view)), + &rect, GDK_GRAVITY_CENTER, GDK_GRAVITY_NORTH_WEST, + NULL); } static void diff --git a/app/widgets/gimppaletteview.c b/app/widgets/gimppaletteview.c index 6b10d05056..ee6168c99f 100644 --- a/app/widgets/gimppaletteview.c +++ b/app/widgets/gimppaletteview.c @@ -42,7 +42,6 @@ enum ENTRY_CLICKED, ENTRY_SELECTED, ENTRY_ACTIVATED, - ENTRY_CONTEXT, COLOR_DROPPED, LAST_SIGNAL }; @@ -119,15 +118,6 @@ gimp_palette_view_class_init (GimpPaletteViewClass *klass) G_TYPE_NONE, 1, G_TYPE_POINTER); - view_signals[ENTRY_CONTEXT] = - g_signal_new ("entry-context", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GimpPaletteViewClass, entry_context), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - view_signals[COLOR_DROPPED] = g_signal_new ("color-dropped", G_TYPE_FROM_CLASS (klass), @@ -226,7 +216,9 @@ gimp_palette_view_button_press (GtkWidget *widget, if (entry != view->selected) gimp_palette_view_select_entry (view, entry); - g_signal_emit (view, view_signals[ENTRY_CONTEXT], 0, entry); + /* Usually the menu is provided by a GimpEditor. + * Make sure it's also run by returning FALSE here */ + return FALSE; } else if (bevent->button == 1) { @@ -404,6 +396,39 @@ gimp_palette_view_select_entry (GimpPaletteView *view, g_signal_emit (view, view_signals[ENTRY_SELECTED], 0, view->selected); } +GimpPaletteEntry * +gimp_palette_view_get_selected_entry (GimpPaletteView *view) +{ + g_return_val_if_fail (GIMP_IS_PALETTE_VIEW (view), NULL); + + return view->selected; +} + +void +gimp_palette_view_get_entry_rect (GimpPaletteView *view, + GimpPaletteEntry *entry, + GdkRectangle *rect) +{ + GimpViewRendererPalette *renderer; + GtkAllocation allocation; + gint row, col; + + g_return_if_fail (GIMP_IS_PALETTE_VIEW (view)); + g_return_if_fail (entry); + g_return_if_fail (rect); + + gtk_widget_get_allocation (GTK_WIDGET (view), &allocation); + + renderer = GIMP_VIEW_RENDERER_PALETTE (GIMP_VIEW (view)->renderer); + row = entry->position / renderer->columns; + col = entry->position % renderer->columns; + + rect->x = allocation.x + col * renderer->cell_width; + rect->y = allocation.y + row * renderer->cell_height; + rect->width = renderer->cell_width; + rect->height = renderer->cell_height; +} + /* private functions */ diff --git a/app/widgets/gimppaletteview.h b/app/widgets/gimppaletteview.h index 68de628fc6..9c215e43e5 100644 --- a/app/widgets/gimppaletteview.h +++ b/app/widgets/gimppaletteview.h @@ -66,5 +66,11 @@ GType gimp_palette_view_get_type (void) G_GNUC_CONST; void gimp_palette_view_select_entry (GimpPaletteView *view, GimpPaletteEntry *entry); +GimpPaletteEntry * gimp_palette_view_get_selected_entry (GimpPaletteView *view); + +void gimp_palette_view_get_entry_rect (GimpPaletteView *view, + GimpPaletteEntry *entry, + GdkRectangle *rect); + #endif /* __GIMP_PALETTE_VIEW_H__ */ diff --git a/app/widgets/gimpuimanager.c b/app/widgets/gimpuimanager.c index be7cd4ad46..c3300cb87d 100644 --- a/app/widgets/gimpuimanager.c +++ b/app/widgets/gimpuimanager.c @@ -801,6 +801,46 @@ gimp_ui_manager_ui_popup_at_pointer (GimpUIManager *manager, gtk_menu_popup_at_pointer (GTK_MENU (menu), trigger_event); } +void +gimp_ui_manager_ui_popup_at_rect (GimpUIManager *manager, + const gchar *ui_path, + GdkWindow *window, + const GdkRectangle *rect, + GdkGravity rect_anchor, + GdkGravity menu_anchor, + const GdkEvent *trigger_event, + GDestroyNotify popdown_func, + gpointer popdown_data) +{ + GtkWidget *menu; + + g_return_if_fail (GIMP_IS_UI_MANAGER (manager)); + g_return_if_fail (ui_path != NULL); + + menu = gimp_ui_manager_get_widget (manager, ui_path); + + if (GTK_IS_MENU_ITEM (menu)) + menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu)); + + if (! menu) + return; + + g_return_if_fail (GTK_IS_MENU (menu)); + + if (popdown_func && popdown_data) + { + g_object_set_data_full (G_OBJECT (manager), "popdown-data", + popdown_data, popdown_func); + g_signal_connect (menu, "selection-done", + G_CALLBACK (gimp_ui_manager_delete_popdown_data), + manager); + } + + gtk_menu_popup_at_rect (GTK_MENU (menu), window, + rect, rect_anchor, menu_anchor, + trigger_event); +} + /* private functions */ diff --git a/app/widgets/gimpuimanager.h b/app/widgets/gimpuimanager.h index 6c508d283b..2b6cabf5f6 100644 --- a/app/widgets/gimpuimanager.h +++ b/app/widgets/gimpuimanager.h @@ -148,6 +148,16 @@ void gimp_ui_manager_ui_popup_at_pointer const GdkEvent *trigger_event, GDestroyNotify popdown_func, gpointer popdown_data); +void gimp_ui_manager_ui_popup_at_rect + (GimpUIManager *manager, + const gchar *ui_path, + GdkWindow *window, + const GdkRectangle *rect, + GdkGravity rect_anchor, + GdkGravity menu_anchor, + const GdkEvent *trigger_event, + GDestroyNotify popdown_func, + gpointer popdown_data); #endif /* __GIMP_UI_MANAGER_H__ */