mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-06-02 14:50: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
a25ae95334
commit
84db9a4f0b
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>
|
Tue Oct 5 1999 Nicola Pero <n.pero@mi.flashnet.it>
|
||||||
|
|
||||||
* Model/IMConnectors.m ([IMOutletConnector -establishConnection]):
|
* Model/IMConnectors.m ([IMOutletConnector -establishConnection]):
|
||||||
|
|
|
@ -99,6 +99,9 @@ enum {
|
||||||
BOOL allocate_gstate;
|
BOOL allocate_gstate;
|
||||||
BOOL renew_gstate;
|
BOOL renew_gstate;
|
||||||
|
|
||||||
|
NSView *_nextKeyView;
|
||||||
|
NSView *_previousKeyView;
|
||||||
|
|
||||||
// Reserved for back-end use
|
// Reserved for back-end use
|
||||||
void *be_view_reserved;
|
void *be_view_reserved;
|
||||||
}
|
}
|
||||||
|
@ -269,6 +272,12 @@ enum {
|
||||||
owner:(id)anObject
|
owner:(id)anObject
|
||||||
userData:(void *)data
|
userData:(void *)data
|
||||||
assumeInside:(BOOL)flag;
|
assumeInside:(BOOL)flag;
|
||||||
|
- (void)setNextKeyView:(NSView *)aView;
|
||||||
|
- (NSView *)nextKeyView;
|
||||||
|
- (NSView *)nextValidKeyView;
|
||||||
|
- (void)setPreviousKeyView:(NSView *)aView;
|
||||||
|
- (NSView *)previousKeyView;
|
||||||
|
- (NSView *)previousValidKeyView;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Dragging
|
// Dragging
|
||||||
|
|
|
@ -378,6 +378,7 @@ void __dummy_GMAppKit_functionForLinking() {}
|
||||||
int nr, nc;
|
int nr, nc;
|
||||||
NSArray *cell_array;
|
NSArray *cell_array;
|
||||||
int i;
|
int i;
|
||||||
|
id decodedDelegate;
|
||||||
|
|
||||||
self = [super initWithModelUnarchiver:unarchiver];
|
self = [super initWithModelUnarchiver:unarchiver];
|
||||||
|
|
||||||
|
@ -405,9 +406,11 @@ void __dummy_GMAppKit_functionForLinking() {}
|
||||||
for (i = 0; (i < [cell_array count]) && (i < nr*nc); i++) {
|
for (i = 0; (i < [cell_array count]) && (i < nr*nc); i++) {
|
||||||
[self putCell:[cell_array objectAtIndex:i] atRow:i/nc column:i%nc];
|
[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 setTarget:[unarchiver decodeObjectWithName:@"target"]];
|
||||||
[self setAction:[unarchiver decodeSelectorWithName:@"action"]];
|
[self setAction:[unarchiver decodeSelectorWithName:@"action"]];
|
||||||
|
@ -617,6 +620,8 @@ void __dummy_GMAppKit_functionForLinking() {}
|
||||||
|
|
||||||
- (id)initWithModelUnarchiver:(GMUnarchiver*)unarchiver
|
- (id)initWithModelUnarchiver:(GMUnarchiver*)unarchiver
|
||||||
{
|
{
|
||||||
|
id decodedCell;
|
||||||
|
|
||||||
self = [super initWithModelUnarchiver:unarchiver];
|
self = [super initWithModelUnarchiver:unarchiver];
|
||||||
|
|
||||||
// if (model_version == 1) {
|
// if (model_version == 1) {
|
||||||
|
@ -630,7 +635,15 @@ void __dummy_GMAppKit_functionForLinking() {}
|
||||||
//[self setIgnoresMultiClick:
|
//[self setIgnoresMultiClick:
|
||||||
// [unarchiver decodeBOOLWithName:@"ignoresMultiClick"]];
|
// [unarchiver decodeBOOLWithName:@"ignoresMultiClick"]];
|
||||||
// } else {
|
// } 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 setEnabled:[unarchiver decodeBOOLWithName:@"isEnabled"]];
|
||||||
[self setTag:[unarchiver decodeIntWithName:@"tag"]];
|
[self setTag:[unarchiver decodeIntWithName:@"tag"]];
|
||||||
[self setIgnoresMultiClick:
|
[self setIgnoresMultiClick:
|
||||||
|
@ -968,6 +981,9 @@ void __dummy_GMAppKit_functionForLinking() {}
|
||||||
withName:@"autoresizesSubviews"];
|
withName:@"autoresizesSubviews"];
|
||||||
[archiver encodeUnsignedInt:[self autoresizingMask]
|
[archiver encodeUnsignedInt:[self autoresizingMask]
|
||||||
withName:@"autoresizingMask"];
|
withName:@"autoresizingMask"];
|
||||||
|
[archiver encodeConditionalObject:[self nextKeyView] withName:@"nextKeyView"];
|
||||||
|
[archiver encodeConditionalObject:[self previousKeyView]
|
||||||
|
withName:@"previousKeyView"];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id)createObjectForModelUnarchiver:(GMUnarchiver*)unarchiver
|
+ (id)createObjectForModelUnarchiver:(GMUnarchiver*)unarchiver
|
||||||
|
@ -1005,6 +1021,10 @@ void __dummy_GMAppKit_functionForLinking() {}
|
||||||
[unarchiver decodeBOOLWithName:@"autoresizesSubviews"]];
|
[unarchiver decodeBOOLWithName:@"autoresizesSubviews"]];
|
||||||
[self setAutoresizingMask:
|
[self setAutoresizingMask:
|
||||||
[unarchiver decodeUnsignedIntWithName:@"autoresizingMask"]];
|
[unarchiver decodeUnsignedIntWithName:@"autoresizingMask"]];
|
||||||
|
[self setNextKeyView: [unarchiver decodeObjectWithName:@"nextKeyView"]];
|
||||||
|
[self setPreviousKeyView:
|
||||||
|
[unarchiver decodeObjectWithName:@"previousKeyView"]];
|
||||||
|
|
||||||
|
|
||||||
#ifdef GNU_GUI_LIBRARY
|
#ifdef GNU_GUI_LIBRARY
|
||||||
_rFlags.flipped_view = [self isFlipped];
|
_rFlags.flipped_view = [self isFlipped];
|
||||||
|
|
113
Source/NSView.m
113
Source/NSView.m
|
@ -66,6 +66,7 @@ struct NSWindow_struct
|
||||||
* Class variables
|
* Class variables
|
||||||
*/
|
*/
|
||||||
static Class rectClass;
|
static Class rectClass;
|
||||||
|
static Class viewClass;
|
||||||
|
|
||||||
static NSAffineTransform *flip = nil;
|
static NSAffineTransform *flip = nil;
|
||||||
|
|
||||||
|
@ -164,6 +165,7 @@ GSSetDragTypes(NSView* obj, NSArray *types)
|
||||||
flip = [matrixClass new];
|
flip = [matrixClass new];
|
||||||
[flip setTransformStruct: ats];
|
[flip setTransformStruct: ats];
|
||||||
|
|
||||||
|
viewClass = [NSView class];
|
||||||
rectClass = [GSTrackingRect class];
|
rectClass = [GSTrackingRect class];
|
||||||
NSDebugLLog(@"NSView", @"Initialize NSView class\n");
|
NSDebugLLog(@"NSView", @"Initialize NSView class\n");
|
||||||
[self setVersion: 1];
|
[self setVersion: 1];
|
||||||
|
@ -224,6 +226,8 @@ GSSetDragTypes(NSView* obj, NSArray *types)
|
||||||
autoresize_subviews = YES;
|
autoresize_subviews = YES;
|
||||||
autoresizingMask = NSViewNotSizable;
|
autoresizingMask = NSViewNotSizable;
|
||||||
coordinates_valid = NO;
|
coordinates_valid = NO;
|
||||||
|
_nextKeyView = nil;
|
||||||
|
_previousKeyView = nil;
|
||||||
|
|
||||||
_rFlags.flipped_view = [self isFlipped];
|
_rFlags.flipped_view = [self isFlipped];
|
||||||
_rFlags.opaque_view = [self isOpaque];
|
_rFlags.opaque_view = [self isOpaque];
|
||||||
|
@ -233,6 +237,12 @@ GSSetDragTypes(NSView* obj, NSArray *types)
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
|
if (_nextKeyView)
|
||||||
|
[_nextKeyView setPreviousKeyView: nil];
|
||||||
|
|
||||||
|
if (_previousKeyView)
|
||||||
|
[_previousKeyView setNextKeyView: nil];
|
||||||
|
|
||||||
RELEASE(matrixToWindow);
|
RELEASE(matrixToWindow);
|
||||||
RELEASE(matrixFromWindow);
|
RELEASE(matrixFromWindow);
|
||||||
RELEASE(frameMatrix);
|
RELEASE(frameMatrix);
|
||||||
|
@ -2049,6 +2059,105 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
|
||||||
return t;
|
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
|
* 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: &post_frame_changes];
|
||||||
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &autoresize_subviews];
|
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &autoresize_subviews];
|
||||||
[aCoder encodeValueOfObjCType: @encode(unsigned int) at: &autoresizingMask];
|
[aCoder encodeValueOfObjCType: @encode(unsigned int) at: &autoresizingMask];
|
||||||
|
[aCoder encodeConditionalObject: _nextKeyView];
|
||||||
|
[aCoder encodeConditionalObject: _previousKeyView];
|
||||||
NSDebugLLog(@"NSView", @"NSView: finish encoding\n");
|
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: &post_frame_changes];
|
||||||
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &autoresize_subviews];
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &autoresize_subviews];
|
||||||
[aDecoder decodeValueOfObjCType: @encode(unsigned int) at: &autoresizingMask];
|
[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");
|
NSDebugLLog(@"NSView", @"NSView: finish decoding\n");
|
||||||
|
|
||||||
frameMatrix = [NSAffineTransform new];
|
frameMatrix = [NSAffineTransform new];
|
||||||
|
|
|
@ -1761,6 +1761,64 @@ static NSRecursiveLock *windowsLock;
|
||||||
return NO;
|
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
|
* Dragging
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue