summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChong Yidong <cyd@stupidchicken.com>2010-12-17 12:04:06 +0800
committerChong Yidong <cyd@stupidchicken.com>2010-12-17 12:04:06 +0800
commit4039c78625bb20cf57b434a7d395bf2473e45133 (patch)
tree729b8ce725973a7e31d769e4ab1217b517738a21 /src
parent8b358e9038806836c599da8233781b14c6bb53e7 (diff)
downloademacs-4039c78625bb20cf57b434a7d395bf2473e45133.tar.gz
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog23
-rw-r--r--src/dispextern.h3
-rw-r--r--src/gtkutil.c118
-rw-r--r--src/keyboard.c76
-rw-r--r--src/keyboard.h1
-rw-r--r--src/nsmenu.m17
-rw-r--r--src/w32menu.c16
-rw-r--r--src/xdisp.c4
8 files changed, 144 insertions, 114 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c6e0d92f1f5..f9287ea9c8f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -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
diff --git a/src/dispextern.h b/src/dispextern.h
index 27d3c1583ca..175dbe1975c 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2881,7 +2881,8 @@ enum tool_bar_item_idx
/* 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. */
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 6fd4b969819..a6cfbf002b3 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -72,6 +72,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#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 @@ make_menu_item (const char *utf8_label,
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 @@ create_menus (widget_value *data,
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 @@ create_menus (widget_value *data,
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 @@ xg_create_widget (const char *type, const char *name, FRAME_PTR f, widget_value
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 @@ xg_update_menubar (GtkWidget *menubar,
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 @@ xg_update_menu_item (widget_value *val,
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 @@ xg_update_submenu (GtkWidget *submenu,
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 @@ xg_update_submenu (GtkWidget *submenu,
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 @@ xg_get_tool_bar_widgets (GtkWidget *vb, GtkWidget **wimage)
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 @@ xg_show_toolbar_item (GtkToolItem *ti)
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 @@ update_frame_tool_bar (FRAME_PTR f)
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 @@ update_frame_tool_bar (FRAME_PTR f)
ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), i);
- if (ti)
- {
- weventbox = gtk_bin_get_child (GTK_BIN (ti));
- wbutton = gtk_bin_get_child (GTK_BIN (weventbox));
- }
-
+ /* 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;
+ }
- image = PROP (TOOL_BAR_ITEM_IMAGES);
+ if (ti)
+ 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 @@ update_frame_tool_bar (FRAME_PTR f)
{
/* 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 @@ update_frame_tool_bar (FRAME_PTR f)
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),
diff --git a/src/keyboard.c b/src/keyboard.c
index 1023d34ca79..959c57a81e3 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -7464,6 +7464,54 @@ static Lisp_Object menu_bar_one_keymap_changed_items;
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 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
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 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
}
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 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
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))
diff --git a/src/keyboard.h b/src/keyboard.h
index 7f36691a5a3..d103950fb2b 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -492,6 +492,7 @@ extern int quit_char;
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);
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 973f2c15e2f..95f651f6690 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -507,21 +507,6 @@ set_frame_menubar (struct frame *f, int first_time, int deep_p)
}
-/* 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 @@ name_is_separator ( const char *name)
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];
diff --git a/src/w32menu.c b/src/w32menu.c
index ff6bd977bea..1e700201bf2 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -1326,20 +1326,6 @@ simple_dialog_show (FRAME_PTR f, Lisp_Object contents, Lisp_Object header)
#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 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
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;
diff --git a/src/xdisp.c b/src/xdisp.c
index 1c220647ba9..41204e0a5b4 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -10317,6 +10317,10 @@ build_desired_tool_bar_string (struct frame *f)
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);