changeset 75009:6ec19c8cca02

(update_frame_tool_bar): Connect create-menu-proxy with xg_tool_bar_menu_proxy. (xg_tool_bar_menu_proxy): New function. (xg_tool_bar_proxy_callback): New function.
author Jan Djärv <jan.h.d@swipnet.se>
date Sun, 31 Dec 2006 18:31:38 +0000
parents 7ef4e78d5b6a
children a2d63e852326
files src/gtkutil.c
diffstat 1 files changed, 95 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/gtkutil.c	Sun Dec 31 15:33:08 2006 +0000
+++ b/src/gtkutil.c	Sun Dec 31 18:31:38 2006 +0000
@@ -3350,6 +3350,8 @@
    get them.  */
 #define XG_TOOL_BAR_LAST_MODIFIER "emacs-tool-bar-modifier"
 
+/* The key for storing the button widget in its proxy menu item. */
+#define XG_TOOL_BAR_PROXY_BUTTON "emacs-tool-bar-proxy-button"
 
 static gboolean
 xg_tool_bar_button_cb (widget, event, user_data)
@@ -3406,6 +3408,92 @@
   kbd_buffer_store_event (&event);
 }
 
+/* Callback function invoked when a tool bar item is pressed in a detached
+   tool bar or the overflow drop down menu.
+   We just call xg_tool_bar_callback.
+   W is the menu item widget that got pressed,
+   CLIENT_DATA is an integer that is the index of the button in the
+   tool bar.  0 is the first button.  */
+
+static void
+xg_tool_bar_proxy_callback (w, client_data)
+     GtkWidget *w;
+     gpointer client_data;
+{
+  GtkWidget *wbutton = GTK_WIDGET (g_object_get_data (G_OBJECT (w),
+                                                      XG_TOOL_BAR_PROXY_BUTTON));
+  xg_tool_bar_callback (wbutton, client_data);
+}
+
+/* This callback is called when a tool item should create a proxy item,
+   such as for the overflow menu.  Also called when the tool bar is detached.
+   If we don't create a proxy menu item, the detached tool bar will be
+   blank.  */
+
+static gboolean
+xg_tool_bar_menu_proxy (toolitem, user_data)
+     GtkToolItem *toolitem;
+     gpointer user_data;
+{
+  GtkWidget *weventbox = gtk_bin_get_child (GTK_BIN (toolitem));
+  GtkButton *wbutton = GTK_BUTTON (gtk_bin_get_child (GTK_BIN (weventbox)));
+  GtkWidget *wmenuitem = gtk_image_menu_item_new ();
+  GtkWidget *wmenuimage;
+
+  if (gtk_button_get_use_stock (wbutton)) 
+    wmenuimage = gtk_image_new_from_stock (gtk_button_get_label (wbutton),
+                                           GTK_ICON_SIZE_MENU);
+  else
+    {
+      GtkImage *wimage = GTK_IMAGE (gtk_bin_get_child (GTK_BIN (wbutton)));
+      GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (wbutton));
+      GtkImageType store_type = gtk_image_get_storage_type (wimage);
+      if (store_type == GTK_IMAGE_STOCK)
+        {
+          gchar *stock_id;
+          gtk_image_get_stock (wimage, &stock_id, NULL);
+          wmenuimage = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
+        }
+      else if (store_type == GTK_IMAGE_ICON_SET)
+        {
+          GtkIconSet *icon_set;
+          gtk_image_get_icon_set (wimage, &icon_set, NULL);
+          wmenuimage = gtk_image_new_from_icon_set (icon_set,
+                                                    GTK_ICON_SIZE_MENU);
+        }
+      else if (store_type == GTK_IMAGE_PIXBUF)
+        {
+          gint width, height;
+      
+          if (settings &&
+              gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
+                                                 &width, &height))
+            {
+              GdkPixbuf *src_pixbuf, *dest_pixbuf;
+
+              src_pixbuf = gtk_image_get_pixbuf (wimage);
+              dest_pixbuf = gdk_pixbuf_scale_simple (src_pixbuf, width, height,
+                                                     GDK_INTERP_BILINEAR);
+
+              wmenuimage = gtk_image_new_from_pixbuf (dest_pixbuf);
+            }
+        }
+    }
+  if (wmenuimage)
+    gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (wmenuitem), wmenuimage);
+
+  g_signal_connect (G_OBJECT (wmenuitem),
+                    "activate",
+                    GTK_SIGNAL_FUNC (xg_tool_bar_proxy_callback),
+                    user_data);
+
+  g_object_set_data (G_OBJECT (wmenuitem), XG_TOOL_BAR_PROXY_BUTTON,
+                     (gpointer) wbutton);
+  gtk_tool_item_set_proxy_menu_item (toolitem, "Emacs toolbar item", wmenuitem);
+
+  return TRUE;
+}
+
 /* This callback is called when a tool bar is detached.  We must set
    the height of the tool bar to zero when this happens so frame sizes
    are correctly calculated.
@@ -3727,6 +3815,7 @@
               /* Insert an empty (non-image) button */
               weventbox = gtk_event_box_new ();
               wbutton = gtk_button_new ();
+              gtk_button_set_focus_on_click (GTK_BUTTON (wbutton), FALSE);
               gtk_button_set_relief (GTK_BUTTON (wbutton), GTK_RELIEF_NONE);
               gtk_container_add (GTK_CONTAINER (weventbox), wbutton);
               ti = gtk_tool_item_new ();
@@ -3741,6 +3830,7 @@
           GtkWidget *w = xg_get_image_for_pixmap (f, img, x->widget, NULL);
           gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin);
           wbutton = gtk_button_new ();
+          gtk_button_set_focus_on_click (GTK_BUTTON (wbutton), FALSE);
           gtk_button_set_relief (GTK_BUTTON (wbutton), GTK_RELIEF_NONE);
           gtk_container_add (GTK_CONTAINER (wbutton), w);
           weventbox = gtk_event_box_new ();
@@ -3751,7 +3841,11 @@
 
 
           /* The EMACS_INT cast avoids a warning. */
-          g_signal_connect (wbutton, "clicked",
+          g_signal_connect (G_OBJECT (ti), "create-menu-proxy",
+                            GTK_SIGNAL_FUNC (xg_tool_bar_menu_proxy),
+                            (gpointer) (EMACS_INT) i);
+
+          g_signal_connect (G_OBJECT (wbutton), "clicked",
                             GTK_SIGNAL_FUNC (xg_tool_bar_callback),
                             (gpointer) (EMACS_INT) i);