mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 22:10:47 +00:00
Moved focus handling to graphics context
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@3859 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
7efd28bd8b
commit
db56ad4a9d
4 changed files with 90 additions and 91 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,4 +1,14 @@
|
||||||
hu Mar 4 12:46:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
Fri Mar 5 14:46:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
|
* Headers/AppKit/NSGraphicsContext.h: Added three new methods to
|
||||||
|
support focusing - ([-focusView]), ([-pushFocusView:]) and
|
||||||
|
([-popFocusView:])
|
||||||
|
* Source/NSGraphicsContext.m: Added new focussing methods, tidied
|
||||||
|
a little, and made graphocs contexts thread-safe.
|
||||||
|
* Source/NSView.m: Removed old code to handle per-thread stack of
|
||||||
|
focussed views - use new code in NSGraphicsContext instead.
|
||||||
|
|
||||||
|
Thu Mar 4 12:46:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
* Source/NSClipView.m: Fixed to cope with nil document view.
|
* Source/NSClipView.m: Fixed to cope with nil document view.
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,10 @@
|
||||||
|
|
||||||
#include <AppKit/GSMethodTable.h>
|
#include <AppKit/GSMethodTable.h>
|
||||||
|
|
||||||
|
@class NSMutableArray;
|
||||||
@class NSMutableData;
|
@class NSMutableData;
|
||||||
@class NSDictionary;
|
@class NSDictionary;
|
||||||
|
@class NSView;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Backing Store Types
|
// Backing Store Types
|
||||||
|
@ -81,11 +83,16 @@ typedef enum _NSWindowOrderingMode
|
||||||
|
|
||||||
@interface NSGraphicsContext : NSObject
|
@interface NSGraphicsContext : NSObject
|
||||||
{
|
{
|
||||||
NSDictionary *context_info;
|
/* Make the one public instance variable first in the object so that, if we
|
||||||
NSMutableData *context_data;
|
* add or remove others, we don't necessarily need to recompile everything.
|
||||||
|
*/
|
||||||
@public
|
@public
|
||||||
const gsMethodTable *methods;
|
const gsMethodTable *methods;
|
||||||
|
|
||||||
|
@protected
|
||||||
|
NSDictionary *context_info;
|
||||||
|
NSMutableData *context_data;
|
||||||
|
NSMutableArray *focus_stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSGraphicsContext*) currentContext;
|
+ (NSGraphicsContext*) currentContext;
|
||||||
|
@ -105,6 +112,13 @@ typedef enum _NSWindowOrderingMode
|
||||||
- (id) initWithContextInfo: (NSDictionary *)info;
|
- (id) initWithContextInfo: (NSDictionary *)info;
|
||||||
- (void) destroyContext;
|
- (void) destroyContext;
|
||||||
- (NSMutableData *) mutableData;
|
- (NSMutableData *) mutableData;
|
||||||
|
/*
|
||||||
|
* Focus management methods - lock and unlock should only be used by NSView
|
||||||
|
* in it's implementation of lockFocus and unlockFocus.
|
||||||
|
*/
|
||||||
|
- (NSView*) focusView;
|
||||||
|
- (void) lockFocusView: (NSView*)aView;
|
||||||
|
- (void) unlockFocusView: (NSView*)aView;
|
||||||
@end
|
@end
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
Written by: Adam Fedor <fedor@gnu.org>
|
Written by: Adam Fedor <fedor@gnu.org>
|
||||||
Date: Nov 1998
|
Date: Nov 1998
|
||||||
Updated by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
Updated by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
Date: Feb 1999
|
||||||
|
|
||||||
This file is part of the GNUStep GUI Library.
|
This file is part of the GNUStep GUI Library.
|
||||||
|
|
||||||
|
@ -30,6 +31,8 @@
|
||||||
#include <Foundation/NSDictionary.h>
|
#include <Foundation/NSDictionary.h>
|
||||||
#include <Foundation/NSException.h>
|
#include <Foundation/NSException.h>
|
||||||
#include <Foundation/NSData.h>
|
#include <Foundation/NSData.h>
|
||||||
|
#include <Foundation/NSLock.h>
|
||||||
|
#include <Foundation/NSThread.h>
|
||||||
#include <Foundation/NSZone.h>
|
#include <Foundation/NSZone.h>
|
||||||
#include "AppKit/NSGraphicsContext.h"
|
#include "AppKit/NSGraphicsContext.h"
|
||||||
|
|
||||||
|
@ -37,9 +40,6 @@
|
||||||
are also allocated from this zone) */
|
are also allocated from this zone) */
|
||||||
NSZone *_globalGSZone = NULL;
|
NSZone *_globalGSZone = NULL;
|
||||||
|
|
||||||
/* The current context */
|
|
||||||
NSGraphicsContext *_currentNSGraphicsContext = nil;
|
|
||||||
|
|
||||||
/* The current concrete class */
|
/* The current concrete class */
|
||||||
static Class defaultNSGraphicsContextClass = NULL;
|
static Class defaultNSGraphicsContextClass = NULL;
|
||||||
|
|
||||||
|
@ -49,6 +49,11 @@ static NSMutableArray *contextList;
|
||||||
/* Class variable for holding pointers to method functions */
|
/* Class variable for holding pointers to method functions */
|
||||||
static NSMutableDictionary *classMethodTable;
|
static NSMutableDictionary *classMethodTable;
|
||||||
|
|
||||||
|
/* Lock for use when creating contexts */
|
||||||
|
static NSRecursiveLock *contextLock = nil;
|
||||||
|
|
||||||
|
static NSString *NSGraphicsContextThredKey = @"NSGraphicsContextThredKey";
|
||||||
|
|
||||||
@interface NSGraphicsContext (Private)
|
@interface NSGraphicsContext (Private)
|
||||||
+ (gsMethodTable *) _initializeMethodTable;
|
+ (gsMethodTable *) _initializeMethodTable;
|
||||||
@end
|
@end
|
||||||
|
@ -57,22 +62,19 @@ static NSMutableDictionary *classMethodTable;
|
||||||
|
|
||||||
+ (void) initialize
|
+ (void) initialize
|
||||||
{
|
{
|
||||||
if (defaultNSGraphicsContextClass == nil)
|
if (contextLock == nil)
|
||||||
{
|
{
|
||||||
defaultNSGraphicsContextClass = [NSGraphicsContext class];
|
[gnustep_global_lock lock];
|
||||||
}
|
if (contextLock == nil)
|
||||||
if (_globalGSZone == 0)
|
{
|
||||||
{
|
contextLock = [NSRecursiveLock new];
|
||||||
_globalGSZone = NSDefaultMallocZone();
|
defaultNSGraphicsContextClass = [NSGraphicsContext class];
|
||||||
}
|
_globalGSZone = NSDefaultMallocZone();
|
||||||
if (contextList == nil)
|
contextList = [[NSMutableArray allocWithZone: _globalGSZone] init];
|
||||||
{
|
classMethodTable =
|
||||||
contextList = [[NSMutableArray allocWithZone: _globalGSZone] init];
|
[[NSMutableDictionary allocWithZone: _globalGSZone] init];
|
||||||
}
|
}
|
||||||
if (classMethodTable == 0)
|
[gnustep_global_lock unlock];
|
||||||
{
|
|
||||||
classMethodTable =
|
|
||||||
[[NSMutableDictionary allocWithZone: _globalGSZone] init];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,16 +97,21 @@ static NSMutableDictionary *classMethodTable;
|
||||||
|
|
||||||
+ (void) setCurrentContext: (NSGraphicsContext *)context
|
+ (void) setCurrentContext: (NSGraphicsContext *)context
|
||||||
{
|
{
|
||||||
_currentNSGraphicsContext = context;
|
NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary];
|
||||||
|
|
||||||
|
[dict setObject: context forKey: NSGraphicsContextThredKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSGraphicsContext *) currentContext
|
+ (NSGraphicsContext *) currentContext
|
||||||
{
|
{
|
||||||
return _currentNSGraphicsContext;
|
NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary];
|
||||||
|
|
||||||
|
return (NSGraphicsContext*) [dict objectForKey: NSGraphicsContextThredKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
|
DESTROY(focus_stack);
|
||||||
DESTROY(context_data);
|
DESTROY(context_data);
|
||||||
DESTROY(context_info);
|
DESTROY(context_info);
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
|
@ -114,7 +121,9 @@ static NSMutableDictionary *classMethodTable;
|
||||||
the next autorelease pool end */
|
the next autorelease pool end */
|
||||||
- (void) destroyContext;
|
- (void) destroyContext;
|
||||||
{
|
{
|
||||||
|
[contextLock lock];
|
||||||
[contextList removeObject: self];
|
[contextList removeObject: self];
|
||||||
|
[contextLock unlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) init
|
- (id) init
|
||||||
|
@ -126,15 +135,25 @@ static NSMutableDictionary *classMethodTable;
|
||||||
- (id) initWithContextInfo: (NSDictionary *)info
|
- (id) initWithContextInfo: (NSDictionary *)info
|
||||||
{
|
{
|
||||||
[super init];
|
[super init];
|
||||||
[contextList addObject: self];
|
|
||||||
context_info = [info retain];
|
context_info = [info retain];
|
||||||
|
focus_stack = [[NSMutableArray allocWithZone: [self zone]]
|
||||||
|
initWithCapacity: 1];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The classMethodTable dictionary and the list of all contexts must both
|
||||||
|
* be protected from other threads.
|
||||||
|
*/
|
||||||
|
[contextLock lock];
|
||||||
if (!(methods = [[classMethodTable objectForKey: [self class]] pointerValue]))
|
if (!(methods = [[classMethodTable objectForKey: [self class]] pointerValue]))
|
||||||
{
|
{
|
||||||
methods = [[self class] _initializeMethodTable];
|
methods = [[self class] _initializeMethodTable];
|
||||||
[classMethodTable setObject: [NSValue valueWithPointer: methods]
|
[classMethodTable setObject: [NSValue valueWithPointer: methods]
|
||||||
forKey: [self class]];
|
forKey: [self class]];
|
||||||
}
|
}
|
||||||
|
[contextList addObject: self];
|
||||||
|
[contextLock unlock];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,6 +183,24 @@ static NSMutableDictionary *classMethodTable;
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSView*) focusView
|
||||||
|
{
|
||||||
|
return [focus_stack lastObject];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) lockFocusView: (NSView*)aView
|
||||||
|
{
|
||||||
|
[focus_stack addObject: aView];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) unlockFocusView: (NSView*)aView
|
||||||
|
{
|
||||||
|
NSView *v = [focus_stack lastObject];
|
||||||
|
|
||||||
|
NSAssert(v == aView, NSInvalidArgumentException);
|
||||||
|
[focus_stack removeLastObject];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation NSGraphicsContext (Private)
|
@implementation NSGraphicsContext (Private)
|
||||||
|
|
|
@ -89,74 +89,12 @@ static SEL invalidateSel = @selector(_invalidateCoordinates);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* return the view at the top of thread's focus stack
|
* return the view at the top of graphics contexts stack
|
||||||
* or nil if none is focused
|
* or nil if none is focused
|
||||||
*/
|
*/
|
||||||
+ (NSView*) focusView
|
+ (NSView*) focusView
|
||||||
{
|
{
|
||||||
NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary];
|
return [[NSGraphicsContext currentContext] focusView];
|
||||||
NSMutableArray *stack = [dict objectForKey: viewThreadKey];
|
|
||||||
NSView *current_view = nil;
|
|
||||||
|
|
||||||
if (stack)
|
|
||||||
{
|
|
||||||
unsigned count = [stack count];
|
|
||||||
|
|
||||||
if (count > 0)
|
|
||||||
current_view = [stack objectAtIndex: --count];
|
|
||||||
}
|
|
||||||
|
|
||||||
return current_view;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
+ (void) pushFocusView: (NSView*)focusView
|
|
||||||
{
|
|
||||||
if (focusView)
|
|
||||||
{
|
|
||||||
NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary];
|
|
||||||
NSMutableArray *stack = [dict objectForKey: viewThreadKey];
|
|
||||||
|
|
||||||
if (stack == nil)
|
|
||||||
{
|
|
||||||
stack = [[NSMutableArray alloc] initWithCapacity: 4];
|
|
||||||
[dict setObject: stack forKey: viewThreadKey];
|
|
||||||
[stack release];
|
|
||||||
}
|
|
||||||
[stack addObject: focusView];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
[NSException raise: NSInternalInconsistencyException
|
|
||||||
format: @"Attempt to push a 'nil' focus view on to stack."];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove the top focusView for the current thread from the stack
|
|
||||||
* and return the new focusView (or nil if the stack is now empty).
|
|
||||||
*/
|
|
||||||
+ (NSView*) popFocusView
|
|
||||||
{
|
|
||||||
NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary];
|
|
||||||
NSMutableArray *stack = [dict objectForKey: viewThreadKey];
|
|
||||||
NSView *v = nil;
|
|
||||||
|
|
||||||
if (stack)
|
|
||||||
{
|
|
||||||
unsigned count = [stack count];
|
|
||||||
|
|
||||||
if (count > 0)
|
|
||||||
{
|
|
||||||
[stack removeObjectAtIndex: --count];
|
|
||||||
}
|
|
||||||
if (count > 0)
|
|
||||||
{
|
|
||||||
v = [stack objectAtIndex: --count];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue