Use proxies for named images so that changes to images are nstantly reflected

when you change themes.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@27810 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2009-02-08 11:02:57 +00:00
parent 6bec341a72
commit fa0b8d995b
3 changed files with 78 additions and 7 deletions

View file

@ -1,3 +1,12 @@
2009-02-08 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSImage.m: WARNING ... this change may have unforseen
consequences. Named images are replaced by proxies to the images
so that all image drawing the the gui updates instantly when the
theme changes. It's possible that sme code uses the image in an
unexpected way that the proxy does not support ... plase look out
for that and report any problems so I can fix them.
2009-02-08 01:17-EST Gregory John Casamento <greg_casamento@yahoo.com>
* Source/NSApplication.m: Added code to handle exceptions in

View file

@ -35,6 +35,7 @@
#include <Foundation/NSException.h>
#include <Foundation/NSFileManager.h>
#include <Foundation/NSKeyedArchiver.h>
#include <Foundation/NSProxy.h>
#include <Foundation/NSString.h>
#include <Foundation/NSValue.h>
@ -71,6 +72,59 @@ static double gs_max(double x, double y)
return x;
}
@interface GSImageProxy : NSProxy
{
NSImage *_image;
}
- (NSImage*) _image;
- (void) _setImage: (NSImage*)image;
@end
@implementation GSImageProxy
- (NSImage*) _image
{
return _image;
}
- (void) _setImage: (NSImage*)image
{
ASSIGN(_image, image);
}
- (void) dealloc
{
DESTROY(_image);
[super dealloc];
}
- (void) forwardInvocation: (NSInvocation*)anInvocation
{
[anInvocation invokeWithTarget: _image];
}
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector
{
if (_image != nil)
{
return [_image methodSignatureForSelector: aSelector];
}
else
{
/*
* Evil hack to prevent recursion - if we are asking a remote
* object for a method signature, we can't ask it for the
* signature of methodSignatureForSelector:, so we hack in
* the signature required manually :-(
*/
if (sel_eq(aSelector, _cmd))
{
static NSMethodSignature *sig = nil;
if (sig == nil)
{
sig = RETAIN([NSMethodSignature signatureWithObjCTypes: "@@::"]);
}
return sig;
}
return nil;
}
}
@end
BOOL NSImageForceCaching = NO; /* use on missmatch */
@ -471,8 +525,8 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
RELEASE(_reps);
/* Make sure we don't remove name from the nameDict if we are just a copy
of the named image, not the original image */
if (_name && self == [nameDict objectForKey: _name])
[nameDict removeObjectForKey: _name];
if (_name && self == [[nameDict objectForKey: _name] _image])
[[nameDict objectForKey: _name] _setImage: nil];
RELEASE(_name);
TEST_RELEASE(_fileName);
RELEASE(_color);
@ -510,23 +564,30 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
- (BOOL) setName: (NSString *)aName
{
GSImageProxy *proxy = nil;
BOOL retained = NO;
if (!aName || [nameDict objectForKey: aName])
if (!aName || [[nameDict objectForKey: aName] _image] != nil)
return NO;
if (_name && self == [nameDict objectForKey: _name])
if (_name && self == [(proxy = [nameDict objectForKey: _name]) _image])
{
/* We retain self in case removing from the dictionary releases
us */
RETAIN (self);
retained = YES;
[nameDict removeObjectForKey: _name];
[proxy _setImage: nil];
}
ASSIGN(_name, aName);
[nameDict setObject: self forKey: _name];
if ((proxy = [nameDict objectForKey: _name]) == nil)
{
proxy = [GSImageProxy alloc];
[nameDict setObject: proxy forKey: _name];
[proxy release];
}
[proxy _setImage: self];
if (retained)
{
RELEASE (self);

View file

@ -1007,7 +1007,8 @@ static float scrollerWidth;
contentRect = NSInsetRect(_bounds, border.width, border.height);
if (contentRect.size.width < 0 || contentRect.size.height < 0)
{
NSWarnMLog(@"given too small a size to tile", 0);
/* FIXME ... should we do something else when given
* too small a size to tile? */
return;
}