Add MacOSX methods.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@25785 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Fred Kiefer 2007-12-25 14:53:45 +00:00
parent aa79c640dc
commit 8557f009df
3 changed files with 237 additions and 76 deletions

View file

@ -1,3 +1,8 @@
2007-12-25 Fred Kiefer <FredKiefer@gmx.de>
* Headers/AppKit/NSMenu.h:
* Source/NSMenu.m: Add MacOSX methods and delegate ivar.
2007-12-23 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSMenuItem.m: Add KVB for enable.

View file

@ -38,6 +38,7 @@
@class NSString;
@class NSEvent;
@class NSFont;
@class NSMatrix;
@class NSPopUpButton;
@class NSPopUpButtonCell;
@ -335,16 +336,19 @@
NSMenu *_superMenu;
NSMenu *_attachedMenu;
NSMutableArray *_notifications;
BOOL _changedMessagesEnabled;
BOOL _autoenable;
BOOL _needsSizing;
BOOL _is_tornoff;
id _delegate;
// GNUstepExtra category
NSPopUpButtonCell *_popUpButtonCell;
BOOL _transient;
BOOL _horizontal;
char _pad1[2];
struct GSMenuFlags {
unsigned int changedMessagesEnabled: 1;
unsigned int autoenable: 1;
unsigned int needsSizing: 1;
unsigned int is_tornoff: 1;
unsigned int transient: 1;
unsigned int horizontal: 1;
unsigned int unused: 26;
} _menu;
@private
NSWindow *_aWindow;
@ -356,15 +360,24 @@
/** Returns the memory allocation zone used to create instances of this class.
*/
+ (NSZone*) menuZone;
+ (void) popUpContextMenu: (NSMenu*)menu
withEvent: (NSEvent*)event
forView: (NSView*)view;
/** Specifies the memory allocation zone used to create instances of this class.
*/
+ (void) setMenuZone: (NSZone*)zone;
+ (void) popUpContextMenu: (NSMenu*)menu
withEvent: (NSEvent*)event
forView: (NSView*)view;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_3, GS_API_LATEST)
+ (void) popUpContextMenu: (NSMenu *)menu
withEvent: (NSEvent *)event
forView: (NSView *)view
withFont: (NSFont *)font;
#endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_2, GS_API_LATEST)
+ (BOOL) menuBarVisible;
+ (void) setMenuBarVisible: (BOOL)flag;
#endif
/** Add newItem to the menu.
*/
@ -406,6 +419,14 @@
*/
- (BOOL) autoenablesItems;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_0, MAC_OS_X_VERSION_10_1)
- (id) contextMenuRepresentation;
#endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_3, GS_API_LATEST)
- (id) delegate;
#endif
/* Displaying Context-Sensitive Help */
- (void) helpRequested: (NSEvent*)event;
@ -504,6 +525,10 @@
*/
- (NSPoint) locationForSubmenu: (NSMenu*)aSubmenu;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
- (float)menuBarHeight;
#endif
- (BOOL) menuChangedMessagesEnabled;
/** Return the NSView that is used for drawing
@ -545,6 +570,14 @@
*/
- (void) setAutoenablesItems: (BOOL)flag;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_0, MAC_OS_X_VERSION_10_1)
- (void) setContextMenuRepresentation: (id)representation;
#endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_3, GS_API_LATEST)
- (void) setDelegate:(id) delegate;
#endif
- (void) setMenuChangedMessagesEnabled: (BOOL)flag;
/** Set the View that should be used to display the menu.
@ -580,6 +613,10 @@
*/
- (void) setSupermenu: (NSMenu *)supermenu;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_0, MAC_OS_X_VERSION_10_1)
- (void) setTearOffMenuRepresentation: (id)representation;
#endif
/** Change the title of the menu.
*/
- (void) setTitle: (NSString*)aTitle;
@ -593,6 +630,10 @@
*/
- (NSMenu*) supermenu;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_0, MAC_OS_X_VERSION_10_1)
- (id) tearOffMenuRepresentation;
#endif
/** Returns the current title.
*/
- (NSString*) title;
@ -619,6 +660,21 @@
- (BOOL) validateMenuItem: (id<NSMenuItem>)menuItem;
@end
#if OS_API_VERSION(MAC_OS_X_VERSION_10_3, GS_API_LATEST)
@interface NSObject (NSMenuDelegate)
- (void) menuNeedsUpdate: (NSMenu *)menu;
- (int) numberOfItemsInMenu: (NSMenu *)menu;
- (BOOL) menu: (NSMenu *)menu
updateItem: (NSMenuItem *)item
atIndex: (int)index
shouldCancel: (BOOL)shouldCancel;
- (BOOL) menuHasKeyEquivalent: (NSMenu *)menu
forEvent: (NSEvent *)event
target: (id *)target
action: (SEL *)action;
@end
#endif
#if OS_API_VERSION(GS_API_NONE, GS_API_NONE)
@interface NSObject (NSMenuActionResponder)
- (BOOL) validateMenuItem: (id<NSMenuItem>)aMenuItem;

