Make tab and shift-tab movement work.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@4978 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 1999-10-08 07:17:19 +00:00
parent 7314f58abc
commit 5d8dd95e38
5 changed files with 238 additions and 4 deletions

View file

@ -1,3 +1,37 @@
Fri Oct 8 1999 Nicola Pero <n.pero@mi.flashnet.it>
Implementation of key view loop.
* Headers/AppKit/NSView.h: New instance variables _nextKeyView and
_previousKeyView. Added prototypes for the new methods implemented
in NSView.m.
* Model/GMAppKit.m ([NSView -encodeWithModelArchiver:]),
([NSView -initWithModelUnarchiver:]): Updated for new ivars
_nextKeyView, _previousKeyView.
* Source/NSView.m ([-dealloc]): Remove references to the view in
_nextKeyView and _previousKeyView.
* Source/NSView.m ([-initWithCoder:]), ([-encodeWithCoder:]),
([-initWithFrame:]): Updated for new ivars _nextKeyView,
_previousKeyView.
* Source/NSView.m ([-setNextKeyView:]): implemented method.
([-nextValidKeyView]): implemented method. ([-nextValidKeyView]):
implemented method. ([-setPreviousKeyView:]): implemented method.
([-previousValidKeyView]): implemented method.
([-previousValidKeyView]): implemented method.
* Source/NSView.m ([NSView -keyDown:]): implemented method
to process TAB/SHIFT+TAB. ([NSView -keyUp:]): idem.
* Source/NSWindow.m: ([-selectPreviousKeyView:]): implemented method.
([-selectKeyViewFollowingView:]): implemented method.
([-selectNextKeyView:]): implemented method.
([-selectKeyViewPrecedingView:]): implemented method.
Fix, mainly useful for custom control subclasses:
* Model/GMAppKit.m ([NSControl -initWithModelUnarchiver:]): If the
encoded cell is nil, create a new one (of the class associated
with the type of NSControl being decoded). This is needed for
NSControl custom subclasses encoded through IMCustomView.
([NSMatrix -initWithModelUnarchiver:]): Do not set delegate if
nil.
Tue Oct 5 1999 Nicola Pero <n.pero@mi.flashnet.it>
* Model/IMConnectors.m ([IMOutletConnector -establishConnection]):

View file

@ -99,6 +99,9 @@ enum {
BOOL allocate_gstate;
BOOL renew_gstate;
NSView *_nextKeyView;
NSView *_previousKeyView;
// Reserved for back-end use
void *be_view_reserved;
}
@ -269,6 +272,12 @@ enum {
owner:(id)anObject
userData:(void *)data
assumeInside:(BOOL)flag;
- (void)setNextKeyView:(NSView *)aView;
- (NSView *)nextKeyView;
- (NSView *)nextValidKeyView;
- (void)setPreviousKeyView:(NSView *)aView;
- (NSView *)previousKeyView;
- (NSView *)previousValidKeyView;
//
// Dragging

View file

@ -378,6 +378,7 @@ void __dummy_GMAppKit_functionForLinking() {}
int nr, nc;
NSArray *cell_array;
int i;
id decodedDelegate;
self = [super initWithModelUnarchiver:unarchiver];
@ -405,9 +406,11 @@ void __dummy_GMAppKit_functionForLinking() {}
for (i = 0; (i < [cell_array count]) && (i < nr*nc); i++) {
[self putCell:[cell_array objectAtIndex:i] atRow:i/nc column:i%nc];
}
[self setDelegate:[unarchiver decodeObjectWithName:@"delegate"]];
decodedDelegate = [unarchiver decodeObjectWithName:@"delegate"];
if (decodedDelegate)
[self setDelegate:decodedDelegate];
[self setTarget:[unarchiver decodeObjectWithName:@"target"]];
[self setAction:[unarchiver decodeSelectorWithName:@"action"]];
@ -617,6 +620,8 @@ void __dummy_GMAppKit_functionForLinking() {}
- (id)initWithModelUnarchiver:(GMUnarchiver*)unarchiver
{
id decodedCell;
self = [super initWithModelUnarchiver:unarchiver];
// if (model_version == 1) {
@ -630,7 +635,15 @@ void __dummy_GMAppKit_functionForLinking() {}
//[self setIgnoresMultiClick:
// [unarchiver decodeBOOLWithName:@"ignoresMultiClick"]];
// } else {
[self setCell:[unarchiver decodeObjectWithName:@"cell"]];
{
// So that custom NSControls, which do not encode the cell,
// can still work.
decodedCell = [unarchiver decodeObjectWithName:@"cell"];
if (decodedCell)
[self setCell: decodedCell];
else
[self setCell: AUTORELEASE([[[self class] cellClass] new])];
}
[self setEnabled:[unarchiver decodeBOOLWithName:@"isEnabled"]];
[self setTag:[unarchiver decodeIntWithName:@"tag"]];
[self setIgnoresMultiClick:
@ -968,6 +981,9 @@ void __dummy_GMAppKit_functionForLinking() {}
withName:@"autoresizesSubviews"];
[archiver encodeUnsignedInt:[self autoresizingMask]
withName:@"autoresizingMask"];
[archiver encodeConditionalObject:[self nextKeyView] withName:@"nextKeyView"];
[archiver encodeConditionalObject:[self previousKeyView]
withName:@"previousKeyView"];
}
+ (id)createObjectForModelUnarchiver:(GMUnarchiver*)unarchiver
@ -1005,6 +1021,10 @@ void __dummy_GMAppKit_functionForLinking() {}
[unarchiver decodeBOOLWithName:@"autoresizesSubviews"]];
[self setAutoresizingMask:
[unarchiver decodeUnsignedIntWithName:@"autoresizingMask"]];
[self setNextKeyView: [unarchiver decodeObjectWithName:@"nextKeyView"]];
[self setPreviousKeyView:
[unarchiver decodeObjectWithName:@"previousKeyView"]];
#ifdef GNU_GUI_LIBRARY
_rFlags.flipped_view = [self isFlipped];

View file

