Add support for temporary elements which go away when the theme is deactivated.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@27528 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2009-01-06 05:08:58 +00:00
parent ea28f55ad6
commit 2f75abcf2e
5 changed files with 109 additions and 58 deletions

View file

@ -1,3 +1,14 @@
2009-01-06 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSTheme.m:
* Source/NSScroller.m:
* Source/GSThemeDrawing.m:
* Headers/Additions/GNUstepGUI/GSTheme.h:
Extend element naming API to support temporary elements ... ones
which are 'owned' by a particular theme instance and automatically
removed when the theme deactivates.
Changed scroller code to use this for the shared scroller parts.
2009-01-05 Fred Kiefer <FredKiefer@gmx.de>
* Headers/AppKit/NSController.h,

View file

@ -410,9 +410,14 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification;
* the value of aString is also nil (and the method does nothing).<br />
* Any control which uses this method to set names for subsidiary elements
* must also make sure to remove the name mapping before that element is
* deallocated.
* deallocated, unless the takeOwnership option is YES, in which case
* anObject is retained, the name mapping lasts only until the receiver
* is deactivated, and at that point anObject is released.
*/
- (void) setName: (NSString*)aString forElement: (id)anObject;
- (void) setName: (NSString*)aString
forElement: (id)anObject
temporary: (BOOL)takeOwnership;
/**
* <p>Provides a standard inspector window used to display information about

View file

@ -76,6 +76,10 @@ NSString *GSThemeWillActivateNotification
NSString *GSThemeWillDeactivateNotification
= @"GSThemeWillDeactivateNotification";
@interface GSTheme (Private)
- (void) _revokeOwnerships;
@end
@implementation GSTheme
static GSTheme *defaultTheme = nil;
@ -92,6 +96,7 @@ typedef struct {
NSMutableDictionary *normalTiles;
NSMutableDictionary *highlightedTiles;
NSMutableDictionary *selectedTiles;
NSMutableSet *owned;
NSImage *icon;
NSString *name;
} internal;
@ -103,6 +108,7 @@ typedef struct {
#define _normalTiles _internal->normalTiles
#define _highlightedTiles _internal->highlightedTiles
#define _selectedTiles _internal->selectedTiles
#define _owned _internal->owned
#define _icon _internal->icon
#define _name _internal->name
@ -473,6 +479,8 @@ typedef struct {
}
[_images removeAllObjects];
[self _revokeOwnerships];
/* Tell everything that we have become inactive.
*/
[[NSNotificationCenter defaultCenter]
@ -492,6 +500,8 @@ typedef struct {
RELEASE(_highlightedTiles);
RELEASE(_selectedTiles);
RELEASE(_icon);
[self _revokeOwnerships];
RELEASE(_owned);
NSZoneFree ([self zone], _reserved);
}
[super dealloc];
@ -532,6 +542,8 @@ typedef struct {
_normalTiles = [NSMutableDictionary new];
_highlightedTiles = [NSMutableDictionary new];
_selectedTiles = [NSMutableDictionary new];
_owned = [NSMutableSet new];
ASSIGN(_name,
[[[_bundle bundlePath] lastPathComponent] stringByDeletingPathExtension]);
@ -567,7 +579,9 @@ typedef struct {
}
}
- (void) setName: (NSString*)aString forElement: (id)anObject
- (void) setName: (NSString*)aString
forElement: (id)anObject
temporary: (BOOL)takeOwnership
{
if (aString == nil)
{
@ -580,6 +594,7 @@ typedef struct {
return;
}
NSMapRemove(names, (void*)anObject);
[_owned removeObject: anObject];
}
else
{
@ -590,6 +605,10 @@ typedef struct {
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
}
NSMapInsert(names, (void*)anObject, (void*)aString);
if (takeOwnership == YES)
{
[_owned addObject: anObject];
}
}
}
@ -725,3 +744,17 @@ typedef struct {
@end
@implementation GSTheme (Private)
/* Remove all temporarily named objects from our registry, releasing them.
*/
- (void) _revokeOwnerships
{
id o;
while ((o = [_owned anyObject]) != nil)
{
[self setName: nil forElement: o temporary: YES];
}
}
@end

View file

@ -282,6 +282,7 @@
horizontal: (BOOL)horizontal
{
NSButtonCell *cell;
NSString *name;
cell = [NSButtonCell new];
if (horizontal)
@ -293,6 +294,7 @@
[cell setImage: [NSImage imageNamed: @"common_ArrowLeft"]];
[cell setAlternateImage: [NSImage imageNamed: @"common_ArrowLeftH"]];
[cell setImagePosition: NSImageOnly];
name = GSScrollerLeftArrow;
}
else
{
@ -301,6 +303,7 @@
[cell setImage: [NSImage imageNamed: @"common_ArrowRight"]];
[cell setAlternateImage: [NSImage imageNamed: @"common_ArrowRightH"]];
[cell setImagePosition: NSImageOnly];
name = GSScrollerRightArrow;
}
}
else
@ -312,6 +315,7 @@
[cell setImage: [NSImage imageNamed: @"common_ArrowUp"]];
[cell setAlternateImage: [NSImage imageNamed: @"common_ArrowUpH"]];
[cell setImagePosition: NSImageOnly];
name = GSScrollerDownArrow;
}
else
{
@ -320,9 +324,12 @@
[cell setImage: [NSImage imageNamed: @"common_ArrowDown"]];
[cell setAlternateImage: [NSImage imageNamed: @"common_ArrowDownH"]];
[cell setImagePosition: NSImageOnly];
name = GSScrollerUpArrow;
}
}
return AUTORELEASE(cell);
[self setName: name forElement: cell temporary: YES];
RELEASE(cell);
return cell;
}
- (NSCell*) cellForScrollerKnob: (BOOL)horizontal
@ -333,7 +340,16 @@
[cell setButtonType: NSMomentaryChangeButton];
[cell setImage: [NSImage imageNamed: @"common_Dimple"]];
[cell setImagePosition: NSImageOnly];
return AUTORELEASE(cell);
if (horizontal)
{
[self setName: GSScrollerHorizontalKnob forElement: cell temporary: YES];
}
else
{
[self setName: GSScrollerVerticalKnob forElement: cell temporary: YES];
}
RELEASE(cell);
return cell;
}
- (NSCell*) cellForScrollerKnobSlot: (BOOL)horizontal
@ -344,7 +360,16 @@
[cell setBordered: NO];
[cell setStringValue: nil];
[cell setBackgroundColor: [NSColor scrollBarColor]];
return AUTORELEASE(cell);
if (horizontal)
{
[self setName: GSScrollerHorizontalSlot forElement: cell temporary: YES];
}
else
{
[self setName: GSScrollerVerticalSlot forElement: cell temporary: YES];
}
RELEASE(cell);
return cell;
}
- (float) defaultScrollerWidth