View file

@ -100,8 +100,8 @@
the code is supposed to know when it is using window A or B.
But it will probably only work correctly when
window A correspond to _transient == NO
window B correspond to _transient == YES
window A correspond to transient == NO
window B correspond to transient == YES
*/
@ -118,6 +118,7 @@ static NSZone *menuZone = NULL;
static NSString *NSMenuLocationsKey = @"NSMenuLocations";
static NSString *NSEnqueuedMenuMoveName = @"EnqueuedMoveNotificationName";
static NSNotificationCenter *nc;
static BOOL menuBarVisible = YES;
@interface NSMenu (GNUstepPrivate)
@ -218,7 +219,7 @@ static NSNotificationCenter *nc;
appItem = (NSMenuItem *)[self itemWithTitle: appTitle];
appMenu = [appItem submenu];
if (_horizontal == YES)
if (_menu.horizontal == YES)
{
NSMutableArray *itemsToMove;
NSImage *ti;
@ -340,7 +341,7 @@ static NSNotificationCenter *nc;
{
NSPoint origin;
if (_horizontal == YES)
if (_menu.horizontal == YES)
{
origin = NSMakePoint (0, [[NSScreen mainScreen] frame].size.height
- [_aWindow frame].size.height);
@ -386,7 +387,7 @@ static NSNotificationCenter *nc;
*/
- (void) _updateUserDefaults: (id) notification
{
if (_horizontal == NO)
if (_menu.horizontal == NO)
{
NSString *key;
@ -437,7 +438,7 @@ static NSNotificationCenter *nc;
- (void) _rightMouseDisplay: (NSEvent*)theEvent
{
if (_horizontal == NO)
if (_menu.horizontal == NO)
{
[self displayTransient];
[_view mouseDown: theEvent];
@ -473,6 +474,16 @@ static NSNotificationCenter *nc;
return menuZone;
}
+ (BOOL) menuBarVisible
{
return menuBarVisible;
}
+ (void) setMenuBarVisible: (BOOL)flag
{
menuBarVisible = flag;
}
/*
*
*/
@ -514,11 +525,11 @@ static NSNotificationCenter *nc;
// Create an array to store our menu items.
_items = [[NSMutableArray alloc] init];
_changedMessagesEnabled = YES;
_menu.changedMessagesEnabled = YES;
_notifications = [[NSMutableArray alloc] init];
_needsSizing = YES;
_menu.needsSizing = YES;
// According to the spec, menus do autoenable by default.
_autoenable = YES;
_menu.autoenable = YES;
/* Please note that we own all this menu network of objects. So,
@ -592,7 +603,7 @@ static NSNotificationCenter *nc;
}
[_items insertObject: newItem atIndex: index];
_needsSizing = YES;
_menu.needsSizing = YES;
// Create the notification for the menu representation.
d = [NSDictionary
@ -603,7 +614,7 @@ static NSNotificationCenter *nc;
object: self
userInfo: d];
if (_changedMessagesEnabled)
if (_menu.changedMessagesEnabled)
[nc postNotification: inserted];
else
[_notifications addObject: inserted];
@ -664,7 +675,7 @@ static NSNotificationCenter *nc;
[anItem setMenu: nil];
[_items removeObjectAtIndex: index];
_needsSizing = YES;
_menu.needsSizing = YES;
d = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: index]
forKey: @"NSMenuItemIndex"];
@ -673,7 +684,7 @@ static NSNotificationCenter *nc;
object: self
userInfo: d];
if (_changedMessagesEnabled)
if (_menu.changedMessagesEnabled)
[nc postNotification: removed];
else
[_notifications addObject: removed];
@ -688,7 +699,7 @@ static NSNotificationCenter *nc;
if (-1 == index)
return;
_needsSizing = YES;
_menu.needsSizing = YES;
d = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: index]
forKey: @"NSMenuItemIndex"];
@ -697,7 +708,7 @@ static NSNotificationCenter *nc;
object: self
userInfo: d];
if (_changedMessagesEnabled)
if (_menu.changedMessagesEnabled)
[nc postNotification: changed];
else
[_notifications addObject: changed];
@ -865,8 +876,8 @@ static NSNotificationCenter *nc;
- (NSMenu *) attachedMenu
{
if (_attachedMenu && _transient
&& !_attachedMenu->_transient)
if (_attachedMenu && _menu.transient
&& !_attachedMenu->_menu.transient)
return nil;
return _attachedMenu;
@ -895,7 +906,7 @@ static NSNotificationCenter *nc;
- (BOOL) isTornOff
{
return _is_tornoff;
return _menu.is_tornoff;
}
- (NSPoint) locationForSubmenu: (NSMenu*)aSubmenu
@ -919,18 +930,60 @@ static NSNotificationCenter *nc;
//
- (void) setAutoenablesItems: (BOOL)flag
{
_autoenable = flag;
_menu.autoenable = flag;
}
- (BOOL) autoenablesItems
{
return _autoenable;
return _menu.autoenable;
}
- (void) update
{
if (_delegate)
{
if ([_delegate respondsToSelector:@selector(menuNeedsUpdate:)])
{
[_delegate menuNeedsUpdate:self];
}
else if ([_delegate respondsToSelector:@selector(numberOfItemsInMenu:)])
{
int num;
num = [_delegate numberOfItemsInMenu: self];
if (num > 0)
{
BOOL cont = YES;
int i = 0;
int curr = [self numberOfItems];
while (num < curr)
{
[self removeItemAtIndex: --curr];
}
while (num > curr)
{
[self insertItemWithTitle: @""
action: NULL
keyEquivalent: @""
atIndex: curr++];
}
// FIXME: Should only process the items we display
while (cont && i < num)
{
cont = [_delegate menu: self
updateItem: [self itemAtIndex: i]
atIndex: i
shouldCancel: NO];
i++;
}
}
}
}
// We use this as a recursion check.
if (!_changedMessagesEnabled)
if (!_menu.changedMessagesEnabled)
return;
if ([self autoenablesItems])
@ -1002,7 +1055,7 @@ static NSNotificationCenter *nc;
[self setMenuChangedMessagesEnabled: YES];
}
if (_needsSizing && ([_aWindow isVisible] || [_bWindow isVisible]))
if (_menu.needsSizing && ([_aWindow isVisible] || [_bWindow isVisible]))
{
NSDebugLLog (@"NSMenu", @" Calling Size To Fit (A)");
[self sizeToFit];
@ -1107,7 +1160,7 @@ static NSNotificationCenter *nc;
{
ASSIGN(_title, aTitle);
_needsSizing = YES;
_menu.needsSizing = YES;
if ([_aWindow isVisible] || [_bWindow isVisible])
{
[self sizeToFit];
@ -1119,6 +1172,22 @@ static NSNotificationCenter *nc;
return _title;
}
- (id) delegate
{
return _delegate;
}
- (void) setDelegate: (id)delegate
{
_delegate=delegate;
}
- (float)menuBarHeight
{
// FIXME
return [NSMenuView menuBarHeight];
}
//
// Setting the Representing Object
//
@ -1132,7 +1201,7 @@ static NSNotificationCenter *nc;
return;
}
_horizontal = [menuRep isHorizontal];
_menu.horizontal = [menuRep isHorizontal];
if (_view == menuRep)
{
@ -1159,6 +1228,24 @@ static NSNotificationCenter *nc;
return _view;
}
- (id) contextMenuRepresentation
{
return nil;
}
- (void) setContextMenuRepresentation: (id)representation
{
}
- (id) tearOffMenuRepresentation
{
return nil;
}
- (void) setTearOffMenuRepresentation: (id)representation
{
}
//
// Updating the Menu Layout
//
@ -1167,7 +1254,7 @@ static NSNotificationCenter *nc;
// to the _notifications array while enumerating it.
- (void) setMenuChangedMessagesEnabled: (BOOL)flag
{
if (_changedMessagesEnabled != flag)
if (_menu.changedMessagesEnabled != flag)
{
if (flag)
{
@ -1184,13 +1271,13 @@ static NSNotificationCenter *nc;
[_notifications removeAllObjects];
}
_changedMessagesEnabled = flag;
_menu.changedMessagesEnabled = flag;
}
}
- (BOOL) menuChangedMessagesEnabled
{
return _changedMessagesEnabled;
return _menu.changedMessagesEnabled;
}
- (void) sizeToFit
@ -1239,7 +1326,7 @@ static NSNotificationCenter *nc;
[_view setNeedsDisplay: YES];
_needsSizing = NO;
_menu.needsSizing = NO;
}
/*
@ -1253,6 +1340,17 @@ static NSNotificationCenter *nc;
+ (void) popUpContextMenu: (NSMenu*)menu
withEvent: (NSEvent*)event
forView: (NSView*)view
{
[self popUpContextMenu: menu
withEvent: event
forView: view
withFont: nil];
}
+ (void) popUpContextMenu: (NSMenu *)menu
withEvent: (NSEvent *)event
forView: (NSView *)view
withFont: (NSFont *)font
{
[menu _rightMouseDisplay: event];
}
@ -1291,9 +1389,11 @@ static NSNotificationCenter *nc;
}
else
{
BOOL autoenable = _menu.autoenable;
[encoder encodeObject: _title];
[encoder encodeObject: _items];
[encoder encodeValueOfObjCType: @encode(BOOL) at: &_autoenable];
[encoder encodeValueOfObjCType: @encode(BOOL) at: &autoenable];
}
}
@ -1351,7 +1451,7 @@ static NSNotificationCenter *nc;
unsigned i;
unsigned count = [_items count];
[new setAutoenablesItems: _autoenable];
[new setAutoenablesItems: _menu.autoenable];
for (i = 0; i < count; i++)
{
// This works because the copy on NSMenuItem sets the menu to nil!!!
@ -1370,7 +1470,7 @@ static NSNotificationCenter *nc;
{
NSMenu *supermenu;
_is_tornoff = flag;
_menu.is_tornoff = flag;
if (flag)
{
@ -1430,7 +1530,7 @@ static NSNotificationCenter *nc;
- (BOOL) isTransient
{
return _transient;
return _menu.transient;
}
- (BOOL) isPartlyOffScreen
@ -1454,13 +1554,13 @@ static NSNotificationCenter *nc;
- (void) display
{
if (_transient)
if (_menu.transient)
{
NSDebugLLog (@"NSMenu",
@"trying to display while alreay displayed transient");
}
if (_needsSizing)
if (_menu.needsSizing)
{
[self sizeToFit];
}
@ -1489,19 +1589,19 @@ static NSNotificationCenter *nc;
NSPoint location;
NSView *contentView;
if (_transient)
if (_menu.transient)
{
NSDebugLLog (@"NSMenu", @"displaying transient while it is transient");
return;
}
if (_needsSizing)
if (_menu.needsSizing)
{
[self sizeToFit];
}
_oldHiglightedIndex = [[self menuRepresentation] highlightedItemIndex];
_transient = YES;
_menu.transient = YES;
/*
* Cache the old submenu if any and query the supermenu our position.
@ -1542,7 +1642,7 @@ static NSNotificationCenter *nc;
NSMenu *sub = [self attachedMenu];
if (_transient)
if (_menu.transient)
{
NSDebugLLog (@"NSMenu", @"We should not close ordinary menu while transient version is still open");
}
@ -1570,7 +1670,7 @@ static NSNotificationCenter *nc;
{
NSView *contentView;
if (_transient == NO)
if (_menu.transient == NO)
{
NSDebugLLog (@"NSMenu",
@"Closing transient: %@ while it is NOT transient now", _title);
@ -1595,13 +1695,13 @@ static NSNotificationCenter *nc;
[[self menuRepresentation] setHighlightedItemIndex: _oldHiglightedIndex];
_transient = NO;
_menu.transient = NO;
[_view update];
}
- (NSWindow*) window
{
if (_transient)
if (_menu.transient)
return (NSWindow *)_bWindow;
else
return (NSWindow *)_aWindow;
@ -1682,14 +1782,14 @@ static NSNotificationCenter *nc;
- (void) shiftOnScreen
{
NSWindow *theWindow = _transient ? _bWindow : _aWindow;
NSWindow *theWindow = [self window];
NSRect frameRect = [theWindow frame];
NSRect screenRect = [[theWindow screen] visibleFrame];
NSPoint vector = {0.0, 0.0};
BOOL moveIt = NO;
// If we are the main menu forget about moving.
if ([self isEqual: [NSApp mainMenu]] && !_transient)
if ([self isEqual: [NSApp mainMenu]] && !_menu.transient)
return;
// 1 - determine the amount we need to shift in the y direction.
@ -1725,30 +1825,30 @@ static NSNotificationCenter *nc;
NSPoint masterLocation;
NSPoint destinationPoint;
if (_horizontal)
if (_menu.horizontal)
{
masterLocation = [[self window] frame].origin;
destinationPoint.x = masterLocation.x + vector.x;
destinationPoint.y = masterLocation.y + vector.y;
masterLocation = [[self window] frame].origin;
destinationPoint.x = masterLocation.x + vector.x;
destinationPoint.y = masterLocation.y + vector.y;
[self nestedSetFrameOrigin: destinationPoint];
}
}
else
{
NSMenu *candidateMenu;
NSMenu *masterMenu;
// Look for the "master" menu, i.e. the one to move from.
for (candidateMenu = masterMenu = self;
(candidateMenu = masterMenu->_superMenu)
&& (!masterMenu->_is_tornoff
|| masterMenu->_transient);
masterMenu = candidateMenu);
masterLocation = [[masterMenu window] frame].origin;
destinationPoint.x = masterLocation.x + vector.x;
destinationPoint.y = masterLocation.y + vector.y;
{
NSMenu *candidateMenu;
NSMenu *masterMenu;
// Look for the "master" menu, i.e. the one to move from.
for (candidateMenu = masterMenu = self;
(candidateMenu = masterMenu->_superMenu)
&& (!masterMenu->_menu.is_tornoff
|| masterMenu->_menu.transient);
masterMenu = candidateMenu);
masterLocation = [[masterMenu window] frame].origin;
destinationPoint.x = masterLocation.x + vector.x;
destinationPoint.y = masterLocation.y + vector.y;
[masterMenu nestedSetFrameOrigin: destinationPoint];
}
}
}
}
@ -1774,7 +1874,7 @@ static NSNotificationCenter *nc;
- (NSString*) description
{
return [NSString stringWithFormat: @"NSMenu: %@ (%@)",
_title, _transient ? @"Transient": @"Normal"];
_title, _menu.transient ? @"Transient": @"Normal"];
}
@end