@ -66,6 +66,7 @@ struct NSWindow_struct
* Class variables
*/
static Class rectClass;
static Class viewClass;
static NSAffineTransform *flip = nil;
@ -164,6 +165,7 @@ GSSetDragTypes(NSView* obj, NSArray *types)
flip = [matrixClass new];
[flip setTransformStruct: ats];
viewClass = [NSView class];
rectClass = [GSTrackingRect class];
NSDebugLLog(@"NSView", @"Initialize NSView class\n");
[self setVersion: 1];
@ -224,6 +226,8 @@ GSSetDragTypes(NSView* obj, NSArray *types)
autoresize_subviews = YES;
autoresizingMask = NSViewNotSizable;
coordinates_valid = NO;
_nextKeyView = nil;
_previousKeyView = nil;
_rFlags.flipped_view = [self isFlipped];
_rFlags.opaque_view = [self isOpaque];
@ -233,6 +237,12 @@ GSSetDragTypes(NSView* obj, NSArray *types)
- (void) dealloc
{
if (_nextKeyView)
[_nextKeyView setPreviousKeyView: nil];
if (_previousKeyView)
[_previousKeyView setNextKeyView: nil];
RELEASE(matrixToWindow);
RELEASE(matrixFromWindow);
RELEASE(frameMatrix);
@ -2049,6 +2059,105 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
return t;
}
- (void) setNextKeyView: (NSView *)aView
{
if (!aView)
{
_nextKeyView = nil;
return;
}
if ([aView isKindOfClass: viewClass])
{
// As an exception, we do not retain aView, to avoid retain loops
// (the simplest being a view retaining and being retained
// by another view), which prevents objects from being ever
// deallocated. To understand how we manage without retaining
// _nextKeyView, see [NSView -dealloc].
_nextKeyView = aView;
if ([aView previousKeyView] != self)
[aView setPreviousKeyView: self];
}
}
- (NSView *) nextKeyView
{
return _nextKeyView;
}
- (NSView *) nextValidKeyView
{
NSView *theView;
theView = _nextKeyView;
while (1)
{
if ([theView acceptsFirstResponder] || (theView == nil))
return theView;
theView = [theView nextKeyView];
}
}
- (void) setPreviousKeyView: (NSView *)aView
{
if (!aView)
{
_previousKeyView = nil;
return;
}
if ([aView isKindOfClass: viewClass])
{
_previousKeyView = aView;
if ([aView nextKeyView] != self)
[aView setNextKeyView: self];
}
}
- (NSView *) previousKeyView
{
return _previousKeyView;
}
- (NSView *) previousValidKeyView
{
NSView *theView;
theView = _previousKeyView;
while (1)
{
if ([theView acceptsFirstResponder] || (theView == nil))
return theView;
theView = [theView previousKeyView];
}
}
- (void) keyDown: (NSEvent *)theEvent
{
unsigned int key_code = [theEvent keyCode];
// If this is a TAB or TAB+SHIFT event, we handle it
if (key_code == 0x09)
{
if ([theEvent modifierFlags] & NSShiftKeyMask)
[window selectKeyViewPrecedingView: self];
else
[window selectKeyViewFollowingView: self];
return;
}
// Otherwise, let the event go on in the responder chain
[super keyDown: theEvent];
}
- (void) keyUp: (NSEvent *)theEvent
{
unsigned int key_code = [theEvent keyCode];
// We handle (ignoring them) TAB/SHIFT+TAB events
if (key_code == 0x09)
return;
else // All other events go on in the chain
[super keyUp: theEvent];
}
/*
* Dragging
*/
@ -2284,6 +2393,8 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &post_frame_changes];
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &autoresize_subviews];
[aCoder encodeValueOfObjCType: @encode(unsigned int) at: &autoresizingMask];
[aCoder encodeConditionalObject: _nextKeyView];
[aCoder encodeConditionalObject: _previousKeyView];
NSDebugLLog(@"NSView", @"NSView: finish encoding\n");
}
@ -2305,6 +2416,8 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &post_frame_changes];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &autoresize_subviews];
[aDecoder decodeValueOfObjCType: @encode(unsigned int) at: &autoresizingMask];
[aDecoder decodeValueOfObjCType: @encode(id) at: &_nextKeyView];
[aDecoder decodeValueOfObjCType: @encode(id) at: &_previousKeyView];
NSDebugLLog(@"NSView", @"NSView: finish decoding\n");
frameMatrix = [NSAffineTransform new];

View file

@ -1761,6 +1761,64 @@ static NSRecursiveLock *windowsLock;
return NO;
}
- (void) selectKeyViewFollowingView: (NSView *)aView
{
NSView *theView = nil;
if ([aView isKindOfClass: viewClass])
theView = [aView nextValidKeyView];
if (theView)
[self makeFirstResponder: theView];
}
- (void) selectKeyViewPrecedingView: (NSView *)aView
{
NSView *theView = nil;
if ([aView isKindOfClass: viewClass])
theView = [aView previousValidKeyView];
if (theView)
[self makeFirstResponder: theView];
}
- (void) selectNextKeyView: (id)sender
{
NSView *theView = nil;
if ([first_responder isKindOfClass: viewClass])
theView = [first_responder nextValidKeyView];
if (!theView)
{
if ([_initial_first_responder acceptsFirstResponder])
theView = _initial_first_responder;
else
theView = [_initial_first_responder nextValidKeyView];
}
if (theView)
[self makeFirstResponder: theView];
}
- (void) selectPreviousKeyView: (id)sender
{
NSView *theView = nil;
if ([first_responder isKindOfClass: viewClass])
theView = [first_responder previousValidKeyView];
if (!theView)
{
if ([_initial_first_responder acceptsFirstResponder])
theView = _initial_first_responder;
else
theView = [_initial_first_responder previousValidKeyView];
}
if (theView)
[self makeFirstResponder: theView];
}
/*
* Dragging
*/