comparison src/gtkutil.c @ 111991:968255ee954a

Support for menu separators in the GTK tool-bar. * src/gtkutil.c (XG_BIN_CHILD): New macro. (xg_get_menu_item_label, xg_update_menubar) (xg_update_menu_item, xg_tool_bar_menu_proxy) (xg_show_toolbar_item, update_frame_tool_bar): Use it. (separator_names, xg_separator_p): Move to keyboard.c. (create_menus, xg_update_submenu, update_frame_tool_bar): Use menu_separator_name_p. * src/keyboard.c (parse_tool_bar_item): Allow menu separators in tool-bar maps. (menu_separator_name_p): New function, from gtkutil.c. (separator_names): Move from gtkutil.c. * src/keyboard.h (menu_separator_name_p): Add prototype. * src/nsmenu.m (name_is_separator): Function deleted. (addItemWithWidgetValue): Use menu_separator_name_p. * src/w32menu.c (name_is_separator): Function deleted. (add_menu_item): Use menu_separator_name_p.
author Chong Yidong <cyd@stupidchicken.com>
date Fri, 17 Dec 2010 12:04:06 +0800
parents 0bd93f14fcb6
children dffe14ef6b65
comparison
equal deleted inserted replaced
111990:fd7dd167d6e5 111991:968255ee954a
69 #if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION > 11 69 #if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION > 11
70 #define remove_submenu(w) gtk_menu_item_set_submenu ((w), NULL) 70 #define remove_submenu(w) gtk_menu_item_set_submenu ((w), NULL)
71 #else 71 #else
72 #define remove_submenu(w) gtk_menu_item_remove_submenu ((w)) 72 #define remove_submenu(w) gtk_menu_item_remove_submenu ((w))
73 #endif 73 #endif
74
75 #define XG_BIN_CHILD(x) gtk_bin_get_child (GTK_BIN (x))
74 76
75 77
76 /*********************************************************************** 78 /***********************************************************************
77 Display handling functions 79 Display handling functions
78 ***********************************************************************/ 80 ***********************************************************************/
2126 if (! item->enabled) gtk_widget_set_sensitive (w, FALSE); 2128 if (! item->enabled) gtk_widget_set_sensitive (w, FALSE);
2127 2129
2128 return w; 2130 return w;
2129 } 2131 }
2130 2132
2131 /* Return non-zero if LABEL specifies a separator (GTK only has one
2132 separator type) */
2133
2134 static const char* separator_names[] = {
2135 "space",
2136 "no-line",
2137 "single-line",
2138 "double-line",
2139 "single-dashed-line",
2140 "double-dashed-line",
2141 "shadow-etched-in",
2142 "shadow-etched-out",
2143 "shadow-etched-in-dash",
2144 "shadow-etched-out-dash",
2145 "shadow-double-etched-in",
2146 "shadow-double-etched-out",
2147 "shadow-double-etched-in-dash",
2148 "shadow-double-etched-out-dash",
2149 0,
2150 };
2151
2152 static int
2153 xg_separator_p (const char *label)
2154 {
2155 if (! label) return 0;
2156 else if (strlen (label) > 3
2157 && strncmp (label, "--", 2) == 0
2158 && label[2] != '-')
2159 {
2160 int i;
2161
2162 label += 2;
2163 for (i = 0; separator_names[i]; ++i)
2164 if (strcmp (label, separator_names[i]) == 0)
2165 return 1;
2166 }
2167 else
2168 {
2169 /* Old-style separator, maybe. It's a separator if it contains
2170 only dashes. */
2171 while (*label == '-')
2172 ++label;
2173 if (*label == 0) return 1;
2174 }
2175
2176 return 0;
2177 }
2178
2179 static int xg_detached_menus; 2133 static int xg_detached_menus;
2180 2134
2181 /* Returns non-zero if there are detached menus. */ 2135 /* Returns non-zero if there are detached menus. */
2182 2136
2183 int 2137 int
2372 for (item = data; item; item = item->next) 2326 for (item = data; item; item = item->next)
2373 { 2327 {
2374 GtkWidget *w; 2328 GtkWidget *w;
2375 2329
2376 if (pop_up_p && !item->contents && !item->call_data 2330 if (pop_up_p && !item->contents && !item->call_data
2377 && !xg_separator_p (item->name)) 2331 && !menu_separator_name_p (item->name))
2378 { 2332 {
2379 char *utf8_label; 2333 char *utf8_label;
2380 /* A title for a popup. We do the same as GTK does when 2334 /* A title for a popup. We do the same as GTK does when
2381 creating titles, but it does not look good. */ 2335 creating titles, but it does not look good. */
2382 group = NULL; 2336 group = NULL;
2385 gtk_menu_set_title (GTK_MENU (wmenu), utf8_label); 2339 gtk_menu_set_title (GTK_MENU (wmenu), utf8_label);
2386 w = gtk_menu_item_new_with_label (utf8_label); 2340 w = gtk_menu_item_new_with_label (utf8_label);
2387 gtk_widget_set_sensitive (w, FALSE); 2341 gtk_widget_set_sensitive (w, FALSE);
2388 if (utf8_label) g_free (utf8_label); 2342 if (utf8_label) g_free (utf8_label);
2389 } 2343 }
2390 else if (xg_separator_p (item->name)) 2344 else if (menu_separator_name_p (item->name))
2391 { 2345 {
2392 group = NULL; 2346 group = NULL;
2393 /* GTK only have one separator type. */ 2347 /* GTK only have one separator type. */
2394 w = gtk_separator_menu_item_new (); 2348 w = gtk_separator_menu_item_new ();
2395 } 2349 }
2497 /* Return the label for menu item WITEM. */ 2451 /* Return the label for menu item WITEM. */
2498 2452
2499 static const char * 2453 static const char *
2500 xg_get_menu_item_label (GtkMenuItem *witem) 2454 xg_get_menu_item_label (GtkMenuItem *witem)
2501 { 2455 {
2502 GtkLabel *wlabel = GTK_LABEL (gtk_bin_get_child (GTK_BIN (witem))); 2456 GtkLabel *wlabel = GTK_LABEL (XG_BIN_CHILD (witem));
2503 return gtk_label_get_label (wlabel); 2457 return gtk_label_get_label (wlabel);
2504 } 2458 }
2505 2459
2506 /* Return non-zero if the menu item WITEM has the text LABEL. */ 2460 /* Return non-zero if the menu item WITEM has the text LABEL. */
2507 2461
2650 back the C-mode menu. Thus we do: 2604 back the C-mode menu. Thus we do:
2651 Rename B to X (C-mode to minibuf menu) 2605 Rename B to X (C-mode to minibuf menu)
2652 Rename X to B (minibuf to C-mode menu). 2606 Rename X to B (minibuf to C-mode menu).
2653 If the X menu hasn't been invoked, the menu under B 2607 If the X menu hasn't been invoked, the menu under B
2654 is up to date when leaving the minibuffer. */ 2608 is up to date when leaving the minibuffer. */
2655 GtkLabel *wlabel = GTK_LABEL (gtk_bin_get_child (GTK_BIN (witem))); 2609 GtkLabel *wlabel = GTK_LABEL (XG_BIN_CHILD (witem));
2656 char *utf8_label = get_utf8_string (val->name); 2610 char *utf8_label = get_utf8_string (val->name);
2657 GtkWidget *submenu = gtk_menu_item_get_submenu (witem); 2611 GtkWidget *submenu = gtk_menu_item_get_submenu (witem);
2658 2612
2659 gtk_label_set_text (wlabel, utf8_label); 2613 gtk_label_set_text (wlabel, utf8_label);
2660 2614
2749 char *utf8_key; 2703 char *utf8_key;
2750 const char *old_label = 0; 2704 const char *old_label = 0;
2751 const char *old_key = 0; 2705 const char *old_key = 0;
2752 xg_menu_item_cb_data *cb_data; 2706 xg_menu_item_cb_data *cb_data;
2753 2707
2754 wchild = gtk_bin_get_child (GTK_BIN (w)); 2708 wchild = XG_BIN_CHILD (w);
2755 utf8_label = get_utf8_string (val->name); 2709 utf8_label = get_utf8_string (val->name);
2756 utf8_key = get_utf8_string (val->key); 2710 utf8_key = get_utf8_string (val->key);
2757 2711
2758 /* See if W is a menu item with a key. See make_menu_item above. */ 2712 /* See if W is a menu item with a key. See make_menu_item above. */
2759 if (GTK_IS_HBOX (wchild)) 2713 if (GTK_IS_HBOX (wchild))
2908 && ! GTK_IS_RADIO_MENU_ITEM (w)) 2862 && ! GTK_IS_RADIO_MENU_ITEM (w))
2909 first_radio = 0; 2863 first_radio = 0;
2910 2864
2911 if (GTK_IS_SEPARATOR_MENU_ITEM (w)) 2865 if (GTK_IS_SEPARATOR_MENU_ITEM (w))
2912 { 2866 {
2913 if (! xg_separator_p (cur->name)) 2867 if (! menu_separator_name_p (cur->name))
2914 break; 2868 break;
2915 } 2869 }
2916 else if (GTK_IS_CHECK_MENU_ITEM (w)) 2870 else if (GTK_IS_CHECK_MENU_ITEM (w))
2917 { 2871 {
2918 if (cur->button_type != BUTTON_TYPE_TOGGLE) 2872 if (cur->button_type != BUTTON_TYPE_TOGGLE)
2931 { 2885 {
2932 GtkMenuItem *witem = GTK_MENU_ITEM (w); 2886 GtkMenuItem *witem = GTK_MENU_ITEM (w);
2933 GtkWidget *sub; 2887 GtkWidget *sub;
2934 2888
2935 if (cur->button_type != BUTTON_TYPE_NONE || 2889 if (cur->button_type != BUTTON_TYPE_NONE ||
2936 xg_separator_p (cur->name)) 2890 menu_separator_name_p (cur->name))
2937 break; 2891 break;
2938 2892
2939 xg_update_menu_item (cur, w, select_cb, highlight_cb, cl_data); 2893 xg_update_menu_item (cur, w, select_cb, highlight_cb, cl_data);
2940 2894
2941 sub = gtk_menu_item_get_submenu (witem); 2895 sub = gtk_menu_item_get_submenu (witem);
3723 blank. */ 3677 blank. */
3724 3678
3725 static gboolean 3679 static gboolean
3726 xg_tool_bar_menu_proxy (GtkToolItem *toolitem, gpointer user_data) 3680 xg_tool_bar_menu_proxy (GtkToolItem *toolitem, gpointer user_data)
3727 { 3681 {
3728 GtkWidget *weventbox = gtk_bin_get_child (GTK_BIN (toolitem)); 3682 GtkButton *wbutton = GTK_BUTTON (XG_BIN_CHILD (XG_BIN_CHILD (toolitem)));
3729 GtkButton *wbutton = GTK_BUTTON (gtk_bin_get_child (GTK_BIN (weventbox))); 3683 GtkWidget *vb = XG_BIN_CHILD (wbutton);
3730 GtkWidget *vb = gtk_bin_get_child (GTK_BIN (wbutton));
3731 GtkWidget *c1; 3684 GtkWidget *c1;
3732 GtkLabel *wlbl = GTK_LABEL (xg_get_tool_bar_widgets (vb, &c1)); 3685 GtkLabel *wlbl = GTK_LABEL (xg_get_tool_bar_widgets (vb, &c1));
3733 GtkImage *wimage = GTK_IMAGE (c1); 3686 GtkImage *wimage = GTK_IMAGE (c1);
3734 GtkWidget *wmenuitem = gtk_image_menu_item_new_with_label 3687 GtkWidget *wmenuitem = gtk_image_menu_item_new_with_label
3735 (gtk_label_get_text (wlbl)); 3688 (gtk_label_get_text (wlbl));
4178 int horiz = both_horiz || text_image; 4131 int horiz = both_horiz || text_image;
4179 int vert_only = ! gtk_tool_item_get_is_important (ti); 4132 int vert_only = ! gtk_tool_item_get_is_important (ti);
4180 int show_label = ! EQ (style, Qimage) && ! (vert_only && horiz); 4133 int show_label = ! EQ (style, Qimage) && ! (vert_only && horiz);
4181 int show_image = ! EQ (style, Qtext); 4134 int show_image = ! EQ (style, Qtext);
4182 4135
4183 GtkWidget *weventbox = gtk_bin_get_child (GTK_BIN (ti)); 4136 GtkWidget *weventbox = XG_BIN_CHILD (ti);
4184 GtkWidget *wbutton = gtk_bin_get_child (GTK_BIN (weventbox)); 4137 GtkWidget *wbutton = XG_BIN_CHILD (weventbox);
4185 GtkWidget *vb = gtk_bin_get_child (GTK_BIN (wbutton)); 4138 GtkWidget *vb = XG_BIN_CHILD (wbutton);
4186 GtkWidget *wimage; 4139 GtkWidget *wimage;
4187 GtkWidget *wlbl = xg_get_tool_bar_widgets (vb, &wimage); 4140 GtkWidget *wlbl = xg_get_tool_bar_widgets (vb, &wimage);
4188 GtkWidget *new_box = NULL; 4141 GtkWidget *new_box = NULL;
4189 4142
4190 if (GTK_IS_VBOX (vb) && horiz) 4143 if (GTK_IS_VBOX (vb) && horiz)
4328 GtkStockItem stock_item; 4281 GtkStockItem stock_item;
4329 char *stock_name = NULL; 4282 char *stock_name = NULL;
4330 char *icon_name = NULL; 4283 char *icon_name = NULL;
4331 Lisp_Object rtl; 4284 Lisp_Object rtl;
4332 GtkWidget *wbutton = NULL; 4285 GtkWidget *wbutton = NULL;
4333 GtkWidget *weventbox;
4334 Lisp_Object specified_file; 4286 Lisp_Object specified_file;
4335 const char *label = (STRINGP (PROP (TOOL_BAR_ITEM_LABEL)) 4287 const char *label = (STRINGP (PROP (TOOL_BAR_ITEM_LABEL))
4336 ? SSDATA (PROP (TOOL_BAR_ITEM_LABEL)) : ""); 4288 ? SSDATA (PROP (TOOL_BAR_ITEM_LABEL)) : "");
4337 int vert_only = ! NILP (PROP (TOOL_BAR_ITEM_VERT_ONLY)); 4289 int vert_only = ! NILP (PROP (TOOL_BAR_ITEM_VERT_ONLY));
4338 4290
4339 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), i); 4291 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), i);
4340 4292
4293 /* If this is a separator, use a gtk separator item. */
4294 if (EQ (PROP (TOOL_BAR_ITEM_TYPE), Qt))
4295 {
4296 if (ti == NULL || !GTK_IS_SEPARATOR_TOOL_ITEM (ti))
4297 {
4298 if (ti)
4299 gtk_container_remove (GTK_CONTAINER (wtoolbar),
4300 GTK_WIDGET (ti));
4301 ti = gtk_separator_tool_item_new ();
4302 gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, i);
4303 }
4304 gtk_widget_show (GTK_WIDGET (ti));
4305 continue;
4306 }
4307
4308 /* Otherwise, the tool-bar item is an ordinary button. */
4309
4310 if (ti && GTK_IS_SEPARATOR_TOOL_ITEM (ti))
4311 {
4312 gtk_container_remove (GTK_CONTAINER (wtoolbar), GTK_WIDGET (ti));
4313 ti = NULL;
4314 }
4315
4341 if (ti) 4316 if (ti)
4342 { 4317 wbutton = XG_BIN_CHILD (XG_BIN_CHILD (ti));
4343 weventbox = gtk_bin_get_child (GTK_BIN (ti)); 4318
4344 wbutton = gtk_bin_get_child (GTK_BIN (weventbox)); 4319 /* Ignore invalid image specifications. */
4345 }
4346
4347
4348 image = PROP (TOOL_BAR_ITEM_IMAGES); 4320 image = PROP (TOOL_BAR_ITEM_IMAGES);
4349
4350 /* Ignore invalid image specifications. */
4351 if (!valid_image_p (image)) 4321 if (!valid_image_p (image))
4352 { 4322 {
4353 if (wbutton) gtk_widget_hide (wbutton); 4323 if (wbutton) gtk_widget_hide (wbutton);
4354 continue; 4324 continue;
4355 } 4325 }
4424 gtk_widget_hide_all (GTK_WIDGET (ti)); 4394 gtk_widget_hide_all (GTK_WIDGET (ti));
4425 else 4395 else
4426 { 4396 {
4427 /* Insert an empty (non-image) button */ 4397 /* Insert an empty (non-image) button */
4428 ti = xg_make_tool_item (f, NULL, NULL, "", i, 0); 4398 ti = xg_make_tool_item (f, NULL, NULL, "", i, 0);
4429 gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, -1); 4399 gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, i);
4430 } 4400 }
4431 continue; 4401 continue;
4432 } 4402 }
4433 } 4403 }
4434 4404
4458 (gpointer)img->pixmap); 4428 (gpointer)img->pixmap);
4459 } 4429 }
4460 4430
4461 gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin); 4431 gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin);
4462 ti = xg_make_tool_item (f, w, &wbutton, label, i, vert_only); 4432 ti = xg_make_tool_item (f, w, &wbutton, label, i, vert_only);
4463 gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, -1); 4433 gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, i);
4464 gtk_widget_set_sensitive (wbutton, enabled_p); 4434 gtk_widget_set_sensitive (wbutton, enabled_p);
4465 } 4435 }
4466 else 4436 else
4467 { 4437 {
4468 GtkWidget *vb = gtk_bin_get_child (GTK_BIN (wbutton)); 4438 GtkWidget *vb = XG_BIN_CHILD (wbutton);
4469 GtkWidget *wimage; 4439 GtkWidget *wimage;
4470 GtkWidget *wlbl = xg_get_tool_bar_widgets (vb, &wimage); 4440 GtkWidget *wlbl = xg_get_tool_bar_widgets (vb, &wimage);
4471 4441
4472 Pixmap old_img = (Pixmap)g_object_get_data (G_OBJECT (wimage), 4442 Pixmap old_img = (Pixmap) g_object_get_data (G_OBJECT (wimage),
4473 XG_TOOL_BAR_IMAGE_DATA); 4443 XG_TOOL_BAR_IMAGE_DATA);
4474 gpointer old_stock_name = g_object_get_data (G_OBJECT (wimage), 4444 gpointer old_stock_name = g_object_get_data (G_OBJECT (wimage),
4475 XG_TOOL_BAR_STOCK_NAME); 4445 XG_TOOL_BAR_STOCK_NAME);
4476 gpointer old_icon_name = g_object_get_data (G_OBJECT (wimage), 4446 gpointer old_icon_name = g_object_get_data (G_OBJECT (wimage),
4477 XG_TOOL_BAR_ICON_NAME); 4447 XG_TOOL_BAR_ICON_NAME);
4478 gtk_label_set_text (GTK_LABEL (wlbl), label); 4448 gtk_label_set_text (GTK_LABEL (wlbl), label);