Mercurial > emacs
changeset 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 | fd7dd167d6e5 |
children | 7e4ae0dd59c9 |
files | etc/NEWS lisp/ChangeLog lisp/menu-bar.el lisp/tool-bar.el src/ChangeLog src/dispextern.h src/gtkutil.c src/keyboard.c src/keyboard.h src/nsmenu.m src/w32menu.c src/xdisp.c |
diffstat | 12 files changed, 162 insertions(+), 119 deletions(-) [+] |
line wrap: on
line diff
--- a/etc/NEWS Fri Dec 17 10:43:03 2010 +0900 +++ b/etc/NEWS Fri Dec 17 12:04:06 2010 +0800 @@ -690,6 +690,11 @@ triplet, instead of signalling an error if the user provides a invalid input. +** Tool-bars can display separators. +Tool-bar separators are handled like menu separators in menu-bar maps, +i.e. with entries of the form `(menu-item "--")'. + +Currently, tool-bar separators are only displayed on GTK. ** Image API
--- a/lisp/ChangeLog Fri Dec 17 10:43:03 2010 +0900 +++ b/lisp/ChangeLog Fri Dec 17 12:04:06 2010 +0800 @@ -1,3 +1,9 @@ +2010-12-16 Chong Yidong <cyd@stupidchicken.com> + + * tool-bar.el (tool-bar-setup): Add separators. + + * menu-bar.el (featurep): Use menu-bar-separator. + 2010-12-16 Daiki Ueno <ueno@unixuser.org> * epa-file.el (epa-file-select-keys): Accept 'silent to inhibit
--- a/lisp/menu-bar.el Fri Dec 17 10:43:03 2010 +0900 +++ b/lisp/menu-bar.el Fri Dec 17 12:04:06 2010 +0800 @@ -523,7 +523,8 @@ ,(purecopy "Cut (kill) text in region between mark and current position"))) ;; ns-win.el said: Separate undo from cut/paste section. (if (featurep 'ns) - (define-key menu-bar-edit-menu [separator-undo] `(,(purecopy "--")))) + (define-key menu-bar-edit-menu [separator-undo] menu-bar-separator)) + (define-key menu-bar-edit-menu [undo] `(menu-item ,(purecopy "Undo") undo :enable (and (not buffer-read-only)
--- a/lisp/tool-bar.el Fri Dec 17 10:43:03 2010 +0900 +++ b/lisp/tool-bar.el Fri Dec 17 12:04:06 2010 +0800 @@ -257,23 +257,23 @@ ;;; Set up some global items. Additions/deletions up for grabs. (defun tool-bar-setup () - ;; People say it's bad to have EXIT on the tool bar, since users - ;; might inadvertently click that button. - ;;(tool-bar-add-item-from-menu 'save-buffers-kill-emacs "exit") (tool-bar-add-item-from-menu 'find-file "new" nil :label "New File" :vert-only t) (tool-bar-add-item-from-menu 'menu-find-file-existing "open" nil - :vert-only t) + :label "Open" :vert-only t) (tool-bar-add-item-from-menu 'dired "diropen" nil :vert-only t) (tool-bar-add-item-from-menu 'kill-this-buffer "close" nil :vert-only t) (tool-bar-add-item-from-menu 'save-buffer "save" nil :vert-only t + :label "Save" :visible '(or buffer-file-name (not (eq 'special (get major-mode 'mode-class))))) + (define-key-after (default-value 'tool-bar-map) [separator-1] menu-bar-separator) (tool-bar-add-item-from-menu 'undo "undo" nil :vert-only t :visible '(not (eq 'special (get major-mode 'mode-class)))) + (define-key-after (default-value 'tool-bar-map) [separator-2] menu-bar-separator) (tool-bar-add-item-from-menu (lookup-key menu-bar-edit-menu [cut]) "cut" nil :vert-only t :visible '(not (eq 'special (get major-mode @@ -284,6 +284,7 @@ "paste" nil :vert-only t :visible '(not (eq 'special (get major-mode 'mode-class)))) + (define-key-after (default-value 'tool-bar-map) [separator-3] menu-bar-separator) (tool-bar-add-item-from-menu 'nonincremental-search-forward "search" nil :label "Search") ;;(tool-bar-add-item-from-menu 'ispell-buffer "spell")
--- a/src/ChangeLog Fri Dec 17 10:43:03 2010 +0900 +++ b/src/ChangeLog Fri Dec 17 12:04:06 2010 +0800 @@ -1,3 +1,26 @@ +2010-12-17 Chong Yidong <cyd@stupidchicken.com> + + * 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. + + * keyboard.h (menu_separator_name_p): Add prototype. + + * 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. + + * nsmenu.m (name_is_separator): Function deleted. + (addItemWithWidgetValue): Use menu_separator_name_p. + + * w32menu.c (name_is_separator): Function deleted. + (add_menu_item): Use menu_separator_name_p. + 2010-12-16 Jan Djärv <jan.h.d@swipnet.se> * nsterm.m (ns_draw_window_cursor): If the cursor color is the
--- a/src/dispextern.h Fri Dec 17 10:43:03 2010 +0900 +++ b/src/dispextern.h Fri Dec 17 12:04:06 2010 +0800 @@ -2881,7 +2881,8 @@ /* The binding. */ TOOL_BAR_ITEM_BINDING, - /* Button type. One of nil, `:radio' or `:toggle'. */ + /* Button type. One of nil (default button), t (a separator), + `:radio', or `:toggle'. The latter two currently do nothing. */ TOOL_BAR_ITEM_TYPE, /* Help string. */
--- a/src/gtkutil.c Fri Dec 17 10:43:03 2010 +0900 +++ b/src/gtkutil.c Fri Dec 17 12:04:06 2010 +0800 @@ -72,6 +72,8 @@ #define remove_submenu(w) gtk_menu_item_remove_submenu ((w)) #endif +#define XG_BIN_CHILD(x) gtk_bin_get_child (GTK_BIN (x)) + /*********************************************************************** Display handling functions @@ -2128,54 +2130,6 @@ return w; } -/* Return non-zero if LABEL specifies a separator (GTK only has one - separator type) */ - -static const char* separator_names[] = { - "space", - "no-line", - "single-line", - "double-line", - "single-dashed-line", - "double-dashed-line", - "shadow-etched-in", - "shadow-etched-out", - "shadow-etched-in-dash", - "shadow-etched-out-dash", - "shadow-double-etched-in", - "shadow-double-etched-out", - "shadow-double-etched-in-dash", - "shadow-double-etched-out-dash", - 0, -}; - -static int -xg_separator_p (const char *label) -{ - if (! label) return 0; - else if (strlen (label) > 3 - && strncmp (label, "--", 2) == 0 - && label[2] != '-') - { - int i; - - label += 2; - for (i = 0; separator_names[i]; ++i) - if (strcmp (label, separator_names[i]) == 0) - return 1; - } - else - { - /* Old-style separator, maybe. It's a separator if it contains - only dashes. */ - while (*label == '-') - ++label; - if (*label == 0) return 1; - } - - return 0; -} - static int xg_detached_menus; /* Returns non-zero if there are detached menus. */ @@ -2374,7 +2328,7 @@ GtkWidget *w; if (pop_up_p && !item->contents && !item->call_data - && !xg_separator_p (item->name)) + && !menu_separator_name_p (item->name)) { char *utf8_label; /* A title for a popup. We do the same as GTK does when @@ -2387,7 +2341,7 @@ gtk_widget_set_sensitive (w, FALSE); if (utf8_label) g_free (utf8_label); } - else if (xg_separator_p (item->name)) + else if (menu_separator_name_p (item->name)) { group = NULL; /* GTK only have one separator type. */ @@ -2499,7 +2453,7 @@ static const char * xg_get_menu_item_label (GtkMenuItem *witem) { - GtkLabel *wlabel = GTK_LABEL (gtk_bin_get_child (GTK_BIN (witem))); + GtkLabel *wlabel = GTK_LABEL (XG_BIN_CHILD (witem)); return gtk_label_get_label (wlabel); } @@ -2652,7 +2606,7 @@ Rename X to B (minibuf to C-mode menu). If the X menu hasn't been invoked, the menu under B is up to date when leaving the minibuffer. */ - GtkLabel *wlabel = GTK_LABEL (gtk_bin_get_child (GTK_BIN (witem))); + GtkLabel *wlabel = GTK_LABEL (XG_BIN_CHILD (witem)); char *utf8_label = get_utf8_string (val->name); GtkWidget *submenu = gtk_menu_item_get_submenu (witem); @@ -2751,7 +2705,7 @@ const char *old_key = 0; xg_menu_item_cb_data *cb_data; - wchild = gtk_bin_get_child (GTK_BIN (w)); + wchild = XG_BIN_CHILD (w); utf8_label = get_utf8_string (val->name); utf8_key = get_utf8_string (val->key); @@ -2910,7 +2864,7 @@ if (GTK_IS_SEPARATOR_MENU_ITEM (w)) { - if (! xg_separator_p (cur->name)) + if (! menu_separator_name_p (cur->name)) break; } else if (GTK_IS_CHECK_MENU_ITEM (w)) @@ -2933,7 +2887,7 @@ GtkWidget *sub; if (cur->button_type != BUTTON_TYPE_NONE || - xg_separator_p (cur->name)) + menu_separator_name_p (cur->name)) break; xg_update_menu_item (cur, w, select_cb, highlight_cb, cl_data); @@ -3725,9 +3679,8 @@ static gboolean xg_tool_bar_menu_proxy (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 *vb = gtk_bin_get_child (GTK_BIN (wbutton)); + GtkButton *wbutton = GTK_BUTTON (XG_BIN_CHILD (XG_BIN_CHILD (toolitem))); + GtkWidget *vb = XG_BIN_CHILD (wbutton); GtkWidget *c1; GtkLabel *wlbl = GTK_LABEL (xg_get_tool_bar_widgets (vb, &c1)); GtkImage *wimage = GTK_IMAGE (c1); @@ -4180,9 +4133,9 @@ int show_label = ! EQ (style, Qimage) && ! (vert_only && horiz); int show_image = ! EQ (style, Qtext); - GtkWidget *weventbox = gtk_bin_get_child (GTK_BIN (ti)); - GtkWidget *wbutton = gtk_bin_get_child (GTK_BIN (weventbox)); - GtkWidget *vb = gtk_bin_get_child (GTK_BIN (wbutton)); + GtkWidget *weventbox = XG_BIN_CHILD (ti); + GtkWidget *wbutton = XG_BIN_CHILD (weventbox); + GtkWidget *vb = XG_BIN_CHILD (wbutton); GtkWidget *wimage; GtkWidget *wlbl = xg_get_tool_bar_widgets (vb, &wimage); GtkWidget *new_box = NULL; @@ -4330,7 +4283,6 @@ char *icon_name = NULL; Lisp_Object rtl; GtkWidget *wbutton = NULL; - GtkWidget *weventbox; Lisp_Object specified_file; const char *label = (STRINGP (PROP (TOOL_BAR_ITEM_LABEL)) ? SSDATA (PROP (TOOL_BAR_ITEM_LABEL)) : ""); @@ -4338,16 +4290,34 @@ ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), i); + /* If this is a separator, use a gtk separator item. */ + if (EQ (PROP (TOOL_BAR_ITEM_TYPE), Qt)) + { + if (ti == NULL || !GTK_IS_SEPARATOR_TOOL_ITEM (ti)) + { + if (ti) + gtk_container_remove (GTK_CONTAINER (wtoolbar), + GTK_WIDGET (ti)); + ti = gtk_separator_tool_item_new (); + gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, i); + } + gtk_widget_show (GTK_WIDGET (ti)); + continue; + } + + /* Otherwise, the tool-bar item is an ordinary button. */ + + if (ti && GTK_IS_SEPARATOR_TOOL_ITEM (ti)) + { + gtk_container_remove (GTK_CONTAINER (wtoolbar), GTK_WIDGET (ti)); + ti = NULL; + } + if (ti) - { - weventbox = gtk_bin_get_child (GTK_BIN (ti)); - wbutton = gtk_bin_get_child (GTK_BIN (weventbox)); - } - - - image = PROP (TOOL_BAR_ITEM_IMAGES); + wbutton = XG_BIN_CHILD (XG_BIN_CHILD (ti)); /* Ignore invalid image specifications. */ + image = PROP (TOOL_BAR_ITEM_IMAGES); if (!valid_image_p (image)) { if (wbutton) gtk_widget_hide (wbutton); @@ -4426,7 +4396,7 @@ { /* Insert an empty (non-image) button */ ti = xg_make_tool_item (f, NULL, NULL, "", i, 0); - gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, -1); + gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, i); } continue; } @@ -4460,17 +4430,17 @@ gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin); ti = xg_make_tool_item (f, w, &wbutton, label, i, vert_only); - gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, -1); + gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, i); gtk_widget_set_sensitive (wbutton, enabled_p); } else { - GtkWidget *vb = gtk_bin_get_child (GTK_BIN (wbutton)); + GtkWidget *vb = XG_BIN_CHILD (wbutton); GtkWidget *wimage; GtkWidget *wlbl = xg_get_tool_bar_widgets (vb, &wimage); - Pixmap old_img = (Pixmap)g_object_get_data (G_OBJECT (wimage), - XG_TOOL_BAR_IMAGE_DATA); + Pixmap old_img = (Pixmap) g_object_get_data (G_OBJECT (wimage), + XG_TOOL_BAR_IMAGE_DATA); gpointer old_stock_name = g_object_get_data (G_OBJECT (wimage), XG_TOOL_BAR_STOCK_NAME); gpointer old_icon_name = g_object_get_data (G_OBJECT (wimage),
--- a/src/keyboard.c Fri Dec 17 10:43:03 2010 +0900 +++ b/src/keyboard.c Fri Dec 17 12:04:06 2010 +0800 @@ -7464,6 +7464,54 @@ static Lisp_Object menu_bar_items_vector; static int menu_bar_items_index; + +static const char* separator_names[] = { + "space", + "no-line", + "single-line", + "double-line", + "single-dashed-line", + "double-dashed-line", + "shadow-etched-in", + "shadow-etched-out", + "shadow-etched-in-dash", + "shadow-etched-out-dash", + "shadow-double-etched-in", + "shadow-double-etched-out", + "shadow-double-etched-in-dash", + "shadow-double-etched-out-dash", + 0, +}; + +/* Return non-zero if LABEL specifies a separator. */ + +int +menu_separator_name_p (const char *label) +{ + if (!label) + return 0; + else if (strlen (label) > 3 + && strncmp (label, "--", 2) == 0 + && label[2] != '-') + { + int i; + label += 2; + for (i = 0; separator_names[i]; ++i) + if (strcmp (label, separator_names[i]) == 0) + return 1; + } + else + { + /* It's a separator if it contains only dashes. */ + while (*label == '-') + ++label; + return (*label == 0); + } + + return 0; +} + + /* Return a vector of menu items for a menu bar, appropriate to the current buffer. Each item has three elements in the vector: KEY STRING MAPLIST. @@ -8201,10 +8249,14 @@ Rule out items that aren't lists, don't start with `menu-item' or whose rest following `tool-bar-item' is not a list. */ - if (!CONSP (item) - || !EQ (XCAR (item), Qmenu_item) - || (item = XCDR (item), - !CONSP (item))) + if (!CONSP (item)) + return 0; + + /* As an exception, allow old-style menu separators. */ + if (STRINGP (XCAR (item))) + item = Fcons (XCAR (item), Qnil); + else if (!EQ (XCAR (item), Qmenu_item) + || (item = XCDR (item), !CONSP (item))) return 0; /* Create tool_bar_item_properties vector if necessary. Reset it to @@ -8234,10 +8286,18 @@ } PROP (TOOL_BAR_ITEM_CAPTION) = caption; - /* Give up if rest following the caption is not a list. */ + /* If the rest following the caption is not a list, the menu item is + either a separator, or invalid. */ item = XCDR (item); if (!CONSP (item)) - return 0; + { + if (menu_separator_name_p (SDATA (caption))) + { + PROP (TOOL_BAR_ITEM_TYPE) = Qt; + return 1; + } + return 0; + } /* Store the binding. */ PROP (TOOL_BAR_ITEM_BINDING) = XCAR (item); @@ -8270,10 +8330,10 @@ if (NILP (menu_item_eval_property (value))) return 0; } - else if (EQ (key, QChelp)) + else if (EQ (key, QChelp)) /* `:help HELP-STRING'. */ PROP (TOOL_BAR_ITEM_HELP) = value; - else if (EQ (key, QCvert_only)) + else if (EQ (key, QCvert_only)) /* `:vert-only t/nil'. */ PROP (TOOL_BAR_ITEM_VERT_ONLY) = value; else if (EQ (key, QClabel))
--- a/src/keyboard.h Fri Dec 17 10:43:03 2010 +0900 +++ b/src/keyboard.h Fri Dec 17 12:04:06 2010 +0800 @@ -492,6 +492,7 @@ extern int timers_run; +extern int menu_separator_name_p (const char *); extern int parse_menu_item (Lisp_Object, int); extern void echo_now (void);
--- a/src/nsmenu.m Fri Dec 17 10:43:03 2010 +0900 +++ b/src/nsmenu.m Fri Dec 17 12:04:06 2010 +0800 @@ -507,21 +507,6 @@ } -/* Utility (from macmenu.c): is this item a separator? */ -static int -name_is_separator ( const char *name) -{ - const char *start = name; - - /* Check if name string consists of only dashes ('-'). */ - while (*name == '-') name++; - /* Separators can also be of the form "--:TripleSuperMegaEtched" - or "--deep-shadow". We don't implement them yet, se we just treat - them like normal separators. */ - return (*name == '\0' || start + 2 == name); -} - - /* ========================================================================== Menu: class implementation @@ -624,7 +609,7 @@ NSMenuItem *item; widget_value *wv = (widget_value *)wvptr; - if (name_is_separator (wv->name)) + if (menu_separator_name_p (wv->name)) { item = [NSMenuItem separatorItem]; [self addItem: item];
--- a/src/w32menu.c Fri Dec 17 10:43:03 2010 +0900 +++ b/src/w32menu.c Fri Dec 17 12:04:06 2010 +0800 @@ -1326,20 +1326,6 @@ #endif /* !HAVE_DIALOGS */ -/* Is this item a separator? */ -static int -name_is_separator (const char *name) -{ - const char *start = name; - - /* Check if name string consists of only dashes ('-'). */ - while (*name == '-') name++; - /* Separators can also be of the form "--:TripleSuperMegaEtched" - or "--deep-shadow". We don't implement them yet, se we just treat - them like normal separators. */ - return (*name == '\0' || start + 2 == name); -} - /* UTF8: 0xxxxxxx, 110xxxxx 10xxxxxx, 1110xxxx, 10xxxxxx, 10xxxxxx */ static void utf8to16 (unsigned char * src, int len, WCHAR * dest) @@ -1388,7 +1374,7 @@ int return_value; size_t nlen, orig_len; - if (name_is_separator (wv->name)) + if (menu_separator_name_p (wv->name)) { fuFlags = MF_SEPARATOR; out_string = NULL;
--- a/src/xdisp.c Fri Dec 17 10:43:03 2010 +0900 +++ b/src/xdisp.c Fri Dec 17 12:04:06 2010 +0800 @@ -10317,6 +10317,10 @@ int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P)); int hmargin, vmargin, relief, idx, end; + /* Ignore separator items. */ + if (EQ (PROP (TOOL_BAR_ITEM_TYPE), Qt)) + continue; + /* If image is a vector, choose the image according to the button state. */ image = PROP (TOOL_BAR_ITEM_IMAGES);