Various updates to get keyboard equivalents for buttons working (especially

for panels).


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@3461 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 1998-12-15 16:20:22 +00:00
parent 958d1bf294
commit bf5137b858
7 changed files with 357 additions and 233 deletions

View file

@ -1,3 +1,13 @@
Tue Dec 15 16:30:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* NSApplication.m: Terminate modal loop if the window goes away.
* NSButton.m: Handle key equivalents.
* NSButtonCell.m: Handle key equivalents.
* NSCell.m: implement ([-performClick:]) method.
* NSPanel.m: Close closable panels when user hits escape key.
handle keyboard shortcut for default option.
* NSWindow.m: Fix bug causing app to terminate when it shouldn't.
Mon Dec 14 16:15:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk> Mon Dec 14 16:15:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* GSServicesMnager.m: Added alert panels to display error messages * GSServicesMnager.m: Added alert panels to display error messages

View file

@ -345,10 +345,10 @@ static int code;
- (int) runModalSession: (NSModalSession)theSession - (int) runModalSession: (NSModalSession)theSession
{ {
BOOL found = NO; BOOL found = NO;
NSEvent *event; NSEvent *event;
unsigned count; unsigned count;
unsigned i; unsigned i;
if (theSession != session) if (theSession != session)
[NSException raise: NSInvalidArgumentException [NSException raise: NSInvalidArgumentException
@ -358,9 +358,13 @@ unsigned i;
[theSession->window display]; [theSession->window display];
[theSession->window makeKeyAndOrderFront: self]; [theSession->window makeKeyAndOrderFront: self];
do { // First we make sure // First we make sure
count = [event_queue count]; // that there is an // that there is an
for (i = 0; i < count; i++) // event. // event.
do
{
count = [event_queue count];
for (i = 0; i < count; i++)
{ {
event = [event_queue objectAtIndex: 0]; event = [event_queue objectAtIndex: 0];
if ([event window] == theSession->window) if ([event window] == theSession->window)
@ -368,8 +372,12 @@ unsigned i;
found = YES; found = YES;
break; break;
} }
else // dump events not for else
[event_queue removeObjectAtIndex:0]; // the modal window {
// dump events not for
// the modal window
[event_queue removeObjectAtIndex: 0];
}
} }
if (found == NO) if (found == NO)
@ -407,10 +415,14 @@ unsigned i;
{ {
[self sendEvent: current_event]; [self sendEvent: current_event];
/*
* Check to see if the window has gone away - if so, end session.
*/
if ([window_list indexOfObjectIdenticalTo: session->window] ==
NSNotFound || [session->window isVisible] == NO)
[self stopModal];
if (windows_need_update) if (windows_need_update)
[self updateWindows]; [self updateWindows];
/* xxx should we update the services menu? */
[listener updateServicesMenu];
} }
[pool release]; [pool release];
@ -1093,7 +1105,7 @@ int i;
{ {
} }
- (void)removeWindowsItem:aWindow - (void) removeWindowsItem: (NSWindow*)aWindow
{ {
if (aWindow == key_window) // This should be different if (aWindow == key_window) // This should be different
key_window = nil; key_window = nil;

View file

@ -263,32 +263,62 @@ id gnustep_gui_nsbutton_class = nil;
// //
// Setting the Key Equivalent // Setting the Key Equivalent
// //
- (NSString *)keyEquivalent - (NSString*) keyEquivalent
{ {
return nil; return [cell keyEquivalent];
} }
- (unsigned int)keyEquivalentModifierMask - (unsigned int) keyEquivalentModifierMask
{ {
return 0; return [cell keyEquivalentModifierMask];
} }
- (void)setKeyEquivalent:(NSString *)aKeyEquivalent - (void) setKeyEquivalent: (NSString*)aKeyEquivalent
{} {
[cell setKeyEquivalent: aKeyEquivalent];
}
- (void)setKeyEquivalentModifierMask:(unsigned int)mask - (void) setKeyEquivalentModifierMask: (unsigned int)mask
{} {
[cell setKeyEquivalentModifierMask: mask];
}
// //
// Handling Events and Action Messages // Handling Events and Action Messages
// //
- (void)performClick:(id)sender - (BOOL)acceptsFirstResponder
{ {
[cell performClick:sender]; return [self keyEquivalent] != nil;;
} }
- (BOOL)performKeyEquivalent:(NSEvent *)anEvent - (void) keyDown: (NSEvent*)theEvent
{ {
if ([self performKeyEquivalent: theEvent] == NO)
[super keyDown: theEvent];
}
- (void) performClick: (id)sender
{
[cell performClick: sender];
}
- (BOOL) performKeyEquivalent: (NSEvent *)anEvent
{
if ([self isEnabled])
{
NSString *key = [self keyEquivalent];
if (key != nil && [key isEqual: [anEvent charactersIgnoringModifiers]])
{
unsigned int mask = [self keyEquivalentModifierMask];
if (([anEvent modifierFlags] & mask) == mask)
{
[self performClick: self];
return YES;
}
}
}
return NO; return NO;
} }

View file

@ -33,6 +33,7 @@
#include <Foundation/NSLock.h> #include <Foundation/NSLock.h>
#include <Foundation/NSArray.h> #include <Foundation/NSArray.h>
#include <Foundation/NSString.h> #include <Foundation/NSString.h>
#include <Foundation/NSException.h>
#include <AppKit/NSButtonCell.h> #include <AppKit/NSButtonCell.h>
#include <AppKit/NSButton.h> #include <AppKit/NSButton.h>
@ -154,35 +155,67 @@ NSString* _string = [aString copy];
[self setContinuous:YES]; [self setContinuous:YES];
} }
- (void) performClick: (id)sender
{
NSView *cv = [self controlView];
[self highlight: YES withFrame: [cv frame] inView: cv];
if (action && target)
{
NS_DURING
{
[(NSControl*)cv sendAction: action to: target];
}
NS_HANDLER
{
[self highlight: NO withFrame: [cv frame] inView: cv];
[localException raise];
}
NS_ENDHANDLER
}
[self highlight: NO withFrame: [cv frame] inView: cv];
}
// //
// Setting the Key Equivalent // Setting the Key Equivalent
// //
- (NSString *)keyEquivalent { return keyEquivalent; } - (NSString*) keyEquivalent
- (NSFont *)keyEquivalentFont { return keyEquivalentFont; } {
return keyEquivalent;
}
- (unsigned int)keyEquivalentModifierMask - (NSFont*) keyEquivalentFont
{
return keyEquivalentFont;
}
- (unsigned int) keyEquivalentModifierMask
{ {
return keyEquivalentModifierMask; return keyEquivalentModifierMask;
} }
- (void)setKeyEquivalent:(NSString *)key - (void) setKeyEquivalent: (NSString*)key
{ {
ASSIGN(keyEquivalent, [key copy]); if (keyEquivalent != key)
{
[keyEquivalent release];
keyEquivalent = [key copy];
}
} }
- (void)setKeyEquivalentModifierMask:(unsigned int)mask - (void) setKeyEquivalentModifierMask: (unsigned int)mask
{ {
keyEquivalentModifierMask = mask; keyEquivalentModifierMask = mask;
} }
- (void)setKeyEquivalentFont:(NSFont *)fontObj - (void) setKeyEquivalentFont: (NSFont*)fontObj
{ {
ASSIGN(keyEquivalentFont, fontObj); ASSIGN(keyEquivalentFont, fontObj);
} }
- (void)setKeyEquivalentFont:(NSString *)fontName size:(float)fontSize - (void) setKeyEquivalentFont: (NSString*)fontName size: (float)fontSize
{ {
ASSIGN(keyEquivalentFont, [NSFont fontWithName:fontName size:fontSize]); ASSIGN(keyEquivalentFont, [NSFont fontWithName: fontName size: fontSize]);
} }
// //
@ -272,13 +305,6 @@ NSString* _string = [aString copy];
control_view = controlView; // Save last view cell was drawn to control_view = controlView; // Save last view cell was drawn to
} }
//
// Simulating a Click
//
- (void)performClick:(id)sender
{
}
- (id)copyWithZone:(NSZone*)zone - (id)copyWithZone:(NSZone*)zone
{ {
NSButtonCell* c = [super copyWithZone:zone]; NSButtonCell* c = [super copyWithZone:zone];

View file

@ -30,6 +30,7 @@
#include <gnustep/gui/config.h> #include <gnustep/gui/config.h>
#include <Foundation/NSString.h> #include <Foundation/NSString.h>
#include <Foundation/NSException.h>
#include <Foundation/NSValue.h> #include <Foundation/NSValue.h>
#include <AppKit/NSApplication.h> #include <AppKit/NSApplication.h>
@ -525,8 +526,25 @@ unsigned int previousMask = action_mask;
- (void)setTarget:(id)anObject {} - (void)setTarget:(id)anObject {}
- (id)target { return nil; } - (id)target { return nil; }
- (void)performClick:(id)sender - (void) performClick: (id)sender
{ {
NSView *cv = [self controlView];
[self highlight: YES withFrame: [cv frame] inView: cv];
if ([self action] && [self target])
{
NS_DURING
{
[(NSControl*)cv sendAction: [self action] to: [self target]];
}
NS_HANDLER
{
[self highlight: NO withFrame: [cv frame] inView: cv];
[localException raise];
}
NS_ENDHANDLER
}
[self highlight: NO withFrame: [cv frame] inView: cv];
} }
// //

View file

@ -83,6 +83,18 @@
defer: NO]; defer: NO];
} }
//
// If we receive an escape, close.
//
- (void) keyDown: (NSEvent*)theEvent
{
if ([@"\e" isEqual: [theEvent charactersIgnoringModifiers]] &&
([self styleMask] & NSClosableWindowMask) == NSClosableWindowMask)
[self close];
else
[super keyDown: theEvent];
}
// //
// Determining the Panel's Behavior // Determining the Panel's Behavior
// //
@ -410,6 +422,7 @@ static GSAlertPanel *gmodelAlertPanel = nil;
[defButton setTitle: defaultButton]; [defButton setTitle: defaultButton];
if ([defButton superview] == nil) if ([defButton superview] == nil)
[content addSubview: defButton]; [content addSubview: defButton];
[self makeFirstResponder: defButton];
} }
else else
{ {

View file

@ -130,7 +130,7 @@ int style;
[content_view release]; // Release the content view [content_view release]; // Release the content view
} }
if(_fieldEditor) if (_fieldEditor)
[_fieldEditor release]; [_fieldEditor release];
[background_color release]; [background_color release];
[represented_filename release]; [represented_filename release];
@ -309,7 +309,7 @@ NSView *wv;
@selector(windowWillReturnFieldEditor:toObject:)]) @selector(windowWillReturnFieldEditor:toObject:)])
return [delegate windowWillReturnFieldEditor:self toObject:anObject]; return [delegate windowWillReturnFieldEditor:self toObject:anObject];
if(!_fieldEditor && createFlag) // each window has a global if (!_fieldEditor && createFlag) // each window has a global
{ // text field editor { // text field editor
_fieldEditor = [[NSText new] retain]; _fieldEditor = [[NSText new] retain];
[_fieldEditor setFieldEditor:YES]; [_fieldEditor setFieldEditor:YES];
@ -515,7 +515,7 @@ NSPoint basePoint;
{ {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
if(is_autodisplay && needs_display) // if autodisplay is if (is_autodisplay && needs_display) // if autodisplay is
{ // enabled and window { // enabled and window
[self displayIfNeeded]; // display [self displayIfNeeded]; // display
[self flushWindowIfNeeded]; [self flushWindowIfNeeded];
@ -612,22 +612,17 @@ NSView *v;
// //
// Handling user actions and events // Handling user actions and events
// //
- (void)close - (void) close
{ {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
// Notify delegate // Notify delegate
[nc postNotificationName: NSWindowWillCloseNotification object: self]; [nc postNotificationName: NSWindowWillCloseNotification object: self];
[self orderOut:self]; [self orderOut: self];
visible = NO; visible = NO;
// if app has no
if(![[NSApplication sharedApplication] mainMenu]) // menu terminate if (is_released_when_closed)
[[NSApplication sharedApplication] terminate:self]; [self autorelease];
else }
{ // else if should
if (is_released_when_closed) // release do so
[self autorelease]; // default is YES
} // for windows and
} // NO for panels
- (void)deminiaturize:sender - (void)deminiaturize:sender
{ {
@ -657,7 +652,7 @@ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
- (void)performClose:sender - (void)performClose:sender
{ {
if(!([self styleMask] & NSClosableWindowMask)) if (!([self styleMask] & NSClosableWindowMask))
{ // self must have a close { // self must have a close
NSBeep(); // button in order to be NSBeep(); // button in order to be
return; // closed return; // closed
@ -665,7 +660,7 @@ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
if ([delegate respondsToSelector:@selector(windowShouldClose:)]) if ([delegate respondsToSelector:@selector(windowShouldClose:)])
{ // if delegate responds to { // if delegate responds to
if(![delegate windowShouldClose:self]) // windowShouldClose query if (![delegate windowShouldClose:self]) // windowShouldClose query
{ // it to see if it's ok to { // it to see if it's ok to
NSBeep(); // close the window NSBeep(); // close the window
return; return;
@ -675,7 +670,7 @@ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
{ {
if ([self respondsToSelector:@selector(windowShouldClose:)]) if ([self respondsToSelector:@selector(windowShouldClose:)])
{ // else if self responds to { // else if self responds to
if(![self windowShouldClose:self]) // windowShouldClose query if (![self windowShouldClose:self]) // windowShouldClose query
{ // self to see if it's ok { // self to see if it's ok
NSBeep(); // to close self NSBeep(); // to close self
return; return;
@ -708,12 +703,32 @@ NSApplication *theApp = [NSApplication sharedApplication];
- (NSResponder *)firstResponder { return first_responder; } - (NSResponder *)firstResponder { return first_responder; }
- (void)keyDown:(NSEvent *)theEvent // save the first responder - (void) keyDown: (NSEvent*)theEvent
{ // so that the key up goes {
original_responder = first_responder; // to it and not a possible static NSEvent *inProgress = nil;
// new first responder
[first_responder keyDown:theEvent]; // Send the first responder if (theEvent == inProgress)
} // the key down {
/*
* There was a loop in the responser chain - nothin handled the event
* so we make a warning beep.
*/
inProgress = nil;
NSBeep();
}
else
{
/*
* Save the first responder so that the key up goes to it and not a
* possible new first responder.
* Save the event so we can detect a loop in the responder chain.
*/
original_responder = first_responder;
inProgress = theEvent;
[first_responder keyDown: theEvent];
inProgress = nil;
}
}
- (BOOL)makeFirstResponder:(NSResponder *)aResponder - (BOOL)makeFirstResponder:(NSResponder *)aResponder
{ {
@ -903,7 +918,7 @@ NSView *v;
v = [content_view hitTest:[theEvent locationInWindow]]; v = [content_view hitTest:[theEvent locationInWindow]];
NSDebugLog([v description]); NSDebugLog([v description]);
NSDebugLog(@"\n"); NSDebugLog(@"\n");
if(first_responder != v) // if hit view is not first if (first_responder != v) // if hit view is not first
[self makeFirstResponder:v]; // responder ask it to be [self makeFirstResponder:v]; // responder ask it to be
[v mouseDown:theEvent]; [v mouseDown:theEvent];
last_point = [theEvent locationInWindow]; last_point = [theEvent locationInWindow];