Move almost everything menu related to the frontend.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@4665 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Michael Silva 1999-07-28 10:31:56 +00:00
parent e384e9853a
commit 0820add291
5 changed files with 388 additions and 18 deletions

View file

@ -1,3 +1,8 @@
1999-07-27 Michael Hanni <mhanni@sprintmail.com>
* Source/NSMenu.m: merge in all backend code. All that remains in
the backend is NSMenuWindow.
1999-07-27 Michael Hanni <mhanni@sprintmail.com>
* Source/NSTabView.m: added code to allow tabs on the bottom of a

View file

@ -28,17 +28,23 @@
#ifndef _GNUstep_H_NSMenu
#define _GNUstep_H_NSMenu
#include <AppKit/NSView.h>
#include <AppKit/NSMenuItem.h>
#include <AppKit/NSButton.h>
#include <AppKit/NSColor.h>
#include <AppKit/NSControl.h>
#include <AppKit/NSImage.h>
#include <AppKit/NSMenuView.h>
#include <AppKit/PSOperators.h>
@class NSString;
@class NSEvent;
@class NSMatrix;
@class NSMenuView;
@class NSMenuMatrix;
@class NSMenuWindow;
@interface NSMenuWindow : NSWindow
@end
@interface NSMenu : NSObject <NSCoding, NSCopying>
{
NSString *menu_title;
@ -54,9 +60,15 @@
// Private.
BOOL menu_follow_transient;
BOOL menu_is_visible;
// Reserved for back-end use
void *be_menu_reserved;
@private
NSMenuWindow *aWindow;
NSMenuWindow *bWindow;
id titleView;
}
/* Controlling allocation zones */
@ -142,6 +154,9 @@
@interface NSMenu (PrivateMethods)
- (BOOL) isFollowTransient;
- (NSWindow *)window;
/* Shows the menu window on screen */
- (void)display;
@ -149,6 +164,23 @@
- (void)close;
@end
@interface NSMenuWindowTitleView : NSView
{
// a menu's title
int titleHeight;
// is an instance
id menu;
// of this class
NSButton* button;
NSButtonCell* buttonCell;
}
- (void) _addCloseButton;
- (void) _releaseCloseButton;
- (void) windowBecomeTornOff;
- (void) setMenu: (NSMenu*)menu;
- (NSMenu*) menu;
@end
extern NSString* const NSMenuDidSendActionNotification;
extern NSString* const NSMenuWillSendActionNotification;
extern NSString* const NSMenuDidAddItemNotification;

View file

@ -34,13 +34,13 @@
#include <Foundation/NSString.h>
#include <Foundation/NSNotification.h>
#include <AppKit/NSColor.h>
#include <AppKit/NSMenu.h>
#include <AppKit/NSMenuItemCell.h>
#include <AppKit/NSScreen.h>
#include <AppKit/NSView.h>
#include <AppKit/NSPopUpButton.h>
@class NSColor;
@class NSPopUpButton;
@class NSFont;
@interface NSMenuView : NSView
@ -61,7 +61,7 @@
BOOL menuv_needsSizing;
NSSize cellSize;
@private
NSPopUpButton *menuv_popb;
id menuv_popb;
id menuv_items_link;
}
+ (float)menuBarHeight;

View file

@ -31,6 +31,8 @@
#ifndef _GNUstep_H_NSPopUpButton
#define _GNUstep_H_NSPopUpButton
#include <Foundation/Foundation.h>
#include <AppKit/NSButton.h>
#include <AppKit/NSMenuItem.h>
#include <AppKit/NSMenu.h>
@ -38,10 +40,9 @@
@class NSString;
@class NSArray;
@class NSMutableArray;
@class NSMenuView;
@class NSFont;
@class NSMatrix;
@class NSPopUpButton;
@interface NSPopUpButton : NSButton <NSCoding>
{

View file

@ -76,6 +76,10 @@ static NSZone *menuZone = NULL;
- (id) initWithTitle: (NSString *)aTitle
{
NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
NSApplication* theApp = [NSApplication sharedApplication];
NSRect winRect = {{0, 0}, {20, 17}};
[super init];
// Keep the title.
@ -93,11 +97,45 @@ static NSZone *menuZone = NULL;
// We have no supermenu.
menu_supermenu = nil;
menu_is_tornoff = NO;
menu_is_visible = NO;
menu_follow_transient = NO;
menu_changed = YES;
/* According to the spec, menus do autoenable by default */
menu_autoenable = YES;
aWindow = [[NSMenuWindow alloc] initWithContentRect:winRect
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreRetained
defer: NO];
bWindow = [[NSMenuWindow alloc] initWithContentRect:winRect
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreRetained
defer: NO];
titleView = [NSMenuWindowTitleView new];
[titleView setFrameOrigin: NSMakePoint(0, winRect.size.height-21)];
[titleView setFrameSize: NSMakeSize (winRect.size.width, 21)];
[[aWindow contentView] addSubview:menu_view];
[[aWindow contentView] addSubview:titleView];
[titleView setMenu: self];
/*
[defaultCenter addObserver: self
selector: @selector(_showTornOffMenuIfAny:)
name: NSApplicationWillFinishLaunchingNotification
object: theApp];
*/
[defaultCenter addObserver: self
selector: @selector(_deactivate:)
name: NSApplicationWillResignActiveNotification
object: theApp];
[defaultCenter addObserver: self
selector: @selector(_activate:)
name: NSApplicationWillBecomeActiveNotification
object: theApp];
return self;
}
@ -354,16 +392,35 @@ static NSZone *menuZone = NULL;
return menu_supermenu && [menu_supermenu attachedMenu] == self;
}
/*
- (BOOL) isTornOff
{
return menu_is_tornoff;
}
*/
- (NSPoint) locationForSubmenu: (NSMenu *)aSubmenu
- (NSPoint) locationForSubmenu: (NSMenu*)aSubmenu
{
return NSZeroPoint;
NSRect frame;
NSRect submenuFrame;
if (![self isFollowTransient])
{
frame = [aWindow frame];
}
else
{
frame = [bWindow frame];
}
if (aSubmenu)
{
submenuFrame = [aSubmenu->aWindow frame];
}
else
submenuFrame = NSZeroRect;
return NSMakePoint (frame.origin.x + frame.size.width + 1,
frame.origin.y + frame.size.height
- submenuFrame.size.height);
}
- (NSMenu *) supermenu
@ -555,12 +612,24 @@ static NSZone *menuZone = NULL;
}
- (void) sizeToFit
{
// NSLog(@"- sizeToFit called in NSMenu\n");
//
// [menu_view sizeToFit];
// [menu_view setNeedsDisplay: YES];
// menu_changed = NO;
{
NSRect mFrame;
NSSize size;
[menu_view sizeToFit];
mFrame = [menu_view frame];
[titleView setFrameOrigin: NSMakePoint(0, mFrame.size.height)];
[titleView setFrameSize: NSMakeSize (mFrame.size.width,21)];
size.width = mFrame.size.width;
size.height = mFrame.size.height+21;
[aWindow setFrame: NSMakeRect(300,300,size.width,size.height) display: NO];
[bWindow setFrame: NSMakeRect(300,300,size.width,size.height) display: NO];
[menu_view setNeedsDisplay:YES];
menu_changed = NO;
}
- (void) helpRequested: (NSEvent *)event
@ -584,3 +653,266 @@ static NSZone *menuZone = NULL;
return self;
}
@end
@implementation NSMenu (GNUstepPrivate)
- (void) _activate: (NSNotification*)notification
{
if (menu_is_visible)
[aWindow orderFrontRegardless];
}
- (void) _deactivate: (NSNotification*)notification
{
if (menu_is_visible)
[aWindow orderOut:nil];
}
- (BOOL) isFollowTransient
{
return menu_follow_transient;
}
- (void) _setTornOff:(BOOL)flag
{
menu_is_tornoff = flag;
[[[self supermenu] menuView] setHighlightedItemIndex:-1];
}
- (void) _performMenuClose:(id)sender
{
[self _setTornOff:NO];
[self close];
[titleView _releaseCloseButton];
}
- (void) display
{
if (menu_changed)
[self sizeToFit];
if (menu_supermenu) // query super menu for
{ // position
NSPoint location = [menu_supermenu locationForSubmenu: self];
[aWindow setFrameOrigin: location];
menu_supermenu->menu_attached_menu = self;
}
menu_is_visible = YES;
[aWindow orderFront:self];
}
- (void) displayTransient
{
menu_follow_transient = YES;
if (menu_supermenu) // query super menu for our
{ // position
NSPoint location = [menu_supermenu locationForSubmenu: self];
[bWindow setFrameOrigin: location];
menu_supermenu->menu_attached_menu = self;
}
[menu_view removeFromSuperviewWithoutNeedingDisplay];
[titleView removeFromSuperviewWithoutNeedingDisplay];
[titleView _releaseCloseButton];
[[bWindow contentView] addSubview:menu_view];
[[bWindow contentView] addSubview:titleView];
[bWindow orderFront:self];
}
- (void) close
{
[aWindow orderOut:self];
menu_is_visible = NO;
}
- (void) closeTransient
{
[bWindow orderOut:self];
[menu_view removeFromSuperviewWithoutNeedingDisplay];
[titleView removeFromSuperviewWithoutNeedingDisplay];
[[aWindow contentView] addSubview:menu_view];
[titleView _addCloseButton];
[[aWindow contentView] addSubview:titleView];
[[aWindow contentView] setNeedsDisplay:YES];
menu_follow_transient = NO;
}
- (NSWindow *) window
{
return (NSWindow *)aWindow;
}
- (NSMenuView *) menuView
{
return menu_view;
}
@end
@implementation NSMenuWindow
+ (void) initialize
{
if (self == [NSMenu class])
{
[self setVersion: 1];
}
}
@end
@implementation NSMenuWindowTitleView
- (BOOL) acceptsFirstMouse: (NSEvent *)theEvent
{
return YES;
}
- (void)setMenu: (NSMenu*)aMenu { menu = aMenu; }
- (NSMenu*)menu { return menu; }
- (void)drawRect: (NSRect)rect
{
NSRect floodRect = rect;
NSDrawButton(rect, rect);
floodRect.origin.x += 1;
floodRect.origin.y += 2;
floodRect.size.height -= 3;
floodRect.size.width -= 3;
[[NSColor blackColor] set];
NSRectFill(floodRect);
[[NSColor whiteColor] set];
[[NSFont boldSystemFontOfSize:12] set];
PSmoveto(rect.origin.x + 5, rect.origin.y + 6);
PSshow([[menu title] cString]);
}
- (void) mouseDown: (NSEvent*)theEvent
{
NSPoint lastLocation;
NSPoint location;
unsigned eventMask = NSLeftMouseUpMask | NSLeftMouseDownMask
| NSPeriodicMask | NSRightMouseUpMask;
BOOL done = NO;
NSApplication *theApp = [NSApplication sharedApplication];
NSDate *theDistantFuture = [NSDate distantFuture];
lastLocation = [theEvent locationInWindow];
if ([menu supermenu])
{
[self windowBecomeTornOff];
[menu _setTornOff:YES];
}
[NSEvent startPeriodicEventsAfterDelay: 0.02 withPeriod: 0.02];
while (!done)
{
theEvent = [theApp nextEventMatchingMask: eventMask
untilDate: theDistantFuture
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
switch ([theEvent type])
{
case NSRightMouseUp:
case NSLeftMouseUp:
/* right mouse up or left mouse up means we're done */
done = YES;
break;
case NSPeriodic:
location = [window mouseLocationOutsideOfEventStream];
if (NSEqualPoints(location, lastLocation) == NO)
{
NSMenu *aMenu = menu;
BOOL aDone = NO;
NSPoint origin = [window frame].origin;
origin.x += (location.x - lastLocation.x);
origin.y += (location.y - lastLocation.y);
[window setFrameOrigin: origin];
while (!aDone)
{
if ((aMenu = [aMenu attachedMenu]))
{
NSPoint origin;
if ([aMenu isTornOff])
{
aDone = YES;
return;
}
origin = [[aMenu window] frame].origin;
origin.x += (location.x - lastLocation.x);
origin.y += (location.y - lastLocation.y);
[[aMenu window] setFrameOrigin: origin];
}
else
aDone = YES;
}
}
break;
default:
break;
}
}
[NSEvent stopPeriodicEvents];
// save position code goes here. FIXME.
}
- (void) windowBecomeTornOff
{
if ([menu isTornOff]) // do nothing if menu
return; // is already torn off
else
{ // show close button
NSImage* closeImage = [NSImage imageNamed: @"common_Close"];
NSImage* closeHImage = [NSImage imageNamed: @"common_CloseH"];
NSSize imageSize = [closeImage size];
NSRect rect = { { frame.size.width - imageSize.width - 4,
(frame.size.height - imageSize.height) / 2},
{ imageSize.height, imageSize.width } };
int mask = NSViewMinXMargin | NSViewMinYMargin | NSViewMaxYMargin;
button = [[NSButton alloc] initWithFrame: rect];
[button setButtonType: NSMomentaryLight]; // configure the menu's
[button setImagePosition: NSImageOnly]; // close button
[button setImage: closeImage];
[button setAlternateImage: closeHImage];
[button setBordered: NO];
[button setTarget: menu];
[button setAction: @selector(_performMenuClose:)];
[button setAutoresizingMask: NSViewMinXMargin];
[self addSubview: button];
[self setAutoresizingMask: mask];
[button display];
[self setNeedsDisplay:YES];
}
}
- (void) _releaseCloseButton
{
[button retain];
[button removeFromSuperview];
}
- (void) _addCloseButton
{
[self addSubview:button];
}
@end /* NSMenuWindowTitleView */