39 var _redComponent = 0,
44 var _hueComponent = 0,
45 _saturationComponent = 1,
46 _brightnessComponent = 2;
97 @"alternate-selected-control-color": [
CPNull null],
98 @"secondary-selected-control-color": [
CPNull null],
99 @"selected-text-background-color": [
CPNull null],
100 @"selected-text-inactive-background-color": [
CPNull null]
106 #pragma mark Static methods 121 + (
CPColor)colorWithRed:(
float)red green:(
float)green blue:(
float)blue alpha:(
float)alpha
123 return [[
CPColor alloc] _initWithRGBA:[MAX(0.0, MIN(1.0, red)), MAX(0.0, MIN(1.0, green)), MAX(0.0, MIN(1.0, blue)), MAX(0.0, MIN(1.0, alpha))]];
141 + (
CPColor)colorWithCalibratedRed:(
float)red green:(
float)green blue:(
float)blue alpha:(
float)alpha
156 + (
CPColor)colorWithWhite:(
float)white alpha:(
float)alpha
158 return [[
CPColor alloc] _initWithRGBA:[white, white, white, alpha]];
172 + (
CPColor)colorWithCalibratedWhite:(
float)white alpha:(
float)alpha
190 + (
CPColor)colorWithHue:(
float)hue saturation:(
float)saturation brightness:(
float)brightness
200 + (
CPColor)colorWithCalibratedHue:(
float)hue saturation:(
float)saturation brightness:(
float)brightness alpha:(
float)alpha
219 + (
CPColor)colorWithHue:(
float)hue saturation:(
float)saturation brightness:(
float)brightness alpha:(
float)alpha
222 hue = MAX(MIN(hue, 1.0), 0.0);
223 saturation = MAX(MIN(saturation, 1.0), 0.0);
224 brightness = MAX(MIN(brightness, 1.0), 0.0);
226 if (saturation === 0.0)
229 var f = (hue * 360) % 60,
230 p = (brightness * (1 - saturation)),
231 q = (brightness * (60 - saturation * f)) / 60,
232 t = (brightness * (60 - saturation * (60 - f))) / 60,
235 switch (FLOOR(hue * 6))
265 var rgba = hexToRGB(hex);
266 return rgba ? [[
CPColor alloc] _initWithRGBA: rgba] : null;
273 + (
CPColor)colorWithSRGBRed:(
float)red green:(
float)green blue:(
float)blue alpha:(
float)alpha
285 if (!cachedBlackColor)
286 cachedBlackColor = [[
CPColor alloc] _initWithRGBA:[0.0, 0.0, 0.0, 1.0]];
288 return cachedBlackColor;
296 if (!cachedBlueColor)
297 cachedBlueColor = [[
CPColor alloc] _initWithRGBA:[0.0, 0.0, 1.0, 1.0]];
299 return cachedBlueColor;
307 if (!cachedDarkGrayColor)
310 return cachedDarkGrayColor;
318 if (!cachedGrayColor)
321 return cachedGrayColor;
329 if (!cachedGreenColor)
330 cachedGreenColor = [[
CPColor alloc] _initWithRGBA:[0.0, 1.0, 0.0, 1.0]];
332 return cachedGreenColor;
340 if (!cachedLightGrayColor)
343 return cachedLightGrayColor;
352 cachedRedColor = [[
CPColor alloc] _initWithRGBA:[1.0, 0.0, 0.0, 1.0]];
354 return cachedRedColor;
362 if (!cachedWhiteColor)
363 cachedWhiteColor = [[
CPColor alloc] _initWithRGBA:[1.0, 1.0, 1.0, 1.0]];
365 return cachedWhiteColor;
373 if (!cachedYellowColor)
374 cachedYellowColor = [[
CPColor alloc] _initWithRGBA:[1.0, 1.0, 0.0, 1.0]];
376 return cachedYellowColor;
384 if (!cachedBrownColor)
385 cachedBrownColor = [[
CPColor alloc] _initWithRGBA:[0.6, 0.4, 0.2, 1.0]];
387 return cachedBrownColor;
395 if (!cachedCyanColor)
396 cachedCyanColor = [[
CPColor alloc] _initWithRGBA:[0.0, 1.0, 1.0, 1.0]];
398 return cachedCyanColor;
406 if (!cachedMagentaColor)
407 cachedMagentaColor = [[
CPColor alloc] _initWithRGBA:[1.0, 0.0, 1.0, 1.0]];
409 return cachedMagentaColor;
417 if (!cachedOrangeColor)
418 cachedOrangeColor = [[
CPColor alloc] _initWithRGBA:[1.0, 0.5, 0.0, 1.0]];
420 return cachedOrangeColor;
428 if (!cachedPurpleColor)
429 cachedPurpleColor = [[
CPColor alloc] _initWithRGBA:[0.5, 0.0, 0.5, 1.0]];
431 return cachedPurpleColor;
440 if (!cachedShadowColor)
441 cachedShadowColor = [[
CPColor alloc] _initWithRGBA:[0.0, 0.0, 0.0, 1.0 / 3.0]];
443 return cachedShadowColor;
452 if (!cachedClearColor)
455 return cachedClearColor;
460 if (!cachedThemeColor)
463 return cachedThemeColor;
468 return [[
self _cachedThemeColor] valueForThemeAttribute:@"alternate-selected-control-color"];
473 return [[
self _cachedThemeColor] valueForThemeAttribute:@"secondary-selected-control-color"];
483 return [[
CPColor alloc] _initWithPatternImage:anImage];
494 return [[
CPColor alloc] _initWithCSSString: aString];
499 return [[
self _cachedThemeColor] valueForThemeAttribute:@"selected-text-background-color"] || [
CPColor colorWithHexString:"99CCFF"];
502 + (
CPColor)_selectedTextBackgroundColorUnfocussed
504 return [[
self _cachedThemeColor] valueForThemeAttribute:@"selected-text-inactive-background-color"] || [
CPColor colorWithHexString:"CCCCCC"];
508 - (id)_initWithCSSString:(
CPString)aString
515 var startingIndex = aString.indexOf(
"("),
516 parts = aString.substring(startingIndex + 1).split(
',');
519 parseInt(parts[0], 10) / 255.0,
520 parseInt(parts[1], 10) / 255.0,
521 parseInt(parts[2], 10) / 255.0,
522 parts[3] ? parseFloat(parts[3], 10) : 1.0
527 [
self _initCSSStringFromComponents];
530 _themeState = CPThemeStateNormal;
531 [
self _loadThemeAttributes];
545 [
self _initCSSStringFromComponents];
548 _themeState = CPThemeStateNormal;
549 [
self _loadThemeAttributes];
555 - (void)_initCSSStringFromComponents
559 _cssString = (hasAlpha ?
"rgba(" :
"rgb(") +
560 parseInt(_components[0] * 255.0) +
", " +
561 parseInt(_components[1] * 255.0) +
", " +
562 parseInt(_components[2] * 255.0) +
563 (hasAlpha ? (
", " + _components[3]) :
"") +
")";
567 - (id)_initWithPatternImage:(
CPImage)anImage
573 _patternImage = anImage;
574 _cssString =
"url(\"" + [_patternImage filename] +
"\")";
575 _components = [0.0, 0.0, 0.0, 1.0];
578 _themeState = CPThemeStateNormal;
579 [
self _loadThemeAttributes];
590 return _patternImage;
598 return _components[3];
606 return _components[2];
614 return _components[1];
622 return _components[0];
648 - (
CPColor)colorWithAlphaComponent:(
float)anAlphaComponent
652 components[components.length - 1] = anAlphaComponent;
654 return [[[
self class] alloc] _initWithRGBA:components];
660 - (
CPColor)colorUsingColorSpaceName:(
id)aColorSpaceName
680 var red = ROUND(_components[_redComponent] * 255.0),
681 green = ROUND(_components[_greenComponent] * 255.0),
682 blue = ROUND(_components[_blueComponent] * 255.0);
684 var max = MAX(red, green, blue),
685 min = MIN(red, green, blue),
688 var brightness = max / 255.0,
689 saturation = (max != 0) ? delta / max : 0;
699 var rr = (max - red) / delta,
700 gr = (max - green) / delta,
701 br = (max - blue) / delta;
705 else if (green == max)
776 if (![aColor isKindOfClass:
CPColor])
810 for (var i = 0; i < slices.length; ++i)
812 var imgDescription = [slices[i] description] ||
"nil";
814 description += imgDescription.replace(/^/mg,
" ") +
",\n";
874 var CPColorComponentsKey =
@"CPColorComponentsKey",
875 CPColorPatternImageKey =
@"CPColorPatternImageKey";
886 if ([aCoder containsValueForKey:CPColorPatternImageKey])
887 self = [
self _initWithPatternImage:[aCoder decodeObjectForKey:CPColorPatternImageKey]];
889 self = [
self _initWithRGBA:[aCoder decodeObjectForKey:CPColorComponentsKey]];
891 [
self _decodeThemeObjectsWithCoder:aCoder];
903 [aCoder encodeObject:_patternImage forKey:CPColorPatternImageKey];
905 [aCoder encodeObject:_components forKey:CPColorComponentsKey];
907 [
self _encodeThemeObjectsWithCoder:aCoder];
914 var hexCharacters =
"0123456789ABCDEF";
920 var hexToRGB =
function(hex)
923 hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
928 hex = hex.toUpperCase();
930 for (var i = 0; i < hex.length; i++)
931 if (hexCharacters.indexOf(hex.charAt(i)) == -1)
934 var red = (hexCharacters.indexOf(hex.charAt(0)) * 16 + hexCharacters.indexOf(hex.charAt(1))) / 255.0,
935 green = (hexCharacters.indexOf(hex.charAt(2)) * 16 + hexCharacters.indexOf(hex.charAt(3))) / 255.0,
936 blue = (hexCharacters.indexOf(hex.charAt(4)) * 16 + hexCharacters.indexOf(hex.charAt(5))) / 255.0;
938 return [red, green, blue, 1.0];
941 var rgbToHex =
function(r,g,b)
943 return byteToHex(r) + byteToHex(g) + byteToHex(b);
946 var byteToHex =
function(n)
951 n = FLOOR(MIN(255, MAX(0, 256 * n)));
953 return hexCharacters.charAt((n - n % 16) / 16) +
954 hexCharacters.charAt(n % 16);
1176 function CPColorWithImages()
1182 args = Array.prototype.slice.apply(arguments);
1184 if (typeof(args[args.length - 1]) ===
"function")
1185 imageFactory = args.pop();
1187 switch (args.length)
1190 return imageFromSlices(args[0], isVertical, imageFactory);
1194 if (typeof(args[0]) ===
"string")
1195 return patternColorsFromPattern.call(
this, args[0], args[1], imageFactory);
1197 return imageFromSlices(args[0], args[1], imageFactory);
1204 throw(
"ERROR: Invalid argument count: " + args.length);
1208 var imageFromSlices =
function(slices, isVertical, imageFactory)
1210 var imageSlices = [];
1212 for (var i = 0; i < slices.length; ++i)
1214 var slice = slices[i];
1216 imageSlices.push(slice ? imageFactory(slice[0], slice[1], slice[2], slice[3]) : nil);
1219 switch (slices.length)
1228 throw(
"ERROR: Invalid number of image slices: " + slices.length);
1232 var patternColorsFromPattern =
function(pattern, attributes, imageFactory)
1234 if (pattern.match(/^.*\{[^}]+\}/))
1236 var
width = attributes["width"],
1237 height = attributes["height"],
1238 separator = attributes["separator"] ||
"-",
1239 orientation = attributes["orientation"],
1247 if (pattern.indexOf(
"{position}") < 0)
1248 throw(
"ERROR: Pattern strings must have a {position} placeholder (\"" + pattern +
"\")");
1250 if (orientation === undefined)
1254 if (attributes[
"centerIsNil"] !== undefined)
1255 centerIsNil = attributes["centerIsNil"];
1260 isVertical = orientation === PatternIsVertical;
1264 if (attributes[
"centerHeight"])
1265 centerWidthHeight = attributes["centerHeight"];
1269 if (attributes[
"centerWidth"])
1270 centerWidthHeight = attributes["centerWidth"];
1274 if (attributes[
"rightWidth"])
1275 rightWidth = attributes["rightWidth"];
1277 if (attributes[
"bottomHeight"])
1278 bottomHeight = attributes["bottomHeight"];
1280 var positions = attributes["positions"] ||
"@",
1286 if (positions ===
"@")
1289 positions = ["top", "center", "bottom"];
1291 positions = ["left", "center", "right"];
1293 else if (positions ===
"#")
1294 positions = ["0", "1", "2"];
1296 throw(
"ERROR: Invalid positions: " + positions)
1300 if (positions ===
"@" || positions ===
"abbrev")
1301 positions = ["top-left", "top", "top-right", "left", "center", "right", "bottom-left", "bottom", "bottom-right"];
1302 else if (positions ===
"full")
1303 positions = ["top-left", "top-center", "top-right", "center-left", "center-center", "center-right", "bottom-left", "bottom-center", "bottom-right"];
1304 else if (positions ===
"#")
1305 positions = ["0", "1", "2", "3", "4", "5", "6", "7", "8"];
1307 throw(
"ERROR: Invalid positions: " + positions)
1311 if (pattern.indexOf(
"{state}") >= 0)
1313 states = attributes["states"];
1316 throw(
"ERROR: {state} placeholder in the pattern (\"" + pattern +
"\") but no states item in the attributes");
1320 if (pattern.indexOf(
"{style}") >= 0)
1322 styles = attributes["styles"];
1325 throw(
"ERROR: {style} placeholder in the pattern (\"" + pattern +
"\") but no styles item in the attributes");
1329 var placeholder =
"{position}",
1330 pos = pattern.indexOf(placeholder),
1333 for (i = 0; i < positions.length; ++i)
1334 positions[i] = pattern.replace(placeholder, pos === 0 ? positions[i] + separator : separator + positions[i]);
1336 var slices = positions,
1343 placeholder =
"{state}";
1344 pos = pattern.indexOf(placeholder);
1347 for (i = 0; i < states.length; ++i)
1349 var state = states[i];
1351 sep = state ? separator :
"";
1353 object[key] = slices.slice(0);
1354 replacePlaceholderInArray(
object[key], placeholder, pos === 0 ? state + sep : sep + state);
1360 placeholder =
"{style}";
1361 pos = pattern.indexOf(placeholder);
1363 var styleObject = {};
1365 for (i = 0; i < styles.length; ++i)
1367 var style = styles[i];
1369 sep = style ? separator :
"";
1373 styleObject[key] = cloneObject(
object);
1374 replacePlaceholderInObject(styleObject[key], placeholder, pos === 0 ? style + sep : sep + style);
1378 styleObject[key] = slices.slice(0);
1379 replacePlaceholderInArray(styleObject[key], placeholder, pos === 0 ? style + sep : sep + style);
1383 object = styleObject;
1386 if (styles || states)
1389 makeThreePartSlicesFromObject(
object, width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical);
1391 makeNinePartSlicesFromObject(
object, width, height, rightWidth, bottomHeight, centerIsNil);
1393 makeImagesFromObject(
object, isVertical, imageFactory);
1399 makeThreePartSlicesFromArray(
object, width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical);
1401 makeNinePartSlicesFromArray(
object, width, height, rightWidth, bottomHeight, centerIsNil);
1403 return imageFromSlices(
object, isVertical, imageFactory);
1407 throw(
"ERROR: No placeholders in slice pattern (\"" + pattern +
"\")");
1410 var replacePlaceholderInArray =
function(array, find, replacement)
1412 for (var i = 0; i < array.length; ++i)
1413 array[i] = array[i].replace(find, replacement);
1416 var replacePlaceholderInObject =
function(object, find, replacement)
1418 for (var key in
object)
1419 if (
object.hasOwnProperty(key))
1420 if (
object[key].constructor === Array)
1421 replacePlaceholderInArray(
object[key], find, replacement);
1423 replacePlaceholderInObject(
object[key], find, replacement);
1426 var cloneObject =
function(object)
1430 for (var key in
object)
1431 if (
object.hasOwnProperty(key))
1432 if (
object[key].constructor === Array)
1433 clone[key] =
object[key].slice(0);
1434 else if (typeof(
object[key]) ===
"object")
1435 clone[key] = cloneObject(
object[key]);
1437 clone[key] =
object[key];
1442 var makeThreePartSlicesFromObject =
function(object,
width, height, centerWidthHeight, rightWidth,
bottomHeight, isVertical)
1444 for (var key in
object)
1445 if (
object.hasOwnProperty(key))
1446 if (
object[key].constructor === Array)
1447 makeThreePartSlicesFromArray(
object[key],
width, height, centerWidthHeight, rightWidth,
bottomHeight, isVertical);
1449 makeThreePartSlicesFromObject(
object[key],
width, height, centerWidthHeight, rightWidth,
bottomHeight, isVertical);
1452 var makeThreePartSlicesFromArray =
function(array,
width, height, centerWidthHeight, rightWidth,
bottomHeight, isVertical)
1454 array[0] = [array[0], width, height];
1458 array[1] = [array[1], width, centerWidthHeight ? centerWidthHeight : 1.0];
1459 array[2] = [array[2], width, bottomHeight ? bottomHeight : height];
1463 array[1] = [array[1], centerWidthHeight ? centerWidthHeight : 1.0, height];
1464 array[2] = [array[2], rightWidth ? rightWidth : width, height];
1468 var makeNinePartSlicesFromObject =
function(object,
width, height, rightWidth,
bottomHeight, centerIsNil)
1470 for (var key in
object)
1471 if (
object.hasOwnProperty(key))
1472 if (
object[key].constructor === Array)
1473 makeNinePartSlicesFromArray(
object[key],
width, height, rightWidth,
bottomHeight, centerIsNil);
1475 makeNinePartSlicesFromObject(
object[key],
width, height, rightWidth,
bottomHeight, centerIsNil);
1478 var makeNinePartSlicesFromArray =
function(array,
width, height, rightWidth,
bottomHeight, centerIsNil)
1480 rightWidth = rightWidth ? rightWidth :
width;
1483 array[0] = [array[0], width, height];
1484 array[1] = [array[1], 1.0, height];
1485 array[2] = [array[2], rightWidth, height];
1486 array[3] = [array[3], width, 1.0];
1487 array[4] = centerIsNil ? nil : [array[4], 1.0, 1.0];
1488 array[5] = [array[5], rightWidth, 1.0];
1489 array[6] = [array[6], width, bottomHeight];
1490 array[7] = [array[7], 1.0, bottomHeight];
1491 array[8] = [array[8], rightWidth, bottomHeight];
1494 var makeImagesFromObject =
function(object, isVertical, imageFactory)
1496 for (var key in
object)
1497 if (
object.hasOwnProperty(key))
1498 if (
object[key].constructor === Array)
1499 object[key] = imageFromSlices(
object[key], isVertical, imageFactory);
1501 makeImagesFromObject(
object[key], isVertical, imageFactory);
function CPImageInBundle()
id initWithImageSlices:isVertical:(CPArray imageSlices, [isVertical] BOOL isVertical)
CPColor colorWithHexString:(string hex)
CPGraphicsContext currentContext()
An object representation of nil.
CPColor secondarySelectedControlColor()
CPColor colorWithPatternImage:(CPImage anImage)
function CGContextSetStrokeColor(aContext, aColor)
CPColor colorWithCalibratedRed:green:blue:alpha:(float red, [green] float green, [blue] float blue, [alpha] float alpha)
id initWithImageSlices:(CPArray imageSlices)
A mutable key-value pair collection.
CPColor alternateSelectedControlColor()
An immutable string (collection of characters).
function CPFeatureIsCompatible(aFeature)
CPColor colorWithCalibratedWhite:alpha:(float white, [alpha] float alpha)
CPColor colorWithRed:green:blue:alpha:(float red, [green] float green, [blue] float blue, [alpha] float alpha)
function CGContextSetFillColor(aContext, aColor)
CPColor colorWithHue:saturation:brightness:alpha:(float hue, [saturation] float saturation, [brightness] float brightness, [alpha] float alpha)
id initWithContentsOfFile:(CPString aFilename)
CPColorPatternIsHorizontal
CPColor checkerBoardColor()
CPColor colorWithWhite:alpha:(float white, [alpha] float alpha)
float saturationComponent()
Defines methods for use when archiving & restoring (enc/decoding).
CPColor selectedTextBackgroundColor()
CPDictionary themeAttributes()
float brightnessComponent()
CPString defaultThemeClass()