Accessing bottom / custom NSColorPanel colors

I would like to read the list of colors that are shown below NSColorPanel

(see picture below). Is there a way to do this?

+3


source to share


2 answers


For undocumented access (this may not work in the sandbox, but will cause your Apple app to be rejected if you plan to distribute it via the App Store ):

NSArray *libraries = [[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSAllDomainsMask];
NSURL *url = [[libraries objectAtIndex:0] URLByAppendingPathComponent:@"Colors/NSColorPanelSwatches.plist"];
NSData *fileData = [NSData dataWithContentsOfURL:url];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:fileData];

NSArray *colors = [unarchiver decodeObjectForKey:@"NSSwatchColorArray"];

      

The array colors

will contain the NSColor

objects of the colored panel.

This works back in OS X 10.6. It can work with earlier versions as well, but you will need to get the filename in a different way (since it URLsForDirectory:inDomains:

was introduced in 10.6). Inside the file NSColorPanelSwatches.plist

is the internal version number, which is set to 6

for 10.6 to 10.10. This may change in the future, but you may be more or less safe by doing:



if ([unarchiver decodeIntForKey:@"NSSwatchFileVersion"] == 6)
{
    NSArray *colors = [unarchiver objectForKey:@"NSSwatchColorArray"];
    // do something with colors
}
else
{
    NSLog(@"System unsupported");
}

      

If you are wondering where the positions of the colors are, you can decode NSIndexSet

from the unarchiver with a key NSSwatchColorIndexes

and use that index set in combination with the number of rows and columns that you can determine by decoding integers with the keys NSSwatchLayoutNumRows

and NSSwatchLayoutNumColumns

. The nth index in the set of indices refers to the location of the nth color in the array, and the indices are incremented downward. For example, the first "colored square" on the panel is index 0, and the field below it is index 1. The field to the right of "index 0" is actually index 10 (or whatever number you decoded from NSSwatchLayoutNumRows

).

So, if you have a color in the first box and another color in the box on the right, you will have two objects NSColor

in the array colors

, and it NSIndexSet

will contain two indices, 0 and 10.

+2


source


Unfortunately, there are no public APIs for accessing user-supplied system-wide colors from swatches. This is a very old problem. NSColorPanel

long delayed for an Apple overhaul ...



+1


source







All Articles