Theme alteration for Riccardo, plus some formatting tweaks

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@39110 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2015-11-01 15:38:47 +00:00
parent 3ff8c0a8d7
commit 1501023c3b
3 changed files with 216 additions and 100 deletions

View file

@ -1,3 +1,18 @@
2015-11-01 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSImage.m: Alter loading of image by name so that before we
try t load from the app's main bundle, we try loading an image of the
same name from the current theme's ThemeImages/bundleIdentifier
subdirectory. This allows a theme to provide an alternative image
for any named image normally provided by the app, as discussed this
morning.
NB. I adopted Ivan's suggestion of requiring a bundle identifier even
though we thought we could use the app name as a fallback ... since
it seems cleaner (and we can always edit the app's property list to
add a bundle identifier if it somehow got omitted by the developer).
Also reformatted some code/comments to conform to coding standards
and not exceed 80 character line limit.
2015-10-28 Riccardo Mottola <rm@gnu.org>
* Headers/AppKit/NSApplication.h

View file

@ -111,18 +111,30 @@ NSString *GSSliderVerticalTrack = @"GSSliderVerticalTrack";
NSString *GSBoxBorder = @"GSBoxBorder";
/* NSTabView parts */
NSString *GSTabViewSelectedTabFill = @"GSTabViewSelectedTabFill";
NSString *GSTabViewUnSelectedTabFill = @"GSTabViewUnSelectedTabFill";
NSString *GSTabViewBackgroundTabFill = @"GSTabViewBackgroundTabFill";
NSString *GSTabViewBottomSelectedTabFill = @"GSTabViewBottomSelectedTabFill";
NSString *GSTabViewBottomUnSelectedTabFill = @"GSTabViewBottomUnSelectedTabFill";
NSString *GSTabViewBottomBackgroundTabFill = @"GSTabViewBottomBackgroundTabFill";
NSString *GSTabViewLeftSelectedTabFill = @"GSTabViewLeftSelectedTabFill";
NSString *GSTabViewLeftUnSelectedTabFill = @"GSTabViewLeftUnSelectedTabFill";
NSString *GSTabViewLeftBackgroundTabFill = @"GSTabViewLeftBackgroundTabFill";
NSString *GSTabViewRightSelectedTabFill = @"GSTabViewRightSelectedTabFill";
NSString *GSTabViewRightUnSelectedTabFill = @"GSTabViewRightUnSelectedTabFill";
NSString *GSTabViewRightBackgroundTabFill = @"GSTabViewRightBackgroundTabFill";
NSString *GSTabViewSelectedTabFill
= @"GSTabViewSelectedTabFill";
NSString *GSTabViewUnSelectedTabFill
= @"GSTabViewUnSelectedTabFill";
NSString *GSTabViewBackgroundTabFill
= @"GSTabViewBackgroundTabFill";
NSString *GSTabViewBottomSelectedTabFill
= @"GSTabViewBottomSelectedTabFill";
NSString *GSTabViewBottomUnSelectedTabFill
= @"GSTabViewBottomUnSelectedTabFill";
NSString *GSTabViewBottomBackgroundTabFill
= @"GSTabViewBottomBackgroundTabFill";
NSString *GSTabViewLeftSelectedTabFill
= @"GSTabViewLeftSelectedTabFill";
NSString *GSTabViewLeftUnSelectedTabFill
= @"GSTabViewLeftUnSelectedTabFill";
NSString *GSTabViewLeftBackgroundTabFill
= @"GSTabViewLeftBackgroundTabFill";
NSString *GSTabViewRightSelectedTabFill
= @"GSTabViewRightSelectedTabFill";
NSString *GSTabViewRightUnSelectedTabFill
= @"GSTabViewRightUnSelectedTabFill";
NSString *GSTabViewRightBackgroundTabFill
= @"GSTabViewRightBackgroundTabFill";
NSString *GSThemeDidActivateNotification
@ -184,14 +196,22 @@ GSStringFromSegmentStyle(NSSegmentStyle segmentStyle)
{
switch (segmentStyle)
{
case NSSegmentStyleAutomatic: return @"NSSegmentStyleAutomatic";
case NSSegmentStyleRounded: return @"NSSegmentStyleRounded";
case NSSegmentStyleTexturedRounded: return @"NSSegmentStyleTexturedRounded";
case NSSegmentStyleRoundRect: return @"NSSegmentStyleRoundRect";
case NSSegmentStyleTexturedSquare: return @"NSSegmentStyleTexturedSquare";
case NSSegmentStyleCapsule: return @"NSSegmentStyleCapsule";
case NSSegmentStyleSmallSquare: return @"NSSegmentStyleSmallSquare";
default: return nil;
case NSSegmentStyleAutomatic:
return @"NSSegmentStyleAutomatic";
case NSSegmentStyleRounded:
return @"NSSegmentStyleRounded";
case NSSegmentStyleTexturedRounded:
return @"NSSegmentStyleTexturedRounded";
case NSSegmentStyleRoundRect:
return @"NSSegmentStyleRoundRect";
case NSSegmentStyleTexturedSquare:
return @"NSSegmentStyleTexturedSquare";
case NSSegmentStyleCapsule:
return @"NSSegmentStyleCapsule";
case NSSegmentStyleSmallSquare:
return @"NSSegmentStyleSmallSquare";
default:
return nil;
}
}
@ -200,26 +220,46 @@ GSStringFromBezelStyle(NSBezelStyle bezelStyle)
{
switch (bezelStyle)
{
case NSRoundedBezelStyle: return @"NSRoundedBezelStyle";
case NSRegularSquareBezelStyle: return @"NSRegularSquareBezelStyle";
case NSThickSquareBezelStyle: return @"NSThickSquareBezelStyle";
case NSThickerSquareBezelStyle: return @"NSThickerSquareBezelStyle";
case NSDisclosureBezelStyle: return @"NSDisclosureBezelStyle";
case NSShadowlessSquareBezelStyle: return @"NSShadowlessSquareBezelStyle";
case NSCircularBezelStyle: return @"NSCircularBezelStyle";
case NSTexturedSquareBezelStyle: return @"NSTexturedSquareBezelStyle";
case NSHelpButtonBezelStyle: return @"NSHelpButtonBezelStyle";
case NSSmallSquareBezelStyle: return @"NSSmallSquareBezelStyle";
case NSTexturedRoundedBezelStyle: return @"NSTexturedRoundedBezelStyle";
case NSRoundRectBezelStyle: return @"NSRoundRectBezelStyle";
case NSRecessedBezelStyle: return @"NSRecessedBezelStyle";
case NSRoundedDisclosureBezelStyle: return @"NSRoundedDisclosureBezelStyle";
case NSNeXTBezelStyle: return @"NSNeXTBezelStyle";
case NSPushButtonBezelStyle: return @"NSPushButtonBezelStyle";
case NSSmallIconButtonBezelStyle: return @"NSSmallIconButtonBezelStyle";
case NSMediumIconButtonBezelStyle: return @"NSMediumIconButtonBezelStyle";
case NSLargeIconButtonBezelStyle: return @"NSLargeIconButtonBezelStyle";
default: return nil;
case NSRoundedBezelStyle:
return @"NSRoundedBezelStyle";
case NSRegularSquareBezelStyle:
return @"NSRegularSquareBezelStyle";
case NSThickSquareBezelStyle:
return @"NSThickSquareBezelStyle";
case NSThickerSquareBezelStyle:
return @"NSThickerSquareBezelStyle";
case NSDisclosureBezelStyle:
return @"NSDisclosureBezelStyle";
case NSShadowlessSquareBezelStyle:
return @"NSShadowlessSquareBezelStyle";
case NSCircularBezelStyle:
return @"NSCircularBezelStyle";
case NSTexturedSquareBezelStyle:
return @"NSTexturedSquareBezelStyle";
case NSHelpButtonBezelStyle:
return @"NSHelpButtonBezelStyle";
case NSSmallSquareBezelStyle:
return @"NSSmallSquareBezelStyle";
case NSTexturedRoundedBezelStyle:
return @"NSTexturedRoundedBezelStyle";
case NSRoundRectBezelStyle:
return @"NSRoundRectBezelStyle";
case NSRecessedBezelStyle:
return @"NSRecessedBezelStyle";
case NSRoundedDisclosureBezelStyle:
return @"NSRoundedDisclosureBezelStyle";
case NSNeXTBezelStyle:
return @"NSNeXTBezelStyle";
case NSPushButtonBezelStyle:
return @"NSPushButtonBezelStyle";
case NSSmallIconButtonBezelStyle:
return @"NSSmallIconButtonBezelStyle";
case NSMediumIconButtonBezelStyle:
return @"NSMediumIconButtonBezelStyle";
case NSLargeIconButtonBezelStyle:
return @"NSLargeIconButtonBezelStyle";
default:
return nil;
}
}
@ -241,14 +281,14 @@ GSStringFromTabViewType(NSTabViewType type)
{
switch (type)
{
case NSTopTabsBezelBorder: return @"NSTopTabsBezelBorder";
case NSBottomTabsBezelBorder: return @"NSBottomTabsBezelBorder";
case NSLeftTabsBezelBorder: return @"NSLeftTabsBezelBorder";
case NSRightTabsBezelBorder: return @"NSRightTabsBezelBorder";
case NSNoTabsBezelBorder: return @"NSNoTabsBezelBorder";
case NSNoTabsLineBorder: return @"NSNoTabsLineBorder";
case NSNoTabsNoBorder: return @"NSNoTabsNoBorder";
default: return nil;
case NSTopTabsBezelBorder: return @"NSTopTabsBezelBorder";
case NSBottomTabsBezelBorder: return @"NSBottomTabsBezelBorder";
case NSLeftTabsBezelBorder: return @"NSLeftTabsBezelBorder";
case NSRightTabsBezelBorder: return @"NSRightTabsBezelBorder";
case NSNoTabsBezelBorder: return @"NSNoTabsBezelBorder";
case NSNoTabsLineBorder: return @"NSNoTabsLineBorder";
case NSNoTabsNoBorder: return @"NSNoTabsNoBorder";
default: return nil;
}
}
@ -257,12 +297,12 @@ GSStringFromImageFrameStyle(NSImageFrameStyle type)
{
switch (type)
{
case NSImageFrameNone: return @"NSImageFrameNone";
case NSImageFramePhoto: return @"NSImageFramePhoto";
case NSImageFrameGrayBezel: return @"NSImageFrameGrayBezel";
case NSImageFrameGroove: return @"NSImageFrameGroove";
case NSImageFrameButton: return @"NSImageFrameButton";
default: return nil;
case NSImageFrameNone: return @"NSImageFrameNone";
case NSImageFramePhoto: return @"NSImageFramePhoto";
case NSImageFrameGrayBezel: return @"NSImageFrameGrayBezel";
case NSImageFrameGroove: return @"NSImageFrameGroove";
case NSImageFrameButton: return @"NSImageFrameButton";
default: return nil;
}
}
@ -1149,13 +1189,15 @@ typedef struct {
fullName = [aName stringByAppendingString: @"Disabled"];
break;
case GSThemeHighlightedFirstResponderState:
fullName = [aName stringByAppendingString: @"HighlightedFirstResponder"];
fullName
= [aName stringByAppendingString: @"HighlightedFirstResponder"];
break;
case GSThemeHighlightedState:
fullName = [aName stringByAppendingString: @"Highlighted"];
break;
case GSThemeSelectedFirstResponderState:
fullName = [aName stringByAppendingString: @"SelectedFirstResponder"];
fullName
= [aName stringByAppendingString: @"SelectedFirstResponder"];
break;
case GSThemeSelectedState:
fullName = [aName stringByAppendingString: @"Selected"];

View file

@ -397,9 +397,9 @@ repd_for_rep(NSArray *_reps, NSImageRep *rep)
NSArray *array = [pasteboard propertyListForType: NSFilenamesPboardType];
NSString* file;
if ((array == nil) || ([array count] == 0) ||
(file = [array objectAtIndex: 0]) == nil ||
![self _loadFromFile: file])
if ((array == nil) || ([array count] == 0)
|| (file = [array objectAtIndex: 0]) == nil
|| ![self _loadFromFile: file])
{
RELEASE(self);
return nil;
@ -1210,12 +1210,16 @@ static NSSize GSResolutionOfImageRep(NSImageRep *rep)
const NSSize repRes = GSResolutionOfImageRep(rep);
if (GSSizeIsIntegerMultipleOfSize(repRes, dres))
{
const NSSize repResDifference = NSMakeSize(fabs(repRes.width - dres.width),
fabs(repRes.height - dres.height));
const NSSize closestResolutionDifference = NSMakeSize(fabs(closestRes.width - dres.width),
fabs(closestRes.height - dres.height));
if (repResDifference.width < closestResolutionDifference.width &&
repResDifference.height < closestResolutionDifference.height)
const NSSize repResDifference
= NSMakeSize(fabs(repRes.width - dres.width),
fabs(repRes.height - dres.height));
const NSSize closestResolutionDifference
= NSMakeSize(fabs(closestRes.width - dres.width),
fabs(closestRes.height - dres.height));
if (repResDifference.width
< closestResolutionDifference.width
&& repResDifference.height
< closestResolutionDifference.height)
{
closestRes = repRes;
}
@ -1478,10 +1482,10 @@ static NSSize GSResolutionOfImageRep(NSImageRep *rep)
while ((rep = [enumerator nextObject]) != nil)
{
const NSSize repSize = [rep size];
if ((repSize.width >= desiredSize.width) &&
(repSize.height >= desiredSize.height) &&
(repSize.width < bestSize.width) &&
(repSize.height < bestSize.height))
if ((repSize.width >= desiredSize.width)
&& (repSize.height >= desiredSize.height)
&& (repSize.width < bestSize.width)
&& (repSize.height < bestSize.height))
{
bestSize = repSize;
bestRep = rep;
@ -1515,10 +1519,14 @@ static NSSize GSResolutionOfImageRep(NSImageRep *rep)
// Producing TIFF Data for the Image
- (NSData *) TIFFRepresentation
{
NSData *data;
NSArray *reps;
NSData *data;
// As a result of using bitmap representations, new drawing wont show on the tiff data.
data = [bitmapClass TIFFRepresentationOfImageRepsInArray: [self _representationsWithCachedImages: NO]];
/* As a result of using bitmap representations,
* new drawing wont show on the tiff data.
*/
reps = [self _representationsWithCachedImages: NO];
data = [bitmapClass TIFFRepresentationOfImageRepsInArray: reps];
if (!data)
{
@ -1544,22 +1552,28 @@ static NSSize GSResolutionOfImageRep(NSImageRep *rep)
- (NSData *) TIFFRepresentationUsingCompression: (NSTIFFCompression)comp
factor: (float)aFloat
{
NSData *data;
NSArray *reps;
NSData *data;
// As a result of using bitmap representations, new drawing wont show on the tiff data.
data = [bitmapClass TIFFRepresentationOfImageRepsInArray: [self _representationsWithCachedImages: NO]
usingCompression: comp
factor: aFloat];
/* As a result of using bitmap representations,
* new drawing wont show on the tiff data.
*/
reps = [self _representationsWithCachedImages: NO];
data = [bitmapClass TIFFRepresentationOfImageRepsInArray: reps
usingCompression: comp
factor: aFloat];
if (!data)
{
NSBitmapImageRep *rep;
NSSize size = [self size];
// If there isn't a bitmap representation to output, create one and store it.
/* If there isn't a bitmap representation to output,
* create one and store it.
*/
[self lockFocus];
rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:
NSMakeRect(0.0, 0.0, size.width, size.height)];
NSMakeRect(0.0, 0.0, size.width, size.height)];
[self unlockFocus];
if (nil != rep)
{
@ -1694,7 +1708,8 @@ static NSSize GSResolutionOfImageRep(NSImageRep *rep)
if ([coder containsValueForKey: @"NSName"])
{
RELEASE(self);
return RETAIN([NSImage imageNamed: [coder decodeObjectForKey: @"NSName"]]);
return RETAIN([NSImage imageNamed:
[coder decodeObjectForKey: @"NSName"]]);
}
if ([coder containsValueForKey: @"NSColor"])
{
@ -1718,8 +1733,10 @@ static NSSize GSResolutionOfImageRep(NSImageRep *rep)
NSArray *reps;
NSUInteger i;
// FIXME: NSReps is in a strange format. It is a mutable array with one
// element which is an array with a first element 0 and than the image rep.
/* FIXME: NSReps is in a strange format. It is a mutable array
* with one element which is an array with a first element 0
* and than the image rep.
*/
reps = [coder decodeObjectForKey: @"NSReps"];
reps = [reps objectAtIndex: 0];
for (i = 1; i < [reps count]; i++)
@ -1736,12 +1753,17 @@ static NSSize GSResolutionOfImageRep(NSImageRep *rep)
NSURL *tmp = (NSURL*)rep;
rep = [NSImageRep imageRepWithContentsOfURL: rep];
// If we are unable to resolved the URL, try to get it from the
// resources folder.
/* If we are unable to resolved the URL,
* try to get it from the resources folder.
*/
if (rep == nil)
{
NSString *fileName = [[tmp absoluteString] lastPathComponent];
NSString *path = [[NSBundle mainBundle] pathForImageResource: fileName];
NSString *fileName;
NSString *path;
fileName = [[tmp absoluteString] lastPathComponent];
path = [[NSBundle mainBundle]
pathForImageResource: fileName];
rep = [NSImageRep imageRepWithContentsOfFile: path];
}
@ -2022,8 +2044,8 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
ext = nil;
}
*aType = ext;
return name;
*aType = ext;
return name;
}
+ (NSString *) _pathForImageNamed: (NSString *)aName
@ -2054,6 +2076,31 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
return nil;
}
/* We support application specific images in a subdirectory where the
* subdirectory name is the app's bundle identifier.
* Loading from this location takes precedence over loading from the
* app's main bundle.
*/
+ (NSString *) _pathForThemeAppImageNamed: (NSString *)aName
ofType: (NSString *)ext
{
NSString *ident = [[NSBundle mainBundle] bundleIdentifier];
NSString *path = nil;
if (nil != ident)
{
NSString *subdir;
subdir = [@"ThemeImages" stringByAppendingPathComponent: ident];
path = [self _pathForImageNamed: aName
ofType: ext
subdirectory: subdir
inBundle: [[GSTheme theme] bundle]];
}
return path;
}
/*
* The type received in argument is meaningfull for searching image files
* using the proposed image name, but useless otherwise.
@ -2094,7 +2141,8 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
while ((aliasName = [e nextObject]) != nil)
{
NSAssert([[aliasName pathExtension] length] == 0, @"nsmapping.strings "
NSAssert([[aliasName pathExtension] length] == 0,
@"nsmapping.strings "
"must include no extensions in image file names");
path = [self _pathForImageNamed: aliasName
@ -2107,7 +2155,8 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
}
}
/* If not found, search among the theme images using the image name directly */
/* If not found, search among the theme images using the image name directly
*/
if (path == nil)
{
path = [self _pathForImageNamed: aName
@ -2141,17 +2190,23 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
+ (NSString *) _pathForImageNamed: (NSString *)aName
{
NSString *ext = nil;
NSString *proposedName = [self _resourceNameForImageNamed: aName type: &ext];
NSString *path = nil;
NSString *proposedName;
NSString *path;
// FIXME: This should use [NSBundle pathForImageResource] if possible, but
// this will only allow imageUnfilteredFileTypes.
proposedName = [self _resourceNameForImageNamed: aName type: &ext];
path = [self _pathForThemeAppImageNamed: proposedName ofType: ext];
/* First search locally */
path = [self _pathForImageNamed: proposedName
ofType: ext
subdirectory: nil
inBundle: [NSBundle mainBundle]];
if (nil == path)
{
path = [self _pathForImageNamed: proposedName
ofType: ext
subdirectory: nil
inBundle: [NSBundle mainBundle]];
}
/* If not found then search in theme */
if (path == nil)
@ -2383,9 +2438,11 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
if (pixelsWide == NSImageRepMatchesDevice ||
pixelsHigh == NSImageRepMatchesDevice)
{
// FIXME: Since the cached rep must be a bitmap,
// we must rasterize vector reps at a particular DPI.
// Here we hardcode 72, but we should choose the DPI more intelligently.
/* FIXME: Since the cached rep must be a bitmap,
* we must rasterize vector reps at a particular DPI.
* Here we hardcode 72, but we should choose the DPI
* more intelligently.
*/
pixelsWide = repSize.width;
pixelsHigh = repSize.height;
}
@ -2393,7 +2450,9 @@ iterate_reps_for_types(NSArray* imageReps, SEL method)
else // e.g. when there are no representations at all
{
repSize = imageSize;
// FIXME: assumes 72 DPI. Also truncates, not sure if that is a problem.
/* FIXME: assumes 72 DPI. Also truncates,
* not sure if that is a problem.
*/
pixelsWide = imageSize.width;
pixelsHigh = imageSize.height;
}