mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-21 03:21:01 +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
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…
Add table
Add a link
Reference in a new issue