mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 07:40:47 +00:00
Release 0.3.0.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@2347 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
ab62618166
commit
e0396854b6
44 changed files with 2645 additions and 1101 deletions
|
@ -125,7 +125,7 @@ gui/NSImage.h \
|
|||
gui/NSImageRep.h \
|
||||
gui/NSMatrix.h \
|
||||
gui/NSMenu.h \
|
||||
gui/NSMenuCell.h \
|
||||
gui/NSMenuItem.h \
|
||||
gui/NSNibLoading.h \
|
||||
gui/NSOpenPanel.h \
|
||||
gui/NSPageLayout.h \
|
||||
|
@ -201,7 +201,7 @@ NSImage$(oext) \
|
|||
NSImageRep$(oext) \
|
||||
NSMatrix$(oext) \
|
||||
NSMenu$(oext) \
|
||||
NSMenuCell$(oext) \
|
||||
NSMenuItem$(oext) \
|
||||
NSOpenPanel$(oext) \
|
||||
NSPageLayout$(oext) \
|
||||
NSPanel$(oext) \
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSNotification.h>
|
||||
#include <Foundation/NSRunLoop.h>
|
||||
#include <Foundation/NSAutoreleasePool.h>
|
||||
|
||||
#include <DPSClient/NSDPSContext.h>
|
||||
#include <AppKit/NSApplication.h>
|
||||
#include <AppKit/NSPopUpButton.h>
|
||||
|
@ -38,7 +40,7 @@
|
|||
#include <AppKit/NSEvent.h>
|
||||
#include <AppKit/NSImage.h>
|
||||
#include <AppKit/NSMenu.h>
|
||||
#include <AppKit/NSMenuCell.h>
|
||||
#include <AppKit/NSMenuItem.h>
|
||||
#include <AppKit/NSCursor.h>
|
||||
|
||||
//
|
||||
|
@ -264,6 +266,7 @@ NSString *NSApplicationWillUpdateNotification = @"ApplicationWillUpdate";
|
|||
- (void)run
|
||||
{
|
||||
NSEvent *e;
|
||||
NSAutoreleasePool* pool;
|
||||
|
||||
NSDebugLog(@"NSApplication -run\n");
|
||||
|
||||
|
@ -274,6 +277,7 @@ NSString *NSApplicationWillUpdateNotification = @"ApplicationWillUpdate";
|
|||
|
||||
do
|
||||
{
|
||||
pool = [NSAutoreleasePool new];
|
||||
e = [self nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:[NSDate distantFuture]
|
||||
inMode:NSDefaultRunLoopMode dequeue:YES];
|
||||
|
@ -285,6 +289,7 @@ NSString *NSApplicationWillUpdateNotification = @"ApplicationWillUpdate";
|
|||
// Call the back-end method to handle it
|
||||
[self handleNullEvent];
|
||||
}
|
||||
[pool release];
|
||||
} while (!app_should_quit);
|
||||
app_is_running = YES;
|
||||
|
||||
|
@ -442,82 +447,76 @@ NSString *NSApplicationWillUpdateNotification = @"ApplicationWillUpdate";
|
|||
{
|
||||
}
|
||||
|
||||
- (NSEvent*)_eventMatchingMask:(unsigned int)mask
|
||||
{
|
||||
NSEvent* event;
|
||||
int i, count;
|
||||
|
||||
/* Get an event from the events queue */
|
||||
if ((count = [event_queue count])) {
|
||||
for (i = 0; i < count; i++) {
|
||||
event = [event_queue objectAtIndex:i];
|
||||
if ([self event:event matchMask:mask]) {
|
||||
[event retain];
|
||||
[event_queue removeObjectAtIndex:i];
|
||||
[self setCurrentEvent:event];
|
||||
return [event autorelease];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSEvent *)nextEventMatchingMask:(unsigned int)mask
|
||||
untilDate:(NSDate *)expiration
|
||||
inMode:(NSString *)mode
|
||||
dequeue:(BOOL)flag
|
||||
{
|
||||
NSEvent *e;
|
||||
BOOL done;
|
||||
int i, j;
|
||||
NSRunLoop* currentLoop = [NSRunLoop currentRunLoop];
|
||||
NSEventType type;
|
||||
NSEvent *event;
|
||||
BOOL done = NO;
|
||||
|
||||
// If the queue isn't empty then check those messages
|
||||
if ([event_queue count])
|
||||
{
|
||||
j = [event_queue count];
|
||||
// for (i = j-1;i >= 0; --i)
|
||||
for (i = 0; i < j; i++)
|
||||
{
|
||||
e = [event_queue objectAtIndex: i];
|
||||
if ([self event: e matchMask: mask])
|
||||
{
|
||||
[e retain];
|
||||
[event_queue removeObjectAtIndex: i];
|
||||
[self setCurrentEvent: e];
|
||||
return [e autorelease];
|
||||
}
|
||||
}
|
||||
}
|
||||
event = [self _eventMatchingMask:mask];
|
||||
if (event)
|
||||
done = YES;
|
||||
|
||||
// Not in queue so wait for next event
|
||||
done = NO;
|
||||
while (!done)
|
||||
{
|
||||
#if USE_RUN_LOOP
|
||||
NSRunLoop* currentLoop = [NSRunLoop currentRunLoop];
|
||||
NSDate* limitDate = [currentLoop limitDateForMode:mode];
|
||||
while (!done) {
|
||||
NSDate* limitDate = [currentLoop limitDateForMode:mode];
|
||||
|
||||
if (!expiration)
|
||||
expiration = [NSDate distantFuture];
|
||||
/* -limitDateForMode: can fire timers and timer events can be quueued in
|
||||
events queue so check for them. */
|
||||
event = [self _eventMatchingMask:mask];
|
||||
if (event)
|
||||
break;
|
||||
|
||||
if (limitDate)
|
||||
limitDate = [expiration earlierDate:limitDate];
|
||||
else
|
||||
limitDate = expiration;
|
||||
if (!expiration)
|
||||
expiration = [NSDate distantFuture];
|
||||
|
||||
// NSLog (@"calling runMode:beforeDate:");
|
||||
[currentLoop runMode:mode beforeDate:limitDate];
|
||||
// NSLog (@"return from runMode:beforeDate:");
|
||||
#else
|
||||
e = [self getNextEvent];
|
||||
#endif
|
||||
if (limitDate)
|
||||
limitDate = [expiration earlierDate:limitDate];
|
||||
else
|
||||
limitDate = expiration;
|
||||
|
||||
if ([event_queue count]) {
|
||||
e = [[event_queue lastObject] retain];
|
||||
[currentLoop runMode:mode beforeDate:limitDate];
|
||||
|
||||
// Check mask
|
||||
if ([self event: e matchMask: mask])
|
||||
{
|
||||
if (e)
|
||||
{
|
||||
[event_queue removeObject: e];
|
||||
}
|
||||
done = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
event = [self _eventMatchingMask:mask];
|
||||
if (event)
|
||||
done = YES;
|
||||
}
|
||||
|
||||
type = [event type];
|
||||
|
||||
// Unhide the cursor if necessary
|
||||
// but only if its not a null event
|
||||
if (e != gnustep_gui_null_event)
|
||||
if (event != gnustep_gui_null_event)
|
||||
{
|
||||
NSEventType type;
|
||||
|
||||
// Only if we should unhide when mouse moves
|
||||
if ([NSCursor isHiddenUntilMouseMoves])
|
||||
{
|
||||
// Make sure the event is a mouse event before unhiding
|
||||
type = [e type];
|
||||
if ((type == NSLeftMouseDown) || (type == NSLeftMouseUp)
|
||||
|| (type == NSRightMouseDown) || (type == NSRightMouseUp)
|
||||
|| (type == NSMouseMoved))
|
||||
|
@ -525,8 +524,7 @@ NSString *NSApplicationWillUpdateNotification = @"ApplicationWillUpdate";
|
|||
}
|
||||
}
|
||||
|
||||
[self setCurrentEvent: e];
|
||||
return [e autorelease];
|
||||
return event;
|
||||
}
|
||||
|
||||
- (NSEvent *)peekEventMatchingMask:(unsigned int)mask
|
||||
|
@ -810,13 +808,13 @@ NSString *NSApplicationWillUpdateNotification = @"ApplicationWillUpdate";
|
|||
- (void)setMainMenu:(NSMenu *)aMenu
|
||||
{
|
||||
int i, j;
|
||||
NSMenuCell *mc;
|
||||
NSMenuItem *mc;
|
||||
NSArray *mi;
|
||||
|
||||
// Release old and retain new
|
||||
[aMenu retain];
|
||||
[main_menu release];
|
||||
main_menu = aMenu;
|
||||
[main_menu retain];
|
||||
|
||||
// Search for a menucell with the name Windows
|
||||
// This is the default windows menu
|
||||
|
@ -897,8 +895,8 @@ NSString *NSApplicationWillUpdateNotification = @"ApplicationWillUpdate";
|
|||
|
||||
- (void)setWindowsMenu:aMenu
|
||||
{
|
||||
if (windows_menu)
|
||||
[windows_menu setSubmenu:aMenu];
|
||||
// if (windows_menu)
|
||||
// [windows_menu setSubmenu:aMenu];
|
||||
}
|
||||
|
||||
- (void)updateWindowsItem:aWindow
|
||||
|
@ -907,7 +905,8 @@ NSString *NSApplicationWillUpdateNotification = @"ApplicationWillUpdate";
|
|||
|
||||
- (NSMenu *)windowsMenu
|
||||
{
|
||||
return [windows_menu submenu];
|
||||
// return [windows_menu submenu];
|
||||
return nil;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -132,6 +132,7 @@
|
|||
[contents release];
|
||||
[cell_image release];
|
||||
[cell_font release];
|
||||
[represented_object release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -223,6 +224,7 @@
|
|||
[anImage retain];
|
||||
[cell_image release];
|
||||
cell_image = anImage;
|
||||
[self setType:NSImageCellType];
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -254,6 +256,7 @@
|
|||
|
||||
[contents release];
|
||||
contents = [[number stringValue] retain];
|
||||
[self setType:NSTextCellType];
|
||||
}
|
||||
|
||||
- (void)setFloatValue:(float)aFloat
|
||||
|
@ -262,6 +265,7 @@
|
|||
|
||||
[contents release];
|
||||
contents = [[number stringValue] retain];
|
||||
[self setType:NSTextCellType];
|
||||
}
|
||||
|
||||
- (void)setIntValue:(int)anInt
|
||||
|
@ -270,6 +274,7 @@
|
|||
|
||||
[contents release];
|
||||
contents = [[number stringValue] retain];
|
||||
[self setType:NSTextCellType];
|
||||
}
|
||||
|
||||
- (void)setStringValue:(NSString *)aString
|
||||
|
@ -537,6 +542,10 @@
|
|||
return nil;
|
||||
}
|
||||
|
||||
- (void)performClick:(id)sender
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Assigning a Tag
|
||||
//
|
||||
|
@ -730,11 +739,15 @@
|
|||
//
|
||||
- (id)representedObject
|
||||
{
|
||||
return nil;
|
||||
return represented_object;
|
||||
}
|
||||
|
||||
- (void)setRepresentedObject:(id)anObject
|
||||
{}
|
||||
{
|
||||
[anObject retain];
|
||||
[represented_object release];
|
||||
represented_object = anObject;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone*)zone
|
||||
{
|
||||
|
@ -761,7 +774,7 @@
|
|||
[c setEntryType:entry_type];
|
||||
c->control_view = control_view;
|
||||
c->cell_size = cell_size;
|
||||
c->represented_object = [represented_object retain];
|
||||
[c setRepresentedObject:represented_object];
|
||||
|
||||
return c;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include <AppKit/NSEvent.h>
|
||||
#include <AppKit/NSApplication.h>
|
||||
#include <AppKit/NSWindow.h>
|
||||
|
||||
@implementation NSEvent
|
||||
|
||||
|
@ -435,9 +436,7 @@ static NSRecursiveLock* timersLock = nil;
|
|||
|
||||
- (NSWindow *)window
|
||||
{
|
||||
NSApplication *theApp = [NSApplication sharedApplication];
|
||||
|
||||
return [theApp windowWithWindowNumber:window_num];
|
||||
return [NSWindow windowWithNumber:window_num];
|
||||
}
|
||||
|
||||
- (int)windowNumber
|
||||
|
|
|
@ -69,6 +69,13 @@ static NSFont* getFont(NSString* key, NSString* defaultFontName, float fontSize)
|
|||
if (!fontName)
|
||||
fontName = defaultFontName;
|
||||
|
||||
if (!fontSize) {
|
||||
fontSize = [[NSUserDefaults standardUserDefaults]
|
||||
floatForKey:[NSString stringWithFormat:@"%@Size", key]];
|
||||
if (!fontSize)
|
||||
fontSize = 12;
|
||||
}
|
||||
|
||||
return [NSFont fontWithName:fontName size:fontSize];
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd)
|
|||
[_reps replaceObjectAtIndex: i withObject:
|
||||
[NSValue value: new_repd withObjCType: @encode(rep_data_t)]];
|
||||
found = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
|
@ -217,7 +218,8 @@ set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd)
|
|||
|
||||
if ([path length] != 0)
|
||||
{
|
||||
NSImage* image = [[NSImage alloc] initByReferencingFile:path];
|
||||
NSImage* image = [[[NSImage alloc] initByReferencingFile:path]
|
||||
autorelease];
|
||||
if (image)
|
||||
[image setName: [[path lastPathComponent]
|
||||
stringByDeletingPathExtension]];
|
||||
|
@ -325,12 +327,15 @@ set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd)
|
|||
NSImage* copy;
|
||||
|
||||
// FIXME: maybe we should retain if _flags.dataRetained = NO
|
||||
copy = (NSImage*)NSAllocateObject (isa, 0, zone);
|
||||
copy = (NSImage*)NSCopyObject (self, 0, zone);
|
||||
|
||||
[name retain];
|
||||
copy->_reps = [NSMutableArray new];
|
||||
copy->_repList = [NSMutableArray new];
|
||||
[_color retain];
|
||||
_lockedView = nil;
|
||||
[copy addRepresentations: [[self representations] copyWithZone: zone]];
|
||||
[copy addRepresentations: [[[self representations] copyWithZone: zone]
|
||||
autorelease]];
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
@ -686,7 +691,7 @@ set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd)
|
|||
for (i = 0; i < count; i++)
|
||||
{
|
||||
repd.fileName = NULL;
|
||||
repd.rep = [imageRepArray objectAtIndex: i];
|
||||
repd.rep = [[imageRepArray objectAtIndex: i] retain];
|
||||
repd.cache = NULL;
|
||||
repd.original = NULL;
|
||||
repd.validCache = NO;
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include <Foundation/NSValue.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSAutoreleasePool.h>
|
||||
|
||||
#include <AppKit/NSColor.h>
|
||||
#include <AppKit/NSActionCell.h>
|
||||
#include <AppKit/NSWindow.h>
|
||||
|
@ -960,11 +962,15 @@ static int mouseDownFlags = 0;
|
|||
- (void)sizeToCells
|
||||
{
|
||||
NSSize newSize;
|
||||
int nc = numCols;
|
||||
int nr = numRows;
|
||||
|
||||
newSize.width = numCols * (cellSize.width + intercell.width)
|
||||
- intercell.width;
|
||||
newSize.height = numRows * (cellSize.height + intercell.height)
|
||||
- intercell.height;
|
||||
if (!nc)
|
||||
nc = 1;
|
||||
if (!nr)
|
||||
nr = 1;
|
||||
newSize.width = nc * (cellSize.width + intercell.width) - intercell.width;
|
||||
newSize.height = nr * (cellSize.height + intercell.height) - intercell.height;
|
||||
[self setFrameSize:newSize];
|
||||
}
|
||||
|
||||
|
@ -1155,7 +1161,8 @@ static int mouseDownFlags = 0;
|
|||
|
||||
mouseDownFlags = [theEvent modifierFlags];
|
||||
lastLocation = [self convertPoint:lastLocation fromView:nil];
|
||||
[NSEvent startPeriodicEventsAfterDelay:0.05 withPeriod:0.05];
|
||||
if (mode != NSTrackModeMatrix)
|
||||
[NSEvent startPeriodicEventsAfterDelay:0.05 withPeriod:0.05];
|
||||
ASSIGN(lastEvent, theEvent);
|
||||
[self lockFocus];
|
||||
|
||||
|
@ -1325,7 +1332,8 @@ static int mouseDownFlags = 0;
|
|||
|
||||
[[self window] flushWindow];
|
||||
[self unlockFocus];
|
||||
[NSEvent stopPeriodicEvents];
|
||||
if (mode != NSTrackModeMatrix)
|
||||
[NSEvent stopPeriodicEvents];
|
||||
[lastEvent release];
|
||||
}
|
||||
|
||||
|
@ -1548,10 +1556,10 @@ static int mouseDownFlags = 0;
|
|||
last:(MPoint)last
|
||||
current:(MPoint)current
|
||||
{
|
||||
/* We use an imaginar coordinate system whose center is the `anchor' point. We
|
||||
should determine in which quadrants are located the `last' and the `current'
|
||||
points. Based on this we extend the selection to the rectangle determined
|
||||
by `anchor' and `current' points.
|
||||
/* We use an imaginar coordinate system whose center is the `anchor' point.
|
||||
We should determine in which quadrants are located the `last' and the
|
||||
`current' points. Based on this we extend the selection to the rectangle
|
||||
determined by `anchor' and `current' points.
|
||||
|
||||
The algorithm uses two rectangles: one determined by `anchor' and
|
||||
`current' that defines how the final selection rectangle will look, and
|
||||
|
@ -1982,4 +1990,80 @@ static int mouseDownFlags = 0;
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
|
||||
/* A test to exhaustively check if the list selection mode works correctly. */
|
||||
- (void)_selectRect2UsingAnchor:(MPoint)anchor
|
||||
last:(MPoint)last
|
||||
current:(MPoint)current
|
||||
{
|
||||
MRect selectRect;
|
||||
MRect unselectRect;
|
||||
|
||||
selectRect.x = MIN(anchor.x, current.x);
|
||||
selectRect.y = MIN(anchor.y, current.y);
|
||||
selectRect.width = ABS(current.x - anchor.x);
|
||||
selectRect.height = ABS(current.y - anchor.y);
|
||||
|
||||
unselectRect.x = MIN(anchor.x, last.x);
|
||||
unselectRect.y = MIN(anchor.y, last.y);
|
||||
unselectRect.width = ABS(current.x - last.x);
|
||||
unselectRect.height = ABS(current.y - last.y);
|
||||
|
||||
[self _setState:0 inRect:unselectRect];
|
||||
[self _setState:1 inRect:selectRect];
|
||||
}
|
||||
|
||||
/* This method assumes the receiver matrix has at least 5 rows and 5 columns.
|
||||
*/
|
||||
- (void)_test
|
||||
{
|
||||
NSArray* selectedCellsByMethod1;
|
||||
NSArray* selectedCellsByMethod2;
|
||||
NSAutoreleasePool* pool;
|
||||
MPoint anchor, last, current;
|
||||
int i = 1;
|
||||
int noOfErrors = 0;
|
||||
|
||||
if (numRows < 5 || numCols < 5) {
|
||||
NSLog (@"matrix should have at least 5 rows and 5 columns!");
|
||||
return;
|
||||
}
|
||||
|
||||
for (anchor.x = 0; anchor.x < 5; anchor.x++)
|
||||
for (anchor.y = 0; anchor.y < 5; anchor.y++)
|
||||
for (last.x = 0; last.x < 5; last.x++)
|
||||
for (last.y = 0; last.y < 5; last.y++)
|
||||
for (current.x = 0; current.x < 5; current.x++)
|
||||
for (current.y = 0; current.y < 5; current.y++) {
|
||||
pool = [NSAutoreleasePool new];
|
||||
|
||||
printf ("%d\r", i++);
|
||||
fflush (stdout);
|
||||
|
||||
/* First determine the selected cells using the sure method */
|
||||
[self _selectRect2UsingAnchor:anchor last:last current:current];
|
||||
selectedCellsByMethod2 = [self selectedCells];
|
||||
|
||||
/* Then determine the same using the optimized method */
|
||||
[self _selectRectUsingAnchor:anchor last:last current:current];
|
||||
selectedCellsByMethod1 = [self selectedCells];
|
||||
|
||||
/* Compare the selected cells determined by the two methods */
|
||||
if (![selectedCellsByMethod1 isEqual:selectedCellsByMethod2]) {
|
||||
NSLog (@"\nSelected cells are different for:\n"
|
||||
@"anchor = (%d, %d)\nlast = (%d, %d)\ncurrent = (%d, %d)",
|
||||
anchor.x, anchor.y, last.x, last.y, current.x, current.y);
|
||||
noOfErrors++;
|
||||
}
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
printf ("\nready!\nnumber of errors = %d\n", noOfErrors);
|
||||
fflush (stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
|
836
Source/NSMenu.m
836
Source/NSMenu.m
|
@ -1,12 +1,11 @@
|
|||
/*
|
||||
NSMenu.m
|
||||
|
||||
The menu class
|
||||
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
|
||||
Author: Scott Christley <scottc@net-community.com>
|
||||
Date: 1996
|
||||
Author: Ovidiu Predescu <ovidiu@net-community.com>
|
||||
Date: May 1997
|
||||
A completely rewritten version of the original source by Scott Christley.
|
||||
|
||||
This file is part of the GNUstep GUI Library.
|
||||
|
||||
|
@ -26,267 +25,710 @@
|
|||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <Foundation/NSLock.h>
|
||||
#include <Foundation/NSCoder.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <AppKit/NSMenu.h>
|
||||
#include <AppKit/NSMenuCell.h>
|
||||
#include <AppKit/NSMenuPrivate.h>
|
||||
#include <AppKit/NSApplication.h>
|
||||
#include <Foundation/NSProcessInfo.h>
|
||||
|
||||
#include <AppKit/NSMatrix.h>
|
||||
#include <AppKit/NSApplication.h>
|
||||
#include <AppKit/NSWindow.h>
|
||||
#include <AppKit/NSEvent.h>
|
||||
#include <AppKit/NSFont.h>
|
||||
#include <AppKit/NSMenu.h>
|
||||
|
||||
NSZone *gnustep_gui_nsmenu_zone = NULL;
|
||||
#define ASSIGN(variable, value) \
|
||||
[value retain]; \
|
||||
[variable release]; \
|
||||
variable = value;
|
||||
|
||||
@implementation NSMenu
|
||||
#ifdef MAX
|
||||
# undef MAX
|
||||
#endif
|
||||
# define MAX(a, b) \
|
||||
({typedef _ta = (a), _tb = (b); \
|
||||
_ta _a = (a); _tb _b = (b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
//
|
||||
// Class methods
|
||||
//
|
||||
+ (void)initialize
|
||||
|
||||
@interface NSMenu (PrivateMethods2)
|
||||
- (void)_menuChanged;
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSMenuMatrix
|
||||
|
||||
// Class variables
|
||||
static NSFont* menuFont = nil;
|
||||
|
||||
- initWithFrame:(NSRect)rect
|
||||
{
|
||||
if (self == [NSMenu class])
|
||||
{
|
||||
// Initial version
|
||||
[self setVersion:2];
|
||||
}
|
||||
}
|
||||
[super initWithFrame:rect];
|
||||
cells = [NSMutableArray new];
|
||||
|
||||
//
|
||||
// Controlling Allocation Zones
|
||||
//
|
||||
+ (NSZone *)menuZone
|
||||
{
|
||||
return gnustep_gui_nsmenu_zone;
|
||||
}
|
||||
|
||||
+ (void)setMenuZone:(NSZone *)zone
|
||||
{
|
||||
gnustep_gui_nsmenu_zone = zone;
|
||||
}
|
||||
|
||||
//
|
||||
// Instance methods
|
||||
//
|
||||
//
|
||||
// Initializing a New NSMenu
|
||||
//
|
||||
- init
|
||||
{
|
||||
return [self initWithTitle:@""];
|
||||
}
|
||||
|
||||
// Default initializer
|
||||
- (id)initWithTitle:(NSString *)aTitle
|
||||
{
|
||||
// NSApplication *theApp = [NSApplication sharedApplication];
|
||||
|
||||
// Init our superclass but skip any of its backend implementation
|
||||
[super init];
|
||||
|
||||
window_title = aTitle;
|
||||
menu_items = [NSMutableArray array];
|
||||
super_menu = nil;
|
||||
autoenables_items = NO;
|
||||
|
||||
menu_matrix = [[NSMatrix alloc] initWithFrame: NSZeroRect];
|
||||
[menu_matrix setCellClass: [NSMenuCell class]];
|
||||
[menu_matrix setIntercellSpacing: NSZeroSize];
|
||||
// [self setContentView: menu_matrix];
|
||||
|
||||
is_torn_off = NO;
|
||||
|
||||
// Register ourselves with the Application object
|
||||
// [theApp addWindowsItem:self title:window_title filename:NO];
|
||||
/* Don't initialize menuFont in +initialize since we don't know if the
|
||||
DGS process knows anything about the fonts yet. */
|
||||
if (!menuFont)
|
||||
menuFont = [[NSFont systemFontOfSize:0] retain];
|
||||
|
||||
cellSize = NSMakeSize (1, [menuFont pointSize] - [menuFont descender] + 4);
|
||||
return self;
|
||||
}
|
||||
|
||||
//
|
||||
// Setting Up the Menu Commands
|
||||
//
|
||||
- (id)addItemWithTitle:(NSString *)aString
|
||||
action:(SEL)aSelector
|
||||
keyEquivalent:(NSString *)charCode
|
||||
- (void)dealloc
|
||||
{
|
||||
NSMenuCell *m;
|
||||
NSDebugLog (@"NSMenuMatrix of menu '%@' dealloc", [menu title]);
|
||||
|
||||
m = [[NSMenuCell alloc] initTextCell:aString];
|
||||
[m setAction:aSelector];
|
||||
[menu_items addObject:m];
|
||||
|
||||
return m;
|
||||
[cells release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)insertItemWithTitle:(NSString *)aString
|
||||
action:(SEL)aSelector
|
||||
keyEquivalent:(NSString *)charCode
|
||||
atIndex:(unsigned int)index
|
||||
- (id)copyWithZone:(NSZone*)zone
|
||||
{
|
||||
NSMenuCell *m;
|
||||
NSMenuMatrix* copy = NSAllocateObject (isa, 0, zone);
|
||||
int i, count;
|
||||
|
||||
m = [[NSMenuCell alloc] initTextCell:aString];
|
||||
[m setAction:aSelector];
|
||||
[menu_items insertObject:m atIndex:index];
|
||||
NSDebugLog (@"copy menu matrix of menu with title '%@'", [menu title]);
|
||||
copy->cells = [[NSMutableArray alloc] initWithCapacity:[cells count]];
|
||||
for (i = 0, count = [cells count]; i < count; i++) {
|
||||
id aCell = [cells objectAtIndex:i];
|
||||
id cellCopy = [[aCell copyWithZone:zone] autorelease];
|
||||
|
||||
return m;
|
||||
[copy->cells addObject:cellCopy];
|
||||
}
|
||||
|
||||
copy->cellSize = cellSize;
|
||||
copy->menu = menu;
|
||||
if (selectedCell) {
|
||||
int index = [cells indexOfObject:selectedCell];
|
||||
|
||||
copy->selectedCell = [[cells objectAtIndex:index] retain];
|
||||
}
|
||||
copy->selectedCellRect = selectedCellRect;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
- (NSArray *)itemArray
|
||||
- (void)_resizeMenuForCellSize
|
||||
{
|
||||
return menu_items;
|
||||
/* Resize the frame to hold all the menu cells */
|
||||
[super setFrameSize:NSMakeSize (cellSize.width,
|
||||
(cellSize.height + INTERCELL_SPACE) * [cells count] - INTERCELL_SPACE)];
|
||||
}
|
||||
|
||||
- (NSMatrix *)itemMatrix
|
||||
- (id <NSMenuItem>)insertItemWithTitle:(NSString*)aString
|
||||
action:(SEL)aSelector
|
||||
keyEquivalent:(NSString*)charCode
|
||||
atIndex:(unsigned int)index
|
||||
{
|
||||
return menu_matrix;
|
||||
id menuCell = [[[NSMenu cellClass] new] autorelease];
|
||||
float titleWidth;
|
||||
|
||||
[menuCell setTitle:aString];
|
||||
[menuCell setAction:aSelector];
|
||||
[menuCell setKeyEquivalent:charCode];
|
||||
[menuCell setFont:menuFont];
|
||||
|
||||
titleWidth = [menuFont widthOfString:aString];
|
||||
cellSize = NSMakeSize (MAX(titleWidth + ADDITIONAL_WIDTH, cellSize.width),
|
||||
cellSize.height);
|
||||
[cells insertObject:menuCell atIndex:index];
|
||||
|
||||
[self _resizeMenuForCellSize];
|
||||
|
||||
return menuCell;
|
||||
}
|
||||
|
||||
- (void)setItemMatrix:(NSMatrix *)aMatrix
|
||||
- (void)removeItem:(id <NSMenuItem>)anItem
|
||||
{
|
||||
menu_matrix = aMatrix;
|
||||
int row = [cells indexOfObject:anItem];
|
||||
float titleWidth;
|
||||
int i, count;
|
||||
|
||||
if (row == -1)
|
||||
return;
|
||||
|
||||
[cells removeObjectAtIndex:row];
|
||||
|
||||
/* Compute the new width of the menu cells matrix */
|
||||
cellSize.width = 0;
|
||||
count = [cells count];
|
||||
for (i = 0; i < count; i++) {
|
||||
titleWidth = [menuFont widthOfString:[cells objectAtIndex:i]];
|
||||
cellSize.width = MAX(titleWidth + ADDITIONAL_WIDTH, cellSize.width);
|
||||
}
|
||||
|
||||
[self _resizeMenuForCellSize];
|
||||
}
|
||||
|
||||
//
|
||||
// Finding Menu Items
|
||||
//
|
||||
- (id)cellWithTag:(int)aTag
|
||||
- (NSArray*)itemArray { return cells; }
|
||||
|
||||
- (id <NSMenuItem>)itemWithTitle:(NSString*)aString
|
||||
{
|
||||
int i, j;
|
||||
NSMenuCell *m, *found;
|
||||
int i, count = [cells count];
|
||||
id menuCell;
|
||||
|
||||
// Recursively find the menu cell with the tag
|
||||
found = nil;
|
||||
j = [menu_items count];
|
||||
for (i = 0;i < j; ++i)
|
||||
{
|
||||
m = [menu_items objectAtIndex:i];
|
||||
if ([m tag] == aTag) return m;
|
||||
if ([m hasSubmenu])
|
||||
found = [[m submenu] cellWithTag:aTag];
|
||||
if (found) return found;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
//
|
||||
// Building Submenus
|
||||
//
|
||||
- (NSMenuCell *)setSubmenu:(NSMenu *)aMenu
|
||||
forItem:(NSMenuCell *)aCell
|
||||
{
|
||||
int i, j;
|
||||
NSMenuCell *m;
|
||||
|
||||
j = [menu_items count];
|
||||
for (i = 0;i < j; ++i)
|
||||
{
|
||||
m = [menu_items objectAtIndex:i];
|
||||
if (m == aCell)
|
||||
{
|
||||
// Set the menucell's submenu
|
||||
[m setSubmenu:aMenu];
|
||||
|
||||
// Tell the submenu we are its supermenu
|
||||
[aMenu setSupermenu: self];
|
||||
|
||||
// Return the menucell
|
||||
return m;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
menuCell = [cells objectAtIndex:i];
|
||||
if ([[menuCell title] isEqual:aString])
|
||||
return menuCell;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)submenuAction:(id)sender
|
||||
{}
|
||||
|
||||
//
|
||||
// Managing NSMenu Windows
|
||||
//
|
||||
- (NSMenu *)attachedMenu
|
||||
- (id <NSMenuItem>)itemWithTag:(int)aTag
|
||||
{
|
||||
int i, count = [cells count];
|
||||
id menuCell;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
menuCell = [cells objectAtIndex:i];
|
||||
if ([menuCell tag] == aTag)
|
||||
return menuCell;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSRect)cellFrameAtRow:(int)index
|
||||
{
|
||||
NSRect rect;
|
||||
|
||||
rect.origin.x = 0;
|
||||
rect.origin.y = ([cells count] - index - 1)
|
||||
* (cellSize.height + INTERCELL_SPACE);
|
||||
rect.size = cellSize;
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)rect
|
||||
{
|
||||
int i, count = [cells count];
|
||||
NSRect intRect = {{0, 0}, {0, 0}};
|
||||
|
||||
intRect.size = cellSize;
|
||||
for (i = count - 1; i >= 0; i--) {
|
||||
id aCell = [cells objectAtIndex:i];
|
||||
|
||||
[aCell drawWithFrame:intRect inView:self];
|
||||
intRect.origin.y += cellSize.height + INTERCELL_SPACE;
|
||||
}
|
||||
[[self window] flushWindow];
|
||||
}
|
||||
|
||||
- (NSSize)cellSize { return cellSize; }
|
||||
- (void)setMenu:(NSMenu*)anObject { menu = anObject; }
|
||||
- (void)setSelectedCell:(id)aCell { ASSIGN(selectedCell, aCell); }
|
||||
- (id)selectedCell { return selectedCell; }
|
||||
- (NSRect)selectedCellRect { return selectedCellRect; }
|
||||
|
||||
@end /* NSMenuMatrix */
|
||||
|
||||
|
||||
@implementation NSMenu
|
||||
|
||||
// Class variables
|
||||
static NSZone *menuZone = NULL;
|
||||
static Class menuCellClass = nil;
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
menuCellClass = [NSMenuItem class];
|
||||
}
|
||||
|
||||
+ (void)setMenuZone:(NSZone*)zone
|
||||
{
|
||||
menuZone = zone;
|
||||
}
|
||||
|
||||
+ (NSZone*)menuZone
|
||||
{
|
||||
return menuZone;
|
||||
}
|
||||
|
||||
+ (void)setCellClass:(Class)aClass
|
||||
{
|
||||
menuCellClass = aClass;
|
||||
}
|
||||
|
||||
+ (Class)cellClass
|
||||
{
|
||||
return menuCellClass;
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
return [self initWithTitle:
|
||||
[[[NSProcessInfo processInfo] processName] lastPathComponent]];
|
||||
}
|
||||
|
||||
- (id)initWithTitle:(NSString*)aTitle
|
||||
{
|
||||
// SUBCLASS to initialize other "instance variables"
|
||||
NSRect rect = {{0, 0}, {80, 20}};
|
||||
|
||||
ASSIGN(title, aTitle);
|
||||
menuCells = [[NSMenuMatrix alloc] initWithFrame:rect];
|
||||
[menuCells setMenu:self];
|
||||
menuChangedMessagesEnabled = YES;
|
||||
autoenablesItems = YES;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
NSDebugLog (@"NSMenu '%@' dealloc", title);
|
||||
|
||||
[title release];
|
||||
[menuCells release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone*)zone
|
||||
{
|
||||
NSMenu* copy = NSAllocateObject (isa, 0, zone);
|
||||
int i, count;
|
||||
NSArray* cells;
|
||||
|
||||
NSDebugLog (@"copy menu with title '%@'", [self title]);
|
||||
|
||||
copy->title = [title copyWithZone:zone];
|
||||
|
||||
copy->menuCells = [menuCells copyWithZone:zone];
|
||||
[copy->menuCells setMenu:copy];
|
||||
|
||||
/* Change the supermenu object of the new cells to the new menu */
|
||||
cells = [copy->menuCells itemArray];
|
||||
for (i = 0, count = [cells count]; i < count; i++) {
|
||||
id cell = [cells objectAtIndex:i];
|
||||
|
||||
if ([cell hasSubmenu]) {
|
||||
NSMenu* submenu = [cell target];
|
||||
|
||||
submenu->supermenu = copy;
|
||||
}
|
||||
}
|
||||
|
||||
[copy->menuCells setFrame:[menuCells frame]];
|
||||
|
||||
copy->supermenu = supermenu;
|
||||
copy->attachedMenu = nil;
|
||||
copy->autoenablesItems = autoenablesItems;
|
||||
copy->menuChangedMessagesEnabled = menuChangedMessagesEnabled;
|
||||
copy->menuHasChanged = menuHasChanged;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
- (id <NSMenuItem>)addItemWithTitle:(NSString*)aString
|
||||
action:(SEL)aSelector
|
||||
keyEquivalent:(NSString*)charCode
|
||||
{
|
||||
return [self insertItemWithTitle:aString
|
||||
action:aSelector
|
||||
keyEquivalent:charCode
|
||||
atIndex:[[menuCells itemArray] count]];
|
||||
}
|
||||
|
||||
- (id <NSMenuItem>)insertItemWithTitle:(NSString*)aString
|
||||
action:(SEL)aSelector
|
||||
keyEquivalent:(NSString*)charCode
|
||||
atIndex:(unsigned int)index
|
||||
{
|
||||
id menuCell = [menuCells insertItemWithTitle:aString
|
||||
action:aSelector
|
||||
keyEquivalent:charCode
|
||||
atIndex:index];
|
||||
[self _menuChanged];
|
||||
|
||||
return menuCell;
|
||||
}
|
||||
|
||||
- (void)removeItem:(id <NSMenuItem>)anItem
|
||||
{
|
||||
[menuCells removeItem:anItem];
|
||||
[self _menuChanged];
|
||||
}
|
||||
|
||||
- (NSArray*)itemArray
|
||||
{
|
||||
return [menuCells itemArray];
|
||||
}
|
||||
|
||||
- (id <NSMenuItem>)itemWithTag:(int)aTag
|
||||
{
|
||||
return [menuCells itemWithTag:aTag];
|
||||
}
|
||||
|
||||
- (id <NSMenuItem>)itemWithTitle:(NSString*)aString
|
||||
{
|
||||
return [menuCells itemWithTitle:aString];
|
||||
}
|
||||
|
||||
- (void)setSubmenu:(NSMenu*)aMenu forItem:(id <NSMenuItem>)anItem
|
||||
{
|
||||
NSString* itemTitle = [anItem title];
|
||||
|
||||
[anItem setTarget:aMenu];
|
||||
[anItem setAction:@selector(submenuAction:)];
|
||||
if (aMenu)
|
||||
aMenu->supermenu = self;
|
||||
|
||||
[itemTitle retain];
|
||||
// [aMenu->title release];
|
||||
aMenu->title = itemTitle;
|
||||
|
||||
[self _menuChanged];
|
||||
}
|
||||
|
||||
- (void)submenuAction:(id)sender
|
||||
{
|
||||
// SUBCLASS
|
||||
}
|
||||
|
||||
- (NSMenu*)attachedMenu
|
||||
{
|
||||
return attachedMenu;
|
||||
}
|
||||
|
||||
- (BOOL)isAttached
|
||||
{
|
||||
return !is_torn_off;
|
||||
return supermenu && [supermenu attachedMenu] == self;
|
||||
}
|
||||
|
||||
- (BOOL)isTornOff
|
||||
{
|
||||
return is_torn_off;
|
||||
// SUBCLASS
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSPoint)locationForSubmenu:(NSMenu *)aSubmenu
|
||||
- (NSPoint)locationForSubmenu:(NSMenu*)aSubmenu
|
||||
{
|
||||
// SUBCLASS
|
||||
return NSZeroPoint;
|
||||
}
|
||||
|
||||
- (void)sizeToFit
|
||||
{}
|
||||
|
||||
- (NSMenu *)supermenu
|
||||
- (NSMenu*)supermenu
|
||||
{
|
||||
return super_menu;
|
||||
}
|
||||
|
||||
//
|
||||
// Displaying the Menu
|
||||
//
|
||||
- (BOOL)autoenablesItems
|
||||
{
|
||||
return autoenables_items;
|
||||
return supermenu;
|
||||
}
|
||||
|
||||
- (void)setAutoenablesItems:(BOOL)flag
|
||||
{
|
||||
autoenables_items = flag;
|
||||
autoenablesItems = flag;
|
||||
}
|
||||
|
||||
//
|
||||
// NSCoding protocol
|
||||
//
|
||||
- (void)encodeWithCoder:aCoder
|
||||
- (BOOL)autoenablesItems
|
||||
{
|
||||
[aCoder encodeObject: menu_items];
|
||||
|
||||
// Version 2
|
||||
[aCoder encodeObject: window_title];
|
||||
#if 0
|
||||
[aCoder encodeObjectReference: super_menu withName: @"SuperMenu"];
|
||||
#else
|
||||
[aCoder encodeConditionalObject:super_menu];
|
||||
#endif
|
||||
[aCoder encodeValueOfObjCType:@encode(BOOL) at: &autoenables_items];
|
||||
[aCoder encodeObject: menu_matrix];
|
||||
[aCoder encodeValueOfObjCType:@encode(BOOL) at: &is_torn_off];
|
||||
return autoenablesItems;
|
||||
}
|
||||
|
||||
- initWithCoder:aDecoder
|
||||
- (void)update
|
||||
{
|
||||
menu_items = [aDecoder decodeObject];
|
||||
// SUBCLASS to redisplay the menu
|
||||
|
||||
// Version 2
|
||||
window_title = [aDecoder decodeObject];
|
||||
#if 0
|
||||
[aDecoder decodeObjectAt: &super_menu withName: NULL];
|
||||
#else
|
||||
super_menu = [aDecoder decodeObject];
|
||||
#endif
|
||||
[aDecoder decodeValueOfObjCType:@encode(BOOL) at: &autoenables_items];
|
||||
menu_matrix = [aDecoder decodeObject];
|
||||
[aDecoder decodeValueOfObjCType:@encode(BOOL) at: &is_torn_off];
|
||||
id cells;
|
||||
int i, count;
|
||||
|
||||
if (![[NSApp mainMenu] autoenablesItems])
|
||||
return;
|
||||
|
||||
cells = [menuCells itemArray];
|
||||
count = [cells count];
|
||||
|
||||
/* Temporary disable automatic displaying of menu */
|
||||
[self setMenuChangedMessagesEnabled:NO];
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
id<NSMenuItem> cell = [cells objectAtIndex:i];
|
||||
SEL action = [cell action];
|
||||
id target;
|
||||
NSWindow* keyWindow;
|
||||
NSWindow* mainWindow;
|
||||
id responder;
|
||||
id delegate;
|
||||
BOOL found = NO;
|
||||
|
||||
/* Update the submenu items if any */
|
||||
if ([cell hasSubmenu]) {
|
||||
[[cell target] update];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!action) {
|
||||
[cell setEnabled:NO];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Search the target */
|
||||
if ((target = [cell target])) {
|
||||
if ([target respondsToSelector:action]) {
|
||||
if ([target respondsToSelector:@selector(validateMenuItem:)])
|
||||
[cell setEnabled:[target validateMenuItem:cell]];
|
||||
else
|
||||
[cell setEnabled:YES];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Search the key window's responder chain */
|
||||
keyWindow = [NSApp keyWindow];
|
||||
responder = [keyWindow firstResponder];
|
||||
while (responder && !found) {
|
||||
if ([responder respondsToSelector:action]) {
|
||||
if ([responder respondsToSelector:@selector(validateMenuItem:)])
|
||||
[cell setEnabled:[responder validateMenuItem:cell]];
|
||||
else
|
||||
[cell setEnabled:YES];
|
||||
found = YES;
|
||||
}
|
||||
responder = [responder nextResponder];
|
||||
}
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
/* Search the key window */
|
||||
if ([keyWindow respondsToSelector:action]) {
|
||||
if ([keyWindow respondsToSelector:@selector(validateMenuItem:)])
|
||||
[cell setEnabled:[keyWindow validateMenuItem:cell]];
|
||||
else
|
||||
[cell setEnabled:YES];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Search the key window's delegate */
|
||||
delegate = [keyWindow delegate];
|
||||
if ([delegate respondsToSelector:action]) {
|
||||
if ([delegate respondsToSelector:@selector(validateMenuItem:)])
|
||||
[cell setEnabled:[delegate validateMenuItem:cell]];
|
||||
else
|
||||
[cell setEnabled:YES];
|
||||
continue;
|
||||
}
|
||||
|
||||
mainWindow = [NSApp mainWindow];
|
||||
if (mainWindow != keyWindow) {
|
||||
/* Search the main window's responder chain */
|
||||
responder = [mainWindow firstResponder];
|
||||
while (responder && !found) {
|
||||
if ([responder respondsToSelector:action]) {
|
||||
if ([responder respondsToSelector:@selector(validateMenuItem:)])
|
||||
[cell setEnabled:[responder validateMenuItem:cell]];
|
||||
else
|
||||
[cell setEnabled:YES];
|
||||
found = YES;
|
||||
}
|
||||
|
||||
responder = [responder nextResponder];
|
||||
}
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
/* Search the main window */
|
||||
if ([mainWindow respondsToSelector:action]) {
|
||||
if ([mainWindow respondsToSelector:@selector(validateMenuItem:)])
|
||||
[cell setEnabled:[mainWindow validateMenuItem:cell]];
|
||||
else
|
||||
[cell setEnabled:YES];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Search the main window's delegate */
|
||||
delegate = [mainWindow delegate];
|
||||
if ([delegate respondsToSelector:action]) {
|
||||
if ([delegate respondsToSelector:@selector(validateMenuItem:)])
|
||||
[cell setEnabled:[delegate validateMenuItem:cell]];
|
||||
else
|
||||
[cell setEnabled:YES];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Search the NSApplication object */
|
||||
if ([NSApp respondsToSelector:action]) {
|
||||
if ([NSApp respondsToSelector:@selector(validateMenuItem:)])
|
||||
[cell setEnabled:[NSApp validateMenuItem:cell]];
|
||||
else
|
||||
[cell setEnabled:YES];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Search the NSApplication object's delegate */
|
||||
delegate = [NSApp delegate];
|
||||
if ([delegate respondsToSelector:action]) {
|
||||
if ([delegate respondsToSelector:@selector(validateMenuItem:)])
|
||||
[cell setEnabled:[delegate validateMenuItem:cell]];
|
||||
else
|
||||
[cell setEnabled:YES];
|
||||
continue;
|
||||
}
|
||||
|
||||
[cell setEnabled:NO];
|
||||
}
|
||||
|
||||
/* Reenable displaying of menus */
|
||||
[self setMenuChangedMessagesEnabled:YES];
|
||||
|
||||
[self sizeToFit];
|
||||
}
|
||||
|
||||
- (void)performActionForItem:(id <NSMenuItem>)cell
|
||||
{
|
||||
SEL action;
|
||||
id target;
|
||||
NSWindow* keyWindow;
|
||||
NSWindow* mainWindow;
|
||||
id responder;
|
||||
id delegate;
|
||||
|
||||
if (![cell isEnabled])
|
||||
return;
|
||||
|
||||
action = [cell action];
|
||||
|
||||
/* Search the target */
|
||||
if ((target = [cell target]) && [target respondsToSelector:action]) {
|
||||
[target perform:action withObject:cell];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Search the key window's responder chain */
|
||||
keyWindow = [NSApp keyWindow];
|
||||
responder = [keyWindow firstResponder];
|
||||
while (responder) {
|
||||
if ([responder respondsToSelector:action]) {
|
||||
[responder perform:action withObject:cell];
|
||||
return;
|
||||
}
|
||||
responder = [responder nextResponder];
|
||||
}
|
||||
|
||||
/* Search the key window */
|
||||
if ([keyWindow respondsToSelector:action]) {
|
||||
[keyWindow perform:action withObject:cell];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Search the key window's delegate */
|
||||
delegate = [keyWindow delegate];
|
||||
if ([delegate respondsToSelector:action]) {
|
||||
[delegate perform:action withObject:cell];
|
||||
return;
|
||||
}
|
||||
|
||||
mainWindow = [NSApp mainWindow];
|
||||
if (mainWindow != keyWindow) {
|
||||
/* Search the main window's responder chain */
|
||||
responder = [mainWindow firstResponder];
|
||||
while (responder) {
|
||||
if ([responder respondsToSelector:action]) {
|
||||
[responder perform:action withObject:cell];
|
||||
return;
|
||||
}
|
||||
responder = [responder nextResponder];
|
||||
}
|
||||
|
||||
/* Search the main window */
|
||||
if ([mainWindow respondsToSelector:action]) {
|
||||
[mainWindow perform:action withObject:cell];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Search the main window's delegate */
|
||||
delegate = [mainWindow delegate];
|
||||
if ([delegate respondsToSelector:action]) {
|
||||
[delegate perform:action withObject:cell];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Search the NSApplication object */
|
||||
if ([NSApp respondsToSelector:action]) {
|
||||
[NSApp perform:action withObject:cell];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Search the NSApplication object's delegate */
|
||||
delegate = [NSApp delegate];
|
||||
if ([delegate respondsToSelector:action]) {
|
||||
[delegate perform:action withObject:cell];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent
|
||||
{
|
||||
id cells = [menuCells itemArray];
|
||||
int i, count = [cells count];
|
||||
NSEventType type = [theEvent type];
|
||||
|
||||
if (type != NSKeyDown || type != NSKeyUp)
|
||||
return NO;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
id<NSMenuItem> cell = [cells objectAtIndex:i];
|
||||
|
||||
if ([cell hasSubmenu]) {
|
||||
if ([[cell target] performKeyEquivalent:theEvent])
|
||||
/* The event has been handled by a cell in submenu */
|
||||
return YES;
|
||||
}
|
||||
else {
|
||||
if ([[cell keyEquivalent] isEqual:[theEvent charactersIgnoringModifiers]]
|
||||
&& [cell keyEquivalentModifierMask] == [theEvent modifierFlags]) {
|
||||
[menuCells lockFocus];
|
||||
[(id)cell performClick:self];
|
||||
[menuCells unlockFocus];
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)setMenuChangedMessagesEnabled:(BOOL)flag
|
||||
{
|
||||
menuChangedMessagesEnabled = flag;
|
||||
}
|
||||
|
||||
- (BOOL)menuChangedMessagesEnabled
|
||||
{
|
||||
return menuChangedMessagesEnabled;
|
||||
}
|
||||
|
||||
- (void)sizeToFit
|
||||
{
|
||||
// SUBCLASS
|
||||
menuHasChanged = NO;
|
||||
}
|
||||
|
||||
- (NSString*)title
|
||||
{
|
||||
return title;
|
||||
}
|
||||
|
||||
- (NSMenuMatrix*)menuCells
|
||||
{
|
||||
return menuCells;
|
||||
}
|
||||
|
||||
- initWithCoder:(NSCoder*)aDecoder
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSMenu (GNUstepPrivate)
|
||||
|
||||
- (void)setSupermenu:(NSMenu *)obj
|
||||
- (void)encodeWithCoder:(NSCoder*)aCoder
|
||||
{
|
||||
super_menu = obj;
|
||||
}
|
||||
|
||||
@end /* NSMenu */
|
||||
|
||||
|
||||
@implementation NSMenu (PrivateMethods2)
|
||||
- (void)_menuChanged
|
||||
{
|
||||
menuHasChanged = YES;
|
||||
if (menuChangedMessagesEnabled)
|
||||
[self sizeToFit];
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
/*
|
||||
NSMenuCell.m
|
||||
|
||||
Cell class for menu items
|
||||
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
|
||||
Author: Scott Christley <scottc@net-community.com>
|
||||
Date: 1996
|
||||
|
||||
This file is part of the GNUstep GUI Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB.
|
||||
If not, write to the Free Software Foundation,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <Foundation/NSCoder.h>
|
||||
#include <AppKit/NSMenuCell.h>
|
||||
#include <AppKit/NSMenu.h>
|
||||
|
||||
//
|
||||
// Class variables
|
||||
//
|
||||
static BOOL MB_NSMENUCELL_USES_KEY = NO;
|
||||
|
||||
@implementation NSMenuCell
|
||||
|
||||
//
|
||||
// Class methods
|
||||
//
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self == [NSMenuCell class])
|
||||
{
|
||||
// Initial version
|
||||
[self setVersion:1];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Managing User Key Equivalents
|
||||
//
|
||||
+ (void)setUsesUserKeyEquivalents:(BOOL)flag
|
||||
{
|
||||
MB_NSMENUCELL_USES_KEY = flag;
|
||||
}
|
||||
|
||||
+ (BOOL)usesUserKeyEquivalents
|
||||
{
|
||||
return MB_NSMENUCELL_USES_KEY;
|
||||
}
|
||||
|
||||
//
|
||||
// Instance methods
|
||||
//
|
||||
- (unsigned int)menuIdentifier
|
||||
{
|
||||
return menu_identifier;
|
||||
}
|
||||
|
||||
- (void)setMenuIdentifier:(unsigned int)theID
|
||||
{
|
||||
menu_identifier = theID;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialization
|
||||
//
|
||||
- init
|
||||
{
|
||||
return [self initTextCell:@"Text"];
|
||||
}
|
||||
|
||||
- initTextCell:(NSString *)aString
|
||||
{
|
||||
[super initTextCell:aString];
|
||||
[self setEnabled:YES];
|
||||
sub_menu = nil;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[sub_menu release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
//
|
||||
// Checking for a Submenu
|
||||
//
|
||||
- (BOOL)hasSubmenu
|
||||
{
|
||||
if (sub_menu)
|
||||
return YES;
|
||||
else
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSMenu *)submenu
|
||||
{
|
||||
return sub_menu;
|
||||
}
|
||||
|
||||
- (void)setSubmenu:(NSMenu *)aMenu
|
||||
{
|
||||
[sub_menu release];
|
||||
sub_menu = aMenu;
|
||||
[sub_menu retain];
|
||||
}
|
||||
|
||||
- (NSString *)userKeyEquivalent
|
||||
{
|
||||
return key_equivalent;
|
||||
}
|
||||
|
||||
//
|
||||
// NSCoding protocol
|
||||
//
|
||||
- (void)encodeWithCoder:aCoder
|
||||
{
|
||||
[super encodeWithCoder:aCoder];
|
||||
|
||||
[aCoder encodeObject: key_equivalent];
|
||||
[aCoder encodeObject: sub_menu];
|
||||
[aCoder encodeValueOfObjCType: "I" at: &menu_identifier];
|
||||
}
|
||||
|
||||
- initWithCoder:aDecoder
|
||||
{
|
||||
[super initWithCoder:aDecoder];
|
||||
|
||||
key_equivalent = [aDecoder decodeObject];
|
||||
sub_menu = [aDecoder decodeObject];
|
||||
[aDecoder decodeValueOfObjCType: "I" at: &menu_identifier];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
157
Source/NSMenuItem.m
Normal file
157
Source/NSMenuItem.m
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
NSMenuItem.m
|
||||
|
||||
The menu cell class.
|
||||
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
|
||||
Author: Ovidiu Predescu <ovidiu@net-community.com>
|
||||
Date: May 1997
|
||||
|
||||
This file is part of the GNUstep GUI Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB.
|
||||
If not, write to the Free Software Foundation,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSDictionary.h>
|
||||
#include <AppKit/NSMenuItem.h>
|
||||
#include <AppKit/NSMenu.h>
|
||||
|
||||
#define ASSIGN(variable, value) \
|
||||
[value retain]; \
|
||||
[variable release]; \
|
||||
variable = value;
|
||||
|
||||
static BOOL usesUserKeyEquivalents = YES;
|
||||
|
||||
@implementation NSMenuItem
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self == [NSMenuItem class])
|
||||
{
|
||||
// Initial version
|
||||
[self setVersion:2];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)setUsesUserKeyEquivalents:(BOOL)flag
|
||||
{
|
||||
usesUserKeyEquivalents = flag;
|
||||
}
|
||||
|
||||
+ (BOOL)usesUserKeyEquivalents
|
||||
{
|
||||
return usesUserKeyEquivalents;
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
[self setAlignment:NSLeftTextAlignment];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
NSDebugLog (@"NSMenuItem '%@' dealloc", [self title]);
|
||||
|
||||
[representedObject release];
|
||||
if (hasSubmenu)
|
||||
[[self target] release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone*)zone
|
||||
{
|
||||
NSMenuItem* copy = [super copyWithZone:zone];
|
||||
|
||||
NSDebugLog (@"menu item '%@' copy", [self title]);
|
||||
copy->representedObject = [representedObject retain];
|
||||
copy->hasSubmenu = hasSubmenu;
|
||||
if (hasSubmenu) {
|
||||
id submenu = [[target copyWithZone:zone] autorelease];
|
||||
[copy setTarget:submenu];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
- (void)setTarget:(id)anObject
|
||||
{
|
||||
hasSubmenu = anObject && [anObject isKindOfClass:[NSMenu class]];
|
||||
if (hasSubmenu) {
|
||||
[anObject retain];
|
||||
[[self target] release];
|
||||
}
|
||||
[super setTarget:anObject];
|
||||
}
|
||||
|
||||
- (void)setTitle:(NSString*)aString
|
||||
{
|
||||
[super setStringValue:aString];
|
||||
}
|
||||
|
||||
- (NSString*)title
|
||||
{
|
||||
return [self stringValue];
|
||||
}
|
||||
|
||||
- (BOOL)hasSubmenu
|
||||
{
|
||||
return hasSubmenu;
|
||||
}
|
||||
|
||||
- (BOOL)isEnabled
|
||||
{
|
||||
if (hasSubmenu)
|
||||
return YES;
|
||||
else
|
||||
return [super isEnabled];
|
||||
}
|
||||
|
||||
- (NSString*)keyEquivalent
|
||||
{
|
||||
if (usesUserKeyEquivalents)
|
||||
return [self userKeyEquivalent];
|
||||
else
|
||||
return [super keyEquivalent];
|
||||
}
|
||||
|
||||
- (NSString*)userKeyEquivalent
|
||||
{
|
||||
NSString* userKeyEquivalent = [[[[NSUserDefaults standardUserDefaults]
|
||||
persistentDomainForName:NSGlobalDomain]
|
||||
objectForKey:@"NSCommandKeys"]
|
||||
objectForKey:[self stringValue]];
|
||||
|
||||
if (!userKeyEquivalent)
|
||||
userKeyEquivalent = [super keyEquivalent];
|
||||
|
||||
return userKeyEquivalent;
|
||||
}
|
||||
|
||||
- (void)setRepresentedObject:(id)anObject
|
||||
{
|
||||
ASSIGN(representedObject, anObject);
|
||||
}
|
||||
|
||||
- (id)representedObject
|
||||
{
|
||||
return representedObject;
|
||||
}
|
||||
|
||||
@end
|
File diff suppressed because it is too large
Load diff
135
Source/NSView.m
135
Source/NSView.m
|
@ -153,13 +153,13 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification";
|
|||
bounds.size = frame.size;
|
||||
|
||||
// Initialize subview list
|
||||
sub_views = [NSMutableArray array];
|
||||
sub_views = [NSMutableArray new];
|
||||
|
||||
// Initialize tracking rectangle list
|
||||
tracking_rects = [NSMutableArray array];
|
||||
tracking_rects = [NSMutableArray new];
|
||||
|
||||
// Initialize cursor rect list
|
||||
cursor_rects = [NSMutableArray array];
|
||||
cursor_rects = [NSMutableArray new];
|
||||
|
||||
super_view = nil;
|
||||
window = nil;
|
||||
|
@ -177,26 +177,9 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification";
|
|||
|
||||
- (void)dealloc
|
||||
{
|
||||
int i, j;
|
||||
|
||||
//NSArray doesn't know -removeAllObjects yet
|
||||
//[sub_views removeAllObjects];
|
||||
j = [sub_views count];
|
||||
for (i = 0;i < j; ++i)
|
||||
[[sub_views objectAtIndex:i] release];
|
||||
|
||||
// no need -array is autoreleased
|
||||
//[sub_views release];
|
||||
|
||||
// Free the tracking rectangles
|
||||
j = [tracking_rects count];
|
||||
for (i = 0;i < j; ++i)
|
||||
[[tracking_rects objectAtIndex:i] release];
|
||||
|
||||
// Free the cursor rectangles
|
||||
j = [cursor_rects count];
|
||||
for (i = 0;i < j; ++i)
|
||||
[[cursor_rects objectAtIndex:i] release];
|
||||
[sub_views release];
|
||||
[tracking_rects release];
|
||||
[cursor_rects release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
@ -224,9 +207,6 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification";
|
|||
return;
|
||||
}
|
||||
|
||||
// retain the object
|
||||
[aView retain];
|
||||
|
||||
// Add to our subview list
|
||||
[sub_views addObject:(id)aView];
|
||||
[aView setSuperview:self];
|
||||
|
@ -246,9 +226,6 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification";
|
|||
if (![aView isKindOfClass:[NSView class]]) return;
|
||||
#endif
|
||||
|
||||
// retain the object
|
||||
[aView retain];
|
||||
|
||||
// Add to our subview list
|
||||
[sub_views addObject:(id)aView];
|
||||
[aView setSuperview:self];
|
||||
|
@ -314,52 +291,22 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification";
|
|||
|
||||
- (void)removeFromSuperview
|
||||
{
|
||||
int i, j;
|
||||
NSMutableArray *v;
|
||||
NSMutableArray *views;
|
||||
|
||||
// No superview then just return
|
||||
if (!super_view) return;
|
||||
|
||||
v = [super_view subviews];
|
||||
j = [v count];
|
||||
for (i = 0;i < j; ++i)
|
||||
{
|
||||
if ([v objectAtIndex:i] == self)
|
||||
[v removeObjectAtIndex:i];
|
||||
}
|
||||
views = [super_view subviews];
|
||||
[views removeObjectIdenticalTo:self];
|
||||
}
|
||||
|
||||
- (void)replaceSubview:(NSView *)oldView
|
||||
with:(NSView *)newView
|
||||
{
|
||||
int i, j;
|
||||
NSView *v;
|
||||
int index = [sub_views indexOfObjectIdenticalTo:oldView];
|
||||
|
||||
// Not a NSView --then forget it
|
||||
// xxx but NSView will really be the backend class
|
||||
// so how do we check that its really a subclass of NSView
|
||||
// and not of the backend class?
|
||||
#if 0
|
||||
if (![newView isKindOfClass:[NSView class]]) return;
|
||||
#endif
|
||||
|
||||
j = [sub_views count];
|
||||
for (i = 0;i < j; ++i)
|
||||
{
|
||||
v = [sub_views objectAtIndex:i];
|
||||
if (v == oldView)
|
||||
{
|
||||
// Found it then replace
|
||||
[sub_views replaceObjectAtIndex:i withObject:newView];
|
||||
// release it as well
|
||||
[v release];
|
||||
// and retain the new view
|
||||
[newView retain];
|
||||
}
|
||||
else
|
||||
// Didn't find then pass down view hierarchy
|
||||
[v replaceSubview:oldView with:newView];
|
||||
}
|
||||
if (index != NSNotFound)
|
||||
[sub_views replaceObjectAtIndex:index withObject:newView];
|
||||
}
|
||||
|
||||
- (void)sortSubviewsUsingFunction:(int (*)(id ,id ,void *))compare
|
||||
|
@ -378,14 +325,6 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification";
|
|||
|
||||
- (void)setSuperview:(NSView *)superview
|
||||
{
|
||||
// Not a NSView --then forget it
|
||||
// xxx but NSView will really be the backend class
|
||||
// so how do we check that its really a subclass of NSView
|
||||
// and not of the backend class?
|
||||
#if 0
|
||||
if (![superview isKindOfClass:[NSView class]]) return;
|
||||
#endif
|
||||
|
||||
super_view = superview;
|
||||
}
|
||||
|
||||
|
@ -400,16 +339,13 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification";
|
|||
|
||||
- (void)viewWillMoveToWindow:(NSWindow *)newWindow
|
||||
{
|
||||
int i, j;
|
||||
|
||||
// not a window --then forget it
|
||||
// if (![newWindow isKindOfClass:[NSWindow class]]) return;
|
||||
int i, count;
|
||||
|
||||
window = newWindow;
|
||||
|
||||
// Pass new window down to subviews
|
||||
j = [sub_views count];
|
||||
for (i = 0;i < j; ++i)
|
||||
count = [sub_views count];
|
||||
for (i = 0; i < count; ++i)
|
||||
[[sub_views objectAtIndex:i] viewWillMoveToWindow:newWindow];
|
||||
|
||||
}
|
||||
|
@ -900,8 +836,9 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification";
|
|||
{
|
||||
TrackingRectangle *m;
|
||||
|
||||
m = [[TrackingRectangle alloc] initWithRect: aRect tag: 0 owner: anObject
|
||||
userData: NULL inside: YES];
|
||||
m = [[[TrackingRectangle alloc] initWithRect: aRect tag: 0 owner: anObject
|
||||
userData: NULL inside: YES]
|
||||
autorelease];
|
||||
[cursor_rects addObject:m];
|
||||
}
|
||||
|
||||
|
@ -916,21 +853,18 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification";
|
|||
id e = [cursor_rects objectEnumerator];
|
||||
TrackingRectangle *o;
|
||||
NSCursor *c;
|
||||
BOOL found = NO;
|
||||
|
||||
// Base remove test upon cursor object
|
||||
o = [e nextObject];
|
||||
while (o && (!found))
|
||||
{
|
||||
c = [o owner];
|
||||
if (c == anObject)
|
||||
found = YES;
|
||||
else
|
||||
o = [e nextObject];
|
||||
while (o) {
|
||||
c = [o owner];
|
||||
if (c == anObject) {
|
||||
[cursor_rects removeObject: o];
|
||||
break;
|
||||
}
|
||||
|
||||
if (found)
|
||||
[cursor_rects removeObject: o];
|
||||
else
|
||||
o = [e nextObject];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)resetCursorRects
|
||||
|
@ -951,13 +885,15 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification";
|
|||
|
||||
- (id)viewWithTag:(int)aTag
|
||||
{
|
||||
int i, j;
|
||||
int i, count;
|
||||
|
||||
j = [sub_views count];
|
||||
for (i = 0;i < j; ++i)
|
||||
count = [sub_views count];
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
if ([[sub_views objectAtIndex:i] tag] == aTag)
|
||||
return [sub_views objectAtIndex:i];
|
||||
id view = [sub_views objectAtIndex:i];
|
||||
|
||||
if ([view tag] == aTag)
|
||||
return view;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
@ -1062,8 +998,9 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification";
|
|||
}
|
||||
++t;
|
||||
|
||||
m = [[TrackingRectangle alloc] initWithRect:aRect tag:t owner:anObject
|
||||
userData:data inside:flag];
|
||||
m = [[[TrackingRectangle alloc] initWithRect:aRect tag:t owner:anObject
|
||||
userData:data inside:flag]
|
||||
autorelease];
|
||||
[tracking_rects addObject:m];
|
||||
|
||||
return t;
|
||||
|
|
|
@ -30,8 +30,10 @@
|
|||
#include <Foundation/NSCoder.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSNotification.h>
|
||||
|
||||
#include <AppKit/NSWindow.h>
|
||||
#include <AppKit/NSApplication.h>
|
||||
#include <AppKit/NSImage.h>
|
||||
#include <AppKit/NSTextFieldCell.h>
|
||||
#include <AppKit/NSTextField.h>
|
||||
#include <AppKit/NSColor.h>
|
||||
|
@ -56,6 +58,11 @@ NSString *NSWindowWillCloseNotification = @"WindowWillClose";
|
|||
NSString *NSWindowWillMiniaturizeNotification = @"WindowWillMiniaturize";
|
||||
NSString *NSWindowWillMoveNotification = @"WindowWillMove";
|
||||
|
||||
#define ASSIGN(variable, value) \
|
||||
[value retain]; \
|
||||
[variable release]; \
|
||||
variable = value;
|
||||
|
||||
//
|
||||
// NSWindow implementation
|
||||
//
|
||||
|
@ -125,17 +132,15 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
|
|||
|
||||
- (void)dealloc
|
||||
{
|
||||
NSApplication *theApp = [NSApplication sharedApplication];
|
||||
|
||||
NSDebugLog(@"Remove NSWindow from application\n");
|
||||
// Remove ourselves from the application window list
|
||||
[theApp removeWindowsItem:self];
|
||||
|
||||
// Release the content view
|
||||
NSDebugLog(@"Release content view\n");
|
||||
if (content_view) [content_view release];
|
||||
|
||||
NSDebugLog(@"NSWindow dealloc super\n");
|
||||
[background_color release];
|
||||
[represented_filename release];
|
||||
[miniaturized_title release];
|
||||
[miniaturized_image release];
|
||||
[window_title release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -160,6 +165,7 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
|
|||
{
|
||||
NSApplication *theApp = [NSApplication sharedApplication];
|
||||
NSRect r = [[NSScreen mainScreen] frame];
|
||||
NSRect cframe;
|
||||
|
||||
NSDebugLog(@"NSWindow default initializer\n");
|
||||
if (!theApp)
|
||||
|
@ -186,7 +192,9 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
|
|||
cursor_rects_valid = NO;
|
||||
|
||||
// Create our content view
|
||||
[self setContentView:[[NSView alloc] initWithFrame:frame]];
|
||||
cframe.origin = NSZeroPoint;
|
||||
cframe.size = frame.size;
|
||||
[self setContentView:[[[NSView alloc] initWithFrame:cframe] autorelease]];
|
||||
|
||||
// Register ourselves with the Application object
|
||||
[theApp addWindowsItem:self title:window_title filename:NO];
|
||||
|
@ -205,22 +213,14 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
|
|||
|
||||
- (void)setContentView:(NSView *)aView
|
||||
{
|
||||
// Not an NSView -then forget it
|
||||
if (![aView isKindOfClass:[NSView class]])
|
||||
return;
|
||||
|
||||
// Release current content view
|
||||
if (content_view)
|
||||
{
|
||||
// Tell view it is no longer in a window
|
||||
[content_view viewWillMoveToWindow:nil];
|
||||
[content_view release];
|
||||
}
|
||||
[content_view viewWillMoveToWindow:nil];
|
||||
|
||||
ASSIGN(content_view, aView);
|
||||
|
||||
content_view = aView;
|
||||
[content_view retain];
|
||||
// Tell the view its changing windows
|
||||
[content_view viewWillMoveToWindow:self];
|
||||
|
||||
// Make us the view's next responder
|
||||
[content_view setNextResponder:self];
|
||||
}
|
||||
|
@ -240,17 +240,17 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
|
|||
|
||||
- (void)setBackgroundColor:(NSColor *)color
|
||||
{
|
||||
background_color = color;
|
||||
ASSIGN(background_color, color);
|
||||
}
|
||||
|
||||
- (void)setRepresentedFilename:(NSString *)aString
|
||||
{
|
||||
represented_filename = aString;
|
||||
ASSIGN(represented_filename, aString);
|
||||
}
|
||||
|
||||
- (void)setTitle:(NSString *)aString
|
||||
{
|
||||
window_title = aString;
|
||||
ASSIGN(window_title, aString);
|
||||
}
|
||||
|
||||
- (void)setTitleWithRepresentedFilename:(NSString *)aString
|
||||
|
@ -327,12 +327,12 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
|
|||
|
||||
- (void)setMiniwindowImage:(NSImage *)image
|
||||
{
|
||||
miniaturized_image = image;
|
||||
ASSIGN(miniaturized_image, image);
|
||||
}
|
||||
|
||||
- (void)setMiniwindowTitle:(NSString *)title;
|
||||
{
|
||||
miniaturized_title = title;
|
||||
ASSIGN(miniaturized_title, title);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -469,7 +469,7 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
|
|||
|
||||
- (void)orderOut:sender
|
||||
{
|
||||
visible = YES;
|
||||
visible = NO;
|
||||
}
|
||||
|
||||
- (void)orderWindow:(NSWindowOrderingMode)place
|
||||
|
@ -636,7 +636,7 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
|
|||
|
||||
- (void)flushWindowIfNeeded
|
||||
{
|
||||
if (!disable_flush_window)
|
||||
if (!disable_flush_window && needs_flush)
|
||||
[self flushWindow];
|
||||
}
|
||||
|
||||
|
@ -1344,6 +1344,9 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
|
|||
- (void)print:sender
|
||||
{}
|
||||
|
||||
- (void)_setNeedsFlush:(BOOL)flag { needs_flush = flag; }
|
||||
- (BOOL)_needsFlush { return needs_flush; }
|
||||
|
||||
//
|
||||
// Assigning a delegate
|
||||
//
|
||||
|
@ -1577,6 +1580,11 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
|
|||
//
|
||||
@implementation NSWindow (GNUstepBackend)
|
||||
|
||||
+ (NSWindow*)windowWithNumber:(int)windowNumber
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
//
|
||||
// Mouse capture/release
|
||||
//
|
||||
|
@ -1598,7 +1606,7 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
|
|||
original_responder = nil;
|
||||
delegate = nil;
|
||||
window_num = 0;
|
||||
background_color = [NSColor lightGrayColor];
|
||||
background_color = [[NSColor lightGrayColor] retain];
|
||||
represented_filename = @"Window";
|
||||
miniaturized_title = @"Window";
|
||||
miniaturized_image = nil;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue