53 + (void)setDefaultHudTheme:(
CPTheme)aTheme
105 return [_attributes allKeys];
125 if ([aClass isKindOfClass:[
CPString class]])
138 if ([aClass respondsToSelector:
@selector(defaultThemeClass)])
142 else if ([aClass respondsToSelector:
@selector(themeClass)])
144 CPLog.warn(
@"%@ themeClass is deprecated in favor of defaultThemeClass",
CPStringFromClass(aClass));
153 return [_attributes objectForKey:className];
177 return [attributes allKeys];
179 return [CPArray array];
195 - (_CPThemeAttribute)attributeWithName:(
CPString)aName forClass:(
id)aClass
202 return [attributes objectForKey:aName];
218 - (id)valueForAttributeWithName:(
CPString)aName forClass:(
id)aClass
243 return [attribute valueForState:aState];
246 - (void)takeThemeFromObject:(
id)anObject
248 var attributes = [anObject _themeAttributeDictionary],
250 attributeNames = [attributes keyEnumerator],
251 objectThemeClass = [anObject themeClass];
253 while ((attributeName = [attributeNames nextObject]) !== nil)
254 [
self _recordAttribute:[attributes objectForKey:attributeName] forClass:objectThemeClass];
257 - (void)_recordAttribute:(_CPThemeAttribute)anAttribute forClass:(
CPString)aClass
259 if (![anAttribute hasValues])
262 var attributes = [_attributes objectForKey:aClass];
268 [_attributes setObject:attributes forKey:aClass];
271 var
name = [anAttribute name],
272 existingAttribute = [attributes objectForKey:name];
274 if (existingAttribute)
275 [attributes setObject:[existingAttribute attributeMergedWithAttribute:anAttribute] forKey:name];
277 [attributes setObject:anAttribute forKey:name];
293 _name = [aCoder decodeObjectForKey:CPThemeNameKey];
294 _attributes = [aCoder decodeObjectForKey:CPThemeAttributesKey];
304 [aCoder encodeObject:_name forKey:CPThemeNameKey];
305 [aCoder encodeObject:_attributes forKey:CPThemeAttributesKey];
316 var stateNameKeys = [];
317 this._stateNames = {};
319 for (key in stateNames)
321 if (!stateNames.hasOwnProperty(key))
324 if (key !==
'normal')
326 this._stateNames[key] =
true;
327 stateNameKeys.push(key);
331 if (stateNameKeys.length === 0)
333 stateNameKeys.push(
'normal');
334 this._stateNames['normal'] =
true;
337 stateNameKeys.sort();
338 this._stateNameString = stateNameKeys[0];
340 var stateNameLength = stateNameKeys.length;
342 for (var stateIndex = 1; stateIndex < stateNameLength; stateIndex++)
343 this._stateNameString = this._stateNameString +
"+" + stateNameKeys[stateIndex];
345 this._stateNameCount = stateNameLength;
350 return this._stateNameString;
353 ThemeState.prototype.hasThemeState =
function(aState)
355 if (!aState || !aState._stateNames)
359 for (var stateName in aState._stateNames)
361 if (!aState._stateNames.hasOwnProperty(stateName))
364 if (!this._stateNames[stateName])
370 ThemeState.prototype.isSubsetOf =
function(aState)
372 if (aState._stateNameCount <
this._stateNameCount)
375 for (var key in this._stateNames)
377 if (!this._stateNames.hasOwnProperty(key))
380 if (!aState._stateNames[key])
386 ThemeState.prototype.without =
function(aState)
388 if (!aState || aState === [
CPNull null])
396 result = firstTransform[aState._stateNameString];
404 for (var stateName in this._stateNames)
406 if (!this._stateNames.hasOwnProperty(stateName))
409 if (!aState._stateNames[stateName])
410 newStates[stateName] =
true;
418 firstTransform[aState._stateNameString] = result;
430 result = firstTransform[aState._stateNameString];
436 result = CPThemeState(
this, aState);
441 firstTransform[aState._stateNameString] = result;
446 var CPThemeStates = {},
450 ThemeState._cacheThemeState =
function(aState)
453 var themeState = CPThemeStates[String(aState)];
455 if (themeState === undefined)
458 CPThemeStates[String(themeState)] = themeState;
472 function CPThemeState()
474 if (arguments.length < 1)
475 throw "CPThemeState() must be called with at least one string argument";
479 if (arguments.length === 1 && typeof arguments[0] ===
'string')
481 themeState = CPThemeStates[arguments[0]];
483 if (themeState !== undefined)
489 for (var argIndex = 0; argIndex < arguments.length; argIndex++)
491 if (arguments[argIndex] === [
CPNull null] || !arguments[argIndex])
494 if (typeof arguments[argIndex] ===
'object')
496 for (var stateName in arguments[argIndex]._stateNames)
498 if (!arguments[argIndex]._stateNames.hasOwnProperty(stateName))
501 stateNames[stateName] =
true;
506 var allNames = arguments[argIndex].split(
'+');
508 for (var nameIndex = 0; nameIndex < allNames.length; nameIndex++)
509 stateNames[allNames[nameIndex]] =
true;
522 - (id)initForReadingWithData:(
CPData)data bundle:(
CPBundle)aBundle
524 self = [
super initForReadingWithData:data];
537 - (BOOL)awakenCustomResources
544 CPThemeStateNormal = CPThemeState(
"normal");
570 @implementation _CPThemeAttribute :
CPObject 577 _CPThemeAttribute _themeDefaultAttribute;
580 - (id)initWithName:(
CPString)aName defaultValue:(
id)aDefaultValue defaultAttribute:(_CPThemeAttribute)aDefaultAttribute
588 _defaultValue = aDefaultValue;
590 if (aDefaultAttribute)
591 _themeDefaultAttribute = aDefaultAttribute;
604 return _defaultValue;
609 return [_values count] > 0;
612 - (_CPThemeAttribute)attributeBySettingValue:(
id)aValue
614 var attribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue defaultAttribute:_themeDefaultAttribute];
616 if (aValue !== undefined && aValue !== nil)
622 - (_CPThemeAttribute)attributeBySettingValue:(
id)aValue forState:(
ThemeState)aState
624 var shouldRemoveValue = aValue === undefined || aValue === nil,
625 attribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue defaultAttribute:_themeDefaultAttribute],
630 values = [values copy];
632 if (shouldRemoveValue)
633 [values removeObjectForKey:String(aState)];
635 [values setObject:aValue forKey:String(aState)];
637 attribute._values = values;
639 else if (!shouldRemoveValue)
642 [values setObject:aValue forKey:String(aState)];
643 attribute._values = values;
651 return [
self valueForState:CPThemeStateNormal];
656 var stateName = String(aState),
657 value = _cache[stateName];
660 if (value !== undefined)
663 value = [_values objectForKey:stateName];
665 if (value === undefined || value === nil)
668 if (aState._stateNameCount > 1)
670 var states = [_values allKeys],
671 count = states ? states.length : 0,
672 largestThemeState = 0;
676 var stateObject = CPThemeState(states[count]);
678 if (stateObject.isSubsetOf(aState) && stateObject._stateNameCount > largestThemeState)
680 value = [_values objectForKey:states[count]];
681 largestThemeState = stateObject._stateNameCount;
687 if (value === undefined || value === nil)
688 value = [_values objectForKey:String(CPThemeStateNormal)];
691 if (value === undefined || value === nil)
692 value = [_themeDefaultAttribute valueForState:aState];
694 if (value === undefined || value === nil)
696 value = _defaultValue;
700 if (value === [
CPNull null])
704 _cache[stateName] = value;
709 - (_CPThemeAttribute)attributeBySettingParentAttribute:(_CPThemeAttribute)anAttribute
711 if (_themeDefaultAttribute === anAttribute)
714 var attribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue defaultAttribute:anAttribute];
716 attribute._values = [_values copy];
721 - (_CPThemeAttribute)attributeMergedWithAttribute:(_CPThemeAttribute)anAttribute
723 var mergedAttribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue defaultAttribute:_themeDefaultAttribute];
725 mergedAttribute._values = [_values copy];
727 if (anAttribute._values)
728 mergedAttribute._values ? [mergedAttribute._values addEntriesFromDictionary:anAttribute._values] : [anAttribute._values copy];
730 return mergedAttribute;
735 return [
super description] +
@" Name: " + _name +
@", defaultAttribute: " + _themeDefaultAttribute +
@", defaultValue: " + _defaultValue +
@", values: " + _values;
744 @implementation _CPThemeAttribute (CPCoding)
746 - (id)initWithCoder:(
CPCoder)aCoder
754 _name = [aCoder decodeObjectForKey:@"name"];
755 _defaultValue = [aCoder decodeObjectForKey:@"defaultValue"];
759 if ([aCoder containsValueForKey:
@"value"])
763 if ([aCoder containsValueForKey:
@"state"])
764 state = [aCoder decodeObjectForKey:@"state"];
768 [_values setObject:[aCoder decodeObjectForKey:"value"] forKey:state];
772 var encodedValues = [aCoder decodeObjectForKey:@"values"],
773 keys = [encodedValues allKeys],
778 var key = keys[count];
780 [_values setObject:[encodedValues objectForKey:key] forKey:key];
788 - (void)encodeWithCoder:(
CPCoder)aCoder
790 [aCoder encodeObject:_name forKey:@"name"];
791 [aCoder encodeObject:_defaultValue forKey:@"defaultValue"];
793 var keys = [_values allKeys],
794 count = keys ? keys.length : 0;
798 var onlyKey = keys[0];
800 if (onlyKey !== String(CPThemeStateNormal))
801 [aCoder encodeObject:onlyKey forKey:
@"state"];
803 [aCoder encodeObject:[_values objectForKey:onlyKey] forKey:@"value"];
807 var encodedValues = @{};
811 var key = keys[count];
813 [encodedValues setObject:[_values objectForKey:key] forKey:key];
816 [aCoder encodeObject:encodedValues forKey:@"values"];
824 var values = aThemeAttribute._values,
825 count = [values count],
826 key =
"$a" + [aThemeAttribute name];
830 var state = [values allKeys][0];
834 [aCoder encodeObject:[values objectForKey:state] forKey:key];
842 [aCoder encodeObject:aThemeAttribute forKey:key];
852 var key =
"$a" + attribute._name;
854 if ([aCoder containsValueForKey:key])
858 var decodedAttribute = [aCoder decodeObjectForKey:key];
862 if (!decodedAttribute || !decodedAttribute.isa || ![decodedAttribute isKindOfClass:[_CPThemeAttribute
class]])
863 attribute = [attribute attributeBySettingValue:decodedAttribute];
865 attribute = decodedAttribute;
CPTheme defaultHudTheme()
function CPStringFromClass(aClass)
CPThemeStateControlSizeMini
An object representation of nil.
ThemeState prototype CPThemeWithoutTransform
id valueForAttributeWithName:inState:forClass:(CPString aName, [inState] ThemeState aState, [forClass] id aClass)
CPThemeStateAutocompleting
A Cappuccino wrapper for any data type.
Unarchives objects created using CPKeyedArchiver.
A mutable key-value pair collection.
function ThemeState(stateNames)
var CPThemeDefaultHudTheme
CPThemeStateTableDataView
An immutable string (collection of characters).
function CPThemeAttributeDecode(aCoder, attribute)
_CPThemeAttribute attributeWithName:forClass:(CPString aName, [forClass] id aClass)
CPThemeStateSelectedDataView
function CPThemeAttributeEncode(aCoder, aThemeAttribute)
CPDictionary attributesForClass:(id aClass)
Defines methods for use when archiving & restoring (enc/decoding).
CPThemeStateFirstResponder
CPTheme themeNamed:(CPString aName)
var ParentAttributeForCoder
CPThemeStateControlSizeSmall
CPThemeStateControlSizeRegular
ThemeState prototype CPThemeAndTransform
function CPClassFromString(aClassName)