mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-22 13:10:59 +00:00
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:
parent
7314f58abc
commit
5d8dd95e38
5 changed files with 238 additions and 4 deletions
34
ChangeLog
34
ChangeLog
|
@ -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]):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
|
113
Source/NSView.m
113
Source/NSView.m
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue