Mercurial > emacs
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); |