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]
104 #pragma mark Static methods 119 + (
CPColor)colorWithRed:(
float)red green:(
float)green blue:(
float)blue alpha:(
float)alpha
121 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))]];
139 + (
CPColor)colorWithCalibratedRed:(
float)red green:(
float)green blue:(
float)blue alpha:(
float)alpha
154 + (
CPColor)colorWithWhite:(
float)white alpha:(
float)alpha
156 return [[
CPColor alloc] _initWithRGBA:[white, white, white, alpha]];
170 + (
CPColor)colorWithCalibratedWhite:(
float)white alpha:(
float)alpha
188 + (
CPColor)colorWithHue:(
float)hue saturation:(
float)saturation brightness:(
float)brightness
198 + (
CPColor)colorWithCalibratedHue:(
float)hue saturation:(
float)saturation brightness:(
float)brightness alpha:(
float)alpha
217 + (
CPColor)colorWithHue:(
float)hue saturation:(
float)saturation brightness:(
float)brightness alpha:(
float)alpha
220 hue = MAX(MIN(hue, 1.0), 0.0);
221 saturation = MAX(MIN(saturation, 1.0), 0.0);
222 brightness = MAX(MIN(brightness, 1.0), 0.0);
224 if (saturation === 0.0)
227 var f = (hue * 360) % 60,
228 p = (brightness * (1 - saturation)),
229 q = (brightness * (60 - saturation * f)) / 60,
230 t = (brightness * (60 - saturation * (60 - f))) / 60,
233 switch (FLOOR(hue * 6))
263 var rgba = hexToRGB(hex);
264 return rgba ? [[
CPColor alloc] _initWithRGBA: rgba] : null;
271 + (
CPColor)colorWithSRGBRed:(
float)red green:(
float)green blue:(
float)blue alpha:(
float)alpha
283 if (!cachedBlackColor)
284 cachedBlackColor = [[
CPColor alloc] _initWithRGBA:[0.0, 0.0, 0.0, 1.0]];
286 return cachedBlackColor;
294 if (!cachedBlueColor)
295 cachedBlueColor = [[
CPColor alloc] _initWithRGBA:[0.0, 0.0, 1.0, 1.0]];
297 return cachedBlueColor;
305 if (!cachedDarkGrayColor)
308 return cachedDarkGrayColor;
316 if (!cachedGrayColor)
319 return cachedGrayColor;
327 if (!cachedGreenColor)
328 cachedGreenColor = [[
CPColor alloc] _initWithRGBA:[0.0, 1.0, 0.0, 1.0]];
330 return cachedGreenColor;
338 if (!cachedLightGrayColor)
341 return cachedLightGrayColor;
350 cachedRedColor = [[
CPColor alloc] _initWithRGBA:[1.0, 0.0, 0.0, 1.0]];
352 return cachedRedColor;
360 if (!cachedWhiteColor)
361 cachedWhiteColor = [[
CPColor alloc] _initWithRGBA:[1.0, 1.0, 1.0, 1.0]];
363 return cachedWhiteColor;
371 if (!cachedYellowColor)
372 cachedYellowColor = [[
CPColor alloc] _initWithRGBA:[1.0, 1.0, 0.0, 1.0]];
374 return cachedYellowColor;
382 if (!cachedBrownColor)
383 cachedBrownColor = [[
CPColor alloc] _initWithRGBA:[0.6, 0.4, 0.2, 1.0]];
385 return cachedBrownColor;
393 if (!cachedCyanColor)
394 cachedCyanColor = [[
CPColor alloc] _initWithRGBA:[0.0, 1.0, 1.0, 1.0]];
396 return cachedCyanColor;
404 if (!cachedMagentaColor)
405 cachedMagentaColor = [[
CPColor alloc] _initWithRGBA:[1.0, 0.0, 1.0, 1.0]];
407 return cachedMagentaColor;
415 if (!cachedOrangeColor)
416 cachedOrangeColor = [[
CPColor alloc] _initWithRGBA:[1.0, 0.5, 0.0, 1.0]];
418 return cachedOrangeColor;
426 if (!cachedPurpleColor)
427 cachedPurpleColor = [[
CPColor alloc] _initWithRGBA:[0.5, 0.0, 0.5, 1.0]];
429 return cachedPurpleColor;
438 if (!cachedShadowColor)
439 cachedShadowColor = [[
CPColor alloc] _initWithRGBA:[0.0, 0.0, 0.0, 1.0 / 3.0]];
441 return cachedShadowColor;
450 if (!cachedClearColor)
453 return cachedClearColor;
458 if (!cachedThemeColor)
461 return cachedThemeColor;
466 return [[
self _cachedThemeColor] valueForThemeAttribute:@"alternate-selected-control-color"];
471 return [[
self _cachedThemeColor] valueForThemeAttribute:@"secondary-selected-control-color"];
481 return [[
CPColor alloc] _initWithPatternImage:anImage];
492 return [[
CPColor alloc] _initWithCSSString: aString];
496 - (id)_initWithCSSString:(
CPString)aString
503 var startingIndex = aString.indexOf(
"("),
504 parts = aString.substring(startingIndex + 1).split(
',');
507 parseInt(parts[0], 10) / 255.0,
508 parseInt(parts[1], 10) / 255.0,
509 parseInt(parts[2], 10) / 255.0,
510 parts[3] ? parseFloat(parts[3], 10) : 1.0
515 [
self _initCSSStringFromComponents];
518 _themeState = CPThemeStateNormal;
519 [
self _loadThemeAttributes];
533 [
self _initCSSStringFromComponents];
536 _themeState = CPThemeStateNormal;
537 [
self _loadThemeAttributes];
543 - (void)_initCSSStringFromComponents
547 _cssString = (hasAlpha ?
"rgba(" :
"rgb(") +
548 parseInt(_components[0] * 255.0) +
", " +
549 parseInt(_components[1] * 255.0) +
", " +
550 parseInt(_components[2] * 255.0) +
551 (hasAlpha ? (
", " + _components[3]) :
"") +
")";
555 - (id)_initWithPatternImage:(
CPImage)anImage
561 _patternImage = anImage;
562 _cssString =
"url(\"" + [_patternImage filename] +
"\")";
563 _components = [0.0, 0.0, 0.0, 1.0];
566 _themeState = CPThemeStateNormal;
567 [
self _loadThemeAttributes];
578 return _patternImage;
586 return _components[3];
594 return _components[2];
602 return _components[1];
610 return _components[0];
636 - (
CPColor)colorWithAlphaComponent:(
float)anAlphaComponent
640 components[components.length - 1] = anAlphaComponent;
642 return [[[
self class] alloc] _initWithRGBA:components];
648 - (
CPColor)colorUsingColorSpaceName:(
id)aColorSpaceName
668 var red = ROUND(_components[_redComponent] * 255.0),
669 green = ROUND(_components[_greenComponent] * 255.0),
670 blue = ROUND(_components[_blueComponent] * 255.0);
672 var max = MAX(red, green, blue),
673 min = MIN(red, green, blue),
676 var brightness = max / 255.0,
677 saturation = (max != 0) ? delta / max : 0;
687 var rr = (max - red) / delta,
688 gr = (max - green) / delta,
689 br = (max - blue) / delta;
693 else if (green == max)
764 if (![aColor isKindOfClass:
CPColor])
798 for (var i = 0; i < slices.length; ++i)
800 var imgDescription = [slices[i] description] ||
"nil";
802 description += imgDescription.replace(/^/mg,
" ") +
",\n";
862 var CPColorComponentsKey =
@"CPColorComponentsKey",
863 CPColorPatternImageKey =
@"CPColorPatternImageKey";
874 if ([aCoder containsValueForKey:CPColorPatternImageKey])
875 self = [
self _initWithPatternImage:[aCoder decodeObjectForKey:CPColorPatternImageKey]];
877 self = [
self _initWithRGBA:[aCoder decodeObjectForKey:CPColorComponentsKey]];
879 [
self _decodeThemeObjectsWithCoder:aCoder];
891 [aCoder encodeObject:_patternImage forKey:CPColorPatternImageKey];
893 [aCoder encodeObject:_components forKey:CPColorComponentsKey];
895 [
self _encodeThemeObjectsWithCoder:aCoder];
902 var hexCharacters =
"0123456789ABCDEF";
908 var hexToRGB =
function(hex)
911 hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
916 hex = hex.toUpperCase();
918 for (var i = 0; i < hex.length; i++)
919 if (hexCharacters.indexOf(hex.charAt(i)) == -1)
922 var red = (hexCharacters.indexOf(hex.charAt(0)) * 16 + hexCharacters.indexOf(hex.charAt(1))) / 255.0,
923 green = (hexCharacters.indexOf(hex.charAt(2)) * 16 + hexCharacters.indexOf(hex.charAt(3))) / 255.0,
924 blue = (hexCharacters.indexOf(hex.charAt(4)) * 16 + hexCharacters.indexOf(hex.charAt(5))) / 255.0;
926 return [red, green, blue, 1.0];
929 var rgbToHex =
function(r,g,b)
931 return byteToHex(r) + byteToHex(g) + byteToHex(b);
934 var byteToHex =
function(n)
939 n = FLOOR(MIN(255, MAX(0, 256 * n)));
941 return hexCharacters.charAt((n - n % 16) / 16) +
942 hexCharacters.charAt(n % 16);
1164 function CPColorWithImages()
1170 args = Array.prototype.slice.apply(arguments);
1172 if (typeof(args[args.length - 1]) ===
"function")
1173 imageFactory = args.pop();
1175 switch (args.length)
1178 return imageFromSlices(args[0], isVertical, imageFactory);
1182 if (typeof(args[0]) ===
"string")
1183 return patternColorsFromPattern.call(
this, args[0], args[1], imageFactory);
1185 return imageFromSlices(args[0], args[1], imageFactory);
1192 throw(
"ERROR: Invalid argument count: " + args.length);
1196 var imageFromSlices =
function(slices, isVertical, imageFactory)
1198 var imageSlices = [];
1200 for (var i = 0; i < slices.length; ++i)
1202 var slice = slices[i];
1204 imageSlices.push(slice ? imageFactory(slice[0], slice[1], slice[2], slice[3]) : nil);
1207 switch (slices.length)
1216 throw(
"ERROR: Invalid number of image slices: " + slices.length);
1220 var patternColorsFromPattern =
function(pattern, attributes, imageFactory)
1222 if (pattern.match(/^.*\{[^}]+\}/))
1224 var
width = attributes["width"],
1225 height = attributes["height"],
1226 separator = attributes["separator"] ||
"-",
1227 orientation = attributes["orientation"],
1235 if (pattern.indexOf(
"{position}") < 0)
1236 throw(
"ERROR: Pattern strings must have a {position} placeholder (\"" + pattern +
"\")");
1238 if (orientation === undefined)
1242 if (attributes[
"centerIsNil"] !== undefined)
1243 centerIsNil = attributes["centerIsNil"];
1248 isVertical = orientation === PatternIsVertical;
1252 if (attributes[
"centerHeight"])
1253 centerWidthHeight = attributes["centerHeight"];
1257 if (attributes[
"centerWidth"])
1258 centerWidthHeight = attributes["centerWidth"];
1262 if (attributes[
"rightWidth"])
1263 rightWidth = attributes["rightWidth"];
1265 if (attributes[
"bottomHeight"])
1266 bottomHeight = attributes["bottomHeight"];
1268 var positions = attributes["positions"] ||
"@",
1274 if (positions ===
"@")
1277 positions = ["top", "center", "bottom"];
1279 positions = ["left", "center", "right"];
1281 else if (positions ===
"#")
1282 positions = ["0", "1", "2"];
1284 throw(
"ERROR: Invalid positions: " + positions)
1288 if (positions ===
"@" || positions ===
"abbrev")
1289 positions = ["top-left", "top", "top-right", "left", "center", "right", "bottom-left", "bottom", "bottom-right"];
1290 else if (positions ===
"full")
1291 positions = ["top-left", "top-center", "top-right", "center-left", "center-center", "center-right", "bottom-left", "bottom-center", "bottom-right"];
1292 else if (positions ===
"#")
1293 positions = ["0", "1", "2", "3", "4", "5", "6", "7", "8"];
1295 throw(
"ERROR: Invalid positions: " + positions)
1299 if (pattern.indexOf(
"{state}") >= 0)
1301 states = attributes["states"];
1304 throw(
"ERROR: {state} placeholder in the pattern (\"" + pattern +
"\") but no states item in the attributes");
1308 if (pattern.indexOf(
"{style}") >= 0)
1310 styles = attributes["styles"];
1313 throw(
"ERROR: {style} placeholder in the pattern (\"" + pattern +
"\") but no styles item in the attributes");
1317 var placeholder =
"{position}",
1318 pos = pattern.indexOf(placeholder),
1321 for (i = 0; i < positions.length; ++i)
1322 positions[i] = pattern.replace(placeholder, pos === 0 ? positions[i] + separator : separator + positions[i]);
1324 var slices = positions,
1331 placeholder =
"{state}";
1332 pos = pattern.indexOf(placeholder);
1335 for (i = 0; i < states.length; ++i)
1337 var state = states[i];
1339 sep = state ? separator :
"";
1341 object[key] = slices.slice(0);
1342 replacePlaceholderInArray(
object[key], placeholder, pos === 0 ? state + sep : sep + state);
1348 placeholder =
"{style}";
1349 pos = pattern.indexOf(placeholder);
1351 var styleObject = {};
1353 for (i = 0; i < styles.length; ++i)
1355 var style = styles[i];
1357 sep = style ? separator :
"";
1361 styleObject[key] = cloneObject(
object);
1362 replacePlaceholderInObject(styleObject[key], placeholder, pos === 0 ? style + sep : sep + style);
1366 styleObject[key] = slices.slice(0);
1367 replacePlaceholderInArray(styleObject[key], placeholder, pos === 0 ? style + sep : sep + style);
1371 object = styleObject;
1374 if (styles || states)
1377 makeThreePartSlicesFromObject(
object, width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical);
1379 makeNinePartSlicesFromObject(
object, width, height, rightWidth, bottomHeight, centerIsNil);
1381 makeImagesFromObject(
object, isVertical, imageFactory);
1387 makeThreePartSlicesFromArray(
object, width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical);
1389 makeNinePartSlicesFromArray(
object, width, height, rightWidth, bottomHeight, centerIsNil);
1391 return imageFromSlices(
object, isVertical, imageFactory);
1395 throw(
"ERROR: No placeholders in slice pattern (\"" + pattern +
"\")");
1398 var replacePlaceholderInArray =
function(array, find, replacement)
1400 for (var i = 0; i < array.length; ++i)
1401 array[i] = array[i].replace(find, replacement);
1404 var replacePlaceholderInObject =
function(object, find, replacement)
1406 for (var key in
object)
1407 if (
object.hasOwnProperty(key))
1408 if (
object[key].constructor === Array)
1409 replacePlaceholderInArray(
object[key], find, replacement);
1411 replacePlaceholderInObject(
object[key], find, replacement);
1414 var cloneObject =
function(object)
1418 for (var key in
object)
1419 if (
object.hasOwnProperty(key))
1420 if (
object[key].constructor === Array)
1421 clone[key] =
object[key].slice(0);
1422 else if (typeof(
object[key]) ===
"object")
1423 clone[key] = cloneObject(
object[key]);
1425 clone[key] =
object[key];
1430 var makeThreePartSlicesFromObject =
function(object,
width, height, centerWidthHeight, rightWidth,
bottomHeight, isVertical)
1432 for (var key in
object)
1433 if (
object.hasOwnProperty(key))
1434 if (
object[key].constructor === Array)
1435 makeThreePartSlicesFromArray(
object[key],
width, height, centerWidthHeight, rightWidth,
bottomHeight, isVertical);
1437 makeThreePartSlicesFromObject(
object[key],
width, height, centerWidthHeight, rightWidth,
bottomHeight, isVertical);
1440 var makeThreePartSlicesFromArray =
function(array,
width, height, centerWidthHeight, rightWidth,
bottomHeight, isVertical)
1442 array[0] = [array[0], width, height];
1446 array[1] = [array[1], width, centerWidthHeight ? centerWidthHeight : 1.0];
1447 array[2] = [array[2], width, bottomHeight ? bottomHeight : height];
1451 array[1] = [array[1], centerWidthHeight ? centerWidthHeight : 1.0, height];
1452 array[2] = [array[2], rightWidth ? rightWidth : width, height];
1456 var makeNinePartSlicesFromObject =
function(object,
width, height, rightWidth,
bottomHeight, centerIsNil)
1458 for (var key in
object)
1459 if (
object.hasOwnProperty(key))
1460 if (
object[key].constructor === Array)
1461 makeNinePartSlicesFromArray(
object[key],
width, height, rightWidth,
bottomHeight, centerIsNil);
1463 makeNinePartSlicesFromObject(
object[key],
width, height, rightWidth,
bottomHeight, centerIsNil);
1466 var makeNinePartSlicesFromArray =
function(array,
width, height, rightWidth,
bottomHeight, centerIsNil)
1468 rightWidth = rightWidth ? rightWidth :
width;
1471 array[0] = [array[0], width, height];
1472 array[1] = [array[1], 1.0, height];
1473 array[2] = [array[2], rightWidth, height];
1474 array[3] = [array[3], width, 1.0];
1475 array[4] = centerIsNil ? nil : [array[4], 1.0, 1.0];
1476 array[5] = [array[5], rightWidth, 1.0];
1477 array[6] = [array[6], width, bottomHeight];
1478 array[7] = [array[7], 1.0, bottomHeight];
1479 array[8] = [array[8], rightWidth, bottomHeight];
1482 var makeImagesFromObject =
function(object, isVertical, imageFactory)
1484 for (var key in
object)
1485 if (
object.hasOwnProperty(key))
1486 if (
object[key].constructor === Array)
1487 object[key] = imageFromSlices(
object[key], isVertical, imageFactory);
1489 makeImagesFromObject(
object[key], isVertical, imageFactory);
function CPImageInBundle()
id initWithImageSlices:isVertical:(CPArray imageSlices, [isVertical] BOOL isVertical)
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).
CPDictionary themeAttributes()
float brightnessComponent()
CPString defaultThemeClass()