View file

@ -69,30 +69,20 @@ static float scrollerWidth = 18.0;
static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
+ (void) _themeWillActivate: (NSNotification*)n
+ (void) _themeWillDeactivate: (NSNotification*)n
{
GSTheme *theme = [GSTheme theme];
/* Clear cached information from the old theme ... will get info from
* the new theme as required.
*/
scrollerWidth = 0.0;
[theme setName: nil forElement: upCell];
DESTROY(upCell);
[theme setName: nil forElement: downCell];
DESTROY(downCell);
[theme setName: nil forElement: leftCell];
DESTROY(leftCell);
[theme setName: nil forElement: rightCell];
DESTROY(rightCell);
[theme setName: nil forElement: verticalKnobCell];
DESTROY(horizontalKnobCell);
[theme setName: nil forElement: horizontalKnobCell];
DESTROY(verticalKnobCell);
[theme setName: nil forElement: verticalKnobSlotCell];
DESTROY(horizontalKnobSlotCell);
[theme setName: nil forElement: horizontalKnobSlotCell];
DESTROY(verticalKnobSlotCell);
upCell = nil;
downCell = nil;
leftCell = nil;
rightCell = nil;
horizontalKnobCell = nil;
verticalKnobCell = nil;
horizontalKnobSlotCell = nil;
verticalKnobSlotCell = nil;
}
/*
@ -104,8 +94,8 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
{
[self setVersion: 1];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(_themeWillActivate:)
name: GSThemeWillActivateNotification
selector: @selector(_themeWillDeactivate:)
name: GSThemeWillDeactivateNotification
object: nil];
}
}
@ -368,33 +358,18 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
theme = [GSTheme theme];
ASSIGN(upCell ,[theme cellForScrollerArrow:
NSScrollerDecrementArrow horizontal:NO]);
[theme setName: GSScrollerUpArrow forElement: upCell];
ASSIGN(downCell, [theme cellForScrollerArrow:
NSScrollerIncrementArrow horizontal:NO]);
[theme setName: GSScrollerDownArrow forElement: downCell];
ASSIGN(leftCell, [theme cellForScrollerArrow:
NSScrollerDecrementArrow horizontal:YES]);
[theme setName: GSScrollerLeftArrow forElement: leftCell];
ASSIGN(rightCell, [theme cellForScrollerArrow:
NSScrollerIncrementArrow horizontal:YES]);
[theme setName: GSScrollerRightArrow forElement: rightCell];
ASSIGN(verticalKnobCell, [theme cellForScrollerKnob: NO]);
[theme setName: GSScrollerVerticalKnob forElement: verticalKnobCell];
ASSIGN(horizontalKnobCell, [theme cellForScrollerKnob: YES]);
[theme setName: GSScrollerHorizontalKnob forElement: horizontalKnobCell];
ASSIGN(verticalKnobSlotCell, [theme cellForScrollerKnobSlot: NO]);
[theme setName: GSScrollerVerticalSlot forElement: verticalKnobSlotCell];
ASSIGN(horizontalKnobSlotCell, [theme cellForScrollerKnobSlot: YES]);
[theme setName: GSScrollerHorizontalSlot forElement: horizontalKnobSlotCell];
upCell
= [theme cellForScrollerArrow: NSScrollerDecrementArrow horizontal:NO];
downCell
= [theme cellForScrollerArrow: NSScrollerIncrementArrow horizontal:NO];
leftCell
= [theme cellForScrollerArrow: NSScrollerDecrementArrow horizontal:YES];
rightCell
= [theme cellForScrollerArrow: NSScrollerIncrementArrow horizontal:YES];
verticalKnobCell = [theme cellForScrollerKnob: NO];
horizontalKnobCell = [theme cellForScrollerKnob: YES];
verticalKnobSlotCell = [theme cellForScrollerKnobSlot: NO];
horizontalKnobSlotCell = [theme cellForScrollerKnobSlot: YES];
[downCell setContinuous: YES];
[downCell sendActionOn: (NSLeftMouseDownMask | NSPeriodicMask)];
@ -994,9 +969,11 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
- (void) drawKnob
{
if (_isHorizontal)
[horizontalKnobCell drawWithFrame: [self rectForPart: NSScrollerKnob] inView: self];
[horizontalKnobCell drawWithFrame: [self rectForPart: NSScrollerKnob]
inView: self];
else
[verticalKnobCell drawWithFrame: [self rectForPart: NSScrollerKnob] inView: self];
[verticalKnobCell drawWithFrame: [self rectForPart: NSScrollerKnob]
inView: self];
}
- (void) drawKnobSlot
@ -1009,9 +986,9 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
}
if (_isHorizontal)
[horizontalKnobSlotCell drawWithFrame:rect inView:self];
[horizontalKnobSlotCell drawWithFrame: rect inView: self];
else
[verticalKnobSlotCell drawWithFrame:rect inView:self];
[verticalKnobSlotCell drawWithFrame: rect inView: self];
}
/**<p>Highlights the button whose under the mouse. Does nothing if the mouse