This file is part of GNU Emacs.
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
+/*
By Adrian Robert, based on code from original nsmenu.m (Carl Edman,
Christian Limpach, Scott Bender, Christophe de Dinechin) and code in the
Carbon version by Yamamoto Mitsuharu. */
+/* This should be the first include, as it may set up #defines affecting
+ interpretation of even the system includes. */
#include "config.h"
+
#include "lisp.h"
#include "window.h"
#include "buffer.h"
#include "nsmenu_common.c"
#endif
-extern struct widget_value;
-
extern Lisp_Object Qundefined, Qmenu_enable, Qmenu_bar_update_hook;
extern Lisp_Object QCtoggle, QCradio;
Qoverriding_local_map, Qoverriding_terminal_local_map;
extern long context_menu_value;
-EmacsMenu *mainMenu, *svcsMenu;
+EmacsMenu *mainMenu, *svcsMenu, *dockMenu;
+
+/* Nonzero means a menu is currently active. */
+static int popup_activated_flag;
/* NOTE: toolbar implementation is at end,
following complete menu implementation. */
========================================================================== */
-/*23: PENDING: not currently used, but should normalize with other terms. */
+/*23: FIXME: not currently used, but should normalize with other terms. */
void
x_activate_menubar (struct frame *f)
{
}
+int
+popup_activated ()
+{
+ return popup_activated_flag;
+}
+
+
/* --------------------------------------------------------------------------
Update menubar. Three cases:
1) deep_p = 0, submenu = nil: Fresh switch onto a frame -- either set up
}
set_buffer_internal_1 (XBUFFER (buffer));
- /* PENDING: for some reason this is not needed in other terms,
- but some menu updates call Info-extract-pointer which causes
- abort-on-error if waiting-for-input. Needs further investigation. */
+ /* TODO: for some reason this is not needed in other terms,
+ but some menu updates call Info-extract-pointer which causes
+ abort-on-error if waiting-for-input. Needs further investigation. */
owfi = waiting_for_input;
waiting_for_input = 0;
if (NILP (string))
break;
- /* PENDING: we'd like to only parse the needed submenu, but this
- was causing crashes in the _common parsing code.. need to make
- sure proper initialization done.. */
-/* if (submenu && strcmp (submenuTitle, SDATA (string)))
+ /* FIXME: we'd like to only parse the needed submenu, but this
+ was causing crashes in the _common parsing code.. need to make
+ sure proper initialization done.. */
+/* if (submenu && strcmp (submenuTitle, SDATA (string)))
continue; */
submenu_start[i] = menu_items_used;
set_buffer_internal_1 (prev);
/* Compare the new menu items with previous, and leave off if no change */
- /* PENDING: following other terms here, but seems like this should be
- done before parse stage 2 above, since its results aren't used */
+ /* FIXME: following other terms here, but seems like this should be
+ done before parse stage 2 above, since its results aren't used */
if (previous_menu_items_used
&& (!submenu || (submenu && submenu == last_submenu))
&& menu_items_used == previous_menu_items_used)
{
for (i = 0; i < previous_menu_items_used; i++)
- /* PENDING: this ALWAYS fails on Buffers menu items.. something
- about their strings causes them to change every time, so we
- double-check failures */
+ /* FIXME: this ALWAYS fails on Buffers menu items.. something
+ about their strings causes them to change every time, so we
+ double-check failures */
if (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i]))
if (!(STRINGP (previous_items[i])
&& STRINGP (XVECTOR (menu_items)->contents[i])
}
}
/* The menu items are different, so store them in the frame */
- /* PENDING: this is not correct for single-submenu case */
+ /* FIXME: this is not correct for single-submenu case */
f->menu_bar_vector = menu_items;
f->menu_bar_items_used = menu_items_used;
{
for (i = 0; i<n; i++)
{
- string = XVECTOR (items)->contents[4*i+1];
+ string = AREF (items, 4*i+1);
- if (!string)
+ if (EQ (string, make_number (0))) // FIXME: Why??? --Stef
continue;
if (NILP (string))
if (previous_strings[i][0])
return [NSString stringWithFormat: @"%c", tpos[2]];
}
-- (id <NSMenuItem>)addItemWithWidgetValue: (void *)wvptr
+
+- (NSMenuItem *)addItemWithWidgetValue: (void *)wvptr
{
- id <NSMenuItem> item;
+ NSMenuItem *item;
widget_value *wv = (widget_value *)wvptr;
if (name_is_separator (wv->name))
/* add new contents */
for (; wv != NULL; wv = wv->next)
{
- id <NSMenuItem> item = [self addItemWithWidgetValue: wv];
+ NSMenuItem *item = [self addItemWithWidgetValue: wv];
if (wv->contents)
{
- (EmacsMenu *)addSubmenuWithTitle: (char *)title forFrame: (struct frame *)f
{
NSString *titleStr = [NSString stringWithUTF8String: title];
- id <NSMenuItem> item =
- [self addItemWithTitle: titleStr
- action: nil /*@selector (menuDown:) */
- keyEquivalent: @""];
+ NSMenuItem *item = [self addItemWithTitle: titleStr
+ action: nil /*@selector (menuDown:) */
+ keyEquivalent: @""];
EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: titleStr frame: f];
[self setSubmenu: submenu forItem: item];
[submenu release];
[NSMenu popUpContextMenu: self withEvent: event forView: view];
retVal = context_menu_value;
context_menu_value = 0;
- return retVal > 0 ?
- find_and_return_menu_selection (f, keymaps, (void *)retVal) : Qnil;
+ return retVal > 0
+ ? find_and_return_menu_selection (f, keymaps, (void *)retVal)
+ : Qnil;
}
@end /* EmacsMenu */
}
else
{ /* no position given */
- /* PENDING: if called during dump, we need to stop precomputation of
+ /* FIXME: if called during dump, we need to stop precomputation of
key equivalents (see below) because the keydefs in ns-win.el have
not been loaded yet. */
if (noninteractive)
specpdl_count2 = SPECPDL_INDEX ();
#if 0
- /*PENDING: a couple of one-line differences prevent reuse */
+ /* FIXME: a couple of one-line differences prevent reuse */
wv = digest_single_submenu (0, menu_items_used, Qnil);
#else
{
/* If this item has a null value,
make the call_data null so that it won't display a box
when the mouse is on it. */
- wv->call_data =
- !NILP (def) ? (void *) &XVECTOR (menu_items)->contents[i] : 0;
+ wv->call_data
+ = !NILP (def) ? (void *) &XVECTOR (menu_items)->contents[i] : 0;
wv->enabled = !NILP (enable);
if (NILP (type))
#endif
wv_title->name = (char *) SDATA (title);
- wv_title->enabled = NULL;
+ wv_title->enabled = NO;
wv_title->button_type = BUTTON_TYPE_NONE;
wv_title->help = Qnil;
wv_title->next = wv_sep;
free_menubar_widget_value_tree (first_wv);
unbind_to (specpdl_count2, Qnil);
+ popup_activated_flag = 1;
tem = [pmenu runMenuAt: p forFrame: f keymaps: keymaps];
+ popup_activated_flag = 0;
[[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
UNBLOCK_INPUT;
+ discard_menu_items ();
unbind_to (specpdl_count, Qnil);
UNGCPRO;
int i;
EmacsToolbar *toolbar = [FRAME_NS_VIEW (f) toolbar];
- if (NILP (f->tool_bar_lines) || !INTEGERP (f->tool_bar_lines))
- return;
-
[toolbar clearActive];
/* update EmacsToolbar as in GtkUtils, build items list */
helpText: (char *)help enabled: (BOOL)enabled
{
/* 1) come up w/identifier */
- NSString *identifier =
- [NSString stringWithFormat: @"%u", [img hash]];
+ NSString *identifier
+ = [NSString stringWithFormat: @"%u", [img hash]];
/* 2) create / reuse item */
NSToolbarItem *item = [identifierToItem objectForKey: identifier];
p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2;
dialog = [[EmacsDialogPanel alloc] initFromContents: contents
isQuestion: isQ];
-
+ popup_activated_flag = 1;
tem = [dialog runDialogAt: p];
+ popup_activated_flag = 0;
[dialog close];
NSSize spacing = {SPACER, SPACER};
NSRect area;
char this_cmd_name[80];
- id cell, tem;
+ id cell;
static NSImageView *imgView;
static FlippedView *contentView;
- (BOOL)windowShouldClose: (id)sender
{
- [NSApp stopModalWithCode: Qnil];
+ [NSApp stopModalWithCode: XHASH (Qnil)]; // FIXME: BIG UGLY HACK!!
return NO;
}
[cell setTarget: self];
[cell setAction: @selector (clicked: )];
[cell setTitle: [NSString stringWithUTF8String: str]];
- [cell setTag: (int)val];
+ [cell setTag: XHASH (val)]; // FIXME: BIG UGLY HACK!!
[cell setBordered: YES];
[cell setEnabled: YES];
- clicked: sender
{
NSArray *sellist = nil;
- Lisp_Object seltag;
+ EMACS_INT seltag;
sellist = [sender selectedCells];
if ([sellist count]<1)
return self;
- seltag = (Lisp_Object)[[sellist objectAtIndex: 0] tag];
- if (! EQ (seltag, Qundefined))
+ seltag = [[sellist objectAtIndex: 0] tag];
+ if (seltag != XHASH (Qundefined)) // FIXME: BIG UGLY HACK!!
[NSApp stopModalWithCode: seltag];
return self;
}
}
[NSApp endModalSession: session];
- return (Lisp_Object)ret;
+ { // FIXME: BIG UGLY HACK!!!
+ Lisp_Object tmp;
+ *(EMACS_INT*)(&tmp) = ret;
+ return tmp;
+ }
}
@end
========================================================================== */
DEFUN ("ns-reset-menu", Fns_reset_menu, Sns_reset_menu, 0, 0, 0,
- "Cause the NS menu to be re-calculated.")
+ doc: /* Cause the NS menu to be re-calculated. */)
()
{
set_frame_menubar (SELECTED_FRAME (), 1, 0);
DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0,
- "Pop up a deck-of-cards menu and return user's selection.\n\
-POSITION is a position specification. This is either a mouse button event\n\
-or a list ((XOFFSET YOFFSET) WINDOW)\n\
-where XOFFSET and YOFFSET are positions in pixels from the top left\n\
-corner of WINDOW's frame. (WINDOW may be a frame object instead of a window.)\n\
-This controls the position of the center of the first line\n\
-in the first pane of the menu, not the top left of the menu as a whole.\n\
-\n\
-MENU is a specifier for a menu. For the simplest case, MENU is a keymap.\n\
-The menu items come from key bindings that have a menu string as well as\n\
-a definition; actually, the \"definition\" in such a key binding looks like\n\
-\(STRING . REAL-DEFINITION). To give the menu a title, put a string into\n\
-the keymap as a top-level element.\n\n\
-You can also use a list of keymaps as MENU.\n\
- Then each keymap makes a separate pane.\n\
-When MENU is a keymap or a list of keymaps, the return value\n\
-is a list of events.\n\n\
-Alternatively, you can specify a menu of multiple panes\n\
- with a list of the form (TITLE PANE1 PANE2...),\n\
-where each pane is a list of form (TITLE ITEM1 ITEM2...).\n\
-Each ITEM is normally a cons cell (STRING . VALUE);\n\
-but a string can appear as an item--that makes a nonselectable line\n\
-in the menu.\n\
-With this form of menu, the return value is VALUE from the chosen item.")
+ doc: /* Pop up a deck-of-cards menu and return user's selection.
+POSITION is a position specification. This is either a mouse button event
+or a list ((XOFFSET YOFFSET) WINDOW)
+where XOFFSET and YOFFSET are positions in pixels from the top left
+corner of WINDOW. (WINDOW may be a window or a frame object.)
+This controls the position of the top left of the menu as a whole.
+If POSITION is t, it means to use the current mouse position.
+
+MENU is a specifier for a menu. For the simplest case, MENU is a keymap.
+The menu items come from key bindings that have a menu string as well as
+a definition; actually, the \"definition\" in such a key binding looks like
+\(STRING . REAL-DEFINITION). To give the menu a title, put a string into
+the keymap as a top-level element.
+
+If REAL-DEFINITION is nil, that puts a nonselectable string in the menu.
+Otherwise, REAL-DEFINITION should be a valid key binding definition.
+
+You can also use a list of keymaps as MENU.
+ Then each keymap makes a separate pane.
+
+When MENU is a keymap or a list of keymaps, the return value is the
+list of events corresponding to the user's choice. Note that
+`x-popup-menu' does not actually execute the command bound to that
+sequence of events.
+
+Alternatively, you can specify a menu of multiple panes
+ with a list of the form (TITLE PANE1 PANE2...),
+where each pane is a list of form (TITLE ITEM1 ITEM2...).
+Each ITEM is normally a cons cell (STRING . VALUE);
+but a string can appear as an item--that makes a nonselectable line
+in the menu.
+With this form of menu, the return value is VALUE from the chosen item. */)
(position, menu)
Lisp_Object position, menu;
{
return ns_popup_dialog (position, contents, header);
}
+DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0,
+ doc: /* Return t if a menu or popup dialog is active. */)
+ ()
+{
+ return popup_activated () ? Qt : Qnil;
+}
/* ==========================================================================
defsubr (&Sx_popup_menu);
defsubr (&Sx_popup_dialog);
defsubr (&Sns_reset_menu);
+ defsubr (&Smenu_or_popup_active_p);
staticpro (&menu_items);
menu_items = Qnil;