Fixed: Cache ThemeAttribute

Conflicts:
	AppKit/CPTheme.j
This commit is contained in:
Martin Carlberg
2015-10-23 10:18:03 +02:00
parent 3a91f43bbb
commit fc411c5c1c
8 changed files with 280 additions and 85 deletions
+6 -6
View File
@@ -272,15 +272,15 @@
currentButtonOffset += width - 1;
}
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateNormal, CPThemeStateBordered]];
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateHighlighted, CPThemeStateBordered, ]];
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateDisabled, CPThemeStateBordered]];
[button setValue:normalColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateNormal, CPThemeStateBordered]];
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateHighlighted, CPThemeStateBordered, ]];
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateDisabled, CPThemeStateBordered]];
[button setValue:textColor forThemeAttribute:@"text-color" inState:CPThemeStateBordered];
// FIXME shouldn't need this
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateNormal, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateHighlighted, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateDisabled, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
[button setValue:normalColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateNormal, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateHighlighted, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateDisabled, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
[self addSubview:button];
}
+16 -16
View File
@@ -1114,30 +1114,30 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:CPThemeStateDisabled] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateDisabled];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:CPThemeStateDisabled] forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateDisabled];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"font" inState:[CPThemeStateDisabled, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:[CPThemeStateDisabled, CPThemeStateSelected]]forThemeAttribute:@"text-color" inState:[CPThemeStateDisabled, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inStates:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"font" inStates:[CPThemeStateDisabled, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inStates:[CPThemeStateDisabled, CPThemeStateSelected]]forThemeAttribute:@"text-color" inStates:[CPThemeStateDisabled, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inStates:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inStates:[CPThemeStateDisabled, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inStates:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inStates:[CPThemeStateDisabled, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:CPThemeStateHighlighted] forThemeAttribute:@"font" inState:CPThemeStateHighlighted];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:CPThemeStateHighlighted] forThemeAttribute:@"text-color" inState:CPThemeStateHighlighted];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:CPThemeStateHighlighted] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateHighlighted];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:CPThemeStateHighlighted] forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateHighlighted];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"font" inState:[CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-color" inState:[CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inState:[CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inState:[CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"font" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-color" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"font" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"font" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"font" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"font" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-shadow-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-shadow-offset" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]];
[self addSubview:_textField];
+6 -6
View File
@@ -188,12 +188,12 @@
[_buttonUp setFrame:upFrame];
[_buttonDown setFrame:downFrame];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inState:[CPThemeStateBordered, CPThemeStateDisabled]];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inState:[CPThemeStateBordered, CPThemeStateHighlighted]];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inState:[CPThemeStateBordered, CPThemeStateDisabled]];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inState:[CPThemeStateBordered, CPThemeStateHighlighted]];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateDisabled]];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateHighlighted]];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateDisabled]];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateHighlighted]];
}
- (void)_sizeToFit
+146 -28
View File
@@ -557,6 +557,26 @@ CPThemeStateControlSizeRegular = CPThemeState("controlSizeRegular");
CPThemeStateControlSizeSmall = CPThemeState("controlSizeSmall");
CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
CPThemeStateNormalString = String(CPThemeStateNormal);
CPThemeAttributeCache = {}; // CPThemeAttributeCache[_name][themeDefaultAttribute._UID][_defaultValue] -> CPThemeAttribute
var stringify = JSON.stringify;
function CPStringthemeAttributeCacheString(array)
{
var returnString = "[";
for (var i = 0, size = array.length; i < size; i++)
{
var aValue = array[i];
returnString += aValue == null ? aValue : aValue._UID || (aValue.isa === _CPJavaScriptArray ? CPStringthemeAttributeCacheString(aValue) : stringify(aValue))
}
return returnString + "]";
}
@implementation _CPThemeAttribute : CPObject
{
CPString _name;
@@ -564,10 +584,26 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
CPDictionary _values @accessors(readonly, getter=values);
JSObject _cache;
JSObject _setValueTransformCache;
JSObject _removeValueTransformCache;
_CPThemeAttribute _themeDefaultAttribute;
}
- (id)initWithName:(CPString)aName defaultValue:(id)aDefaultValue
+ (id)attributeWithName:(CPString)aName defaultValue:(id)aDefaultValue defaultAttribute:(_CPThemeAttribute)aDefaultAttribute
{
var defaultAttributeCache = CPThemeAttributeCache[aName] || (CPThemeAttributeCache[aName] = {}),
defaultAttributeUID = aDefaultAttribute ? aDefaultAttribute._UID : nil,
defaultValueCache = defaultAttributeCache[defaultAttributeUID] || (defaultAttributeCache[defaultAttributeUID] = {}),
aDefaultValueString = aDefaultValue == null ? aDefaultValue : aDefaultValue._UID || (aDefaultValue.isa === _CPJavaScriptArray ? CPStringthemeAttributeCacheString(aDefaultValue) : JSON.stringify(aDefaultValue)),
attribute = defaultValueCache[aDefaultValueString];
if (!attribute)
attribute = defaultValueCache[aDefaultValueString] = [[_CPThemeAttribute alloc] initWithName:aName defaultValue:aDefaultValue defaultAttribute:aDefaultAttribute];
return attribute;
}
- (id)initWithName:(CPString)aName defaultValue:(id)aDefaultValue defaultAttribute:(_CPThemeAttribute)aDefaultAttribute
{
self = [super init];
@@ -577,6 +613,8 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
_name = aName;
_defaultValue = aDefaultValue;
_values = @{};
if (aDefaultAttribute)
_themeDefaultAttribute = aDefaultAttribute;
}
return self;
@@ -597,7 +635,64 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
return [_values count] > 0;
}
- (void)setValue:(id)aValue
- (_CPThemeAttribute)attributeBySettingValue:(id)aValue
{
var transformStateDict = self._setValueTransformCacheN || (self._setValueTransformCacheN = {}),
transformValueDict = transformStateDict[CPThemeStateNormalString] || (transformStateDict[CPThemeStateNormalString] = {}),
aValueString = aValue == null ? aValue : aValue._UID || (aValue.isa === _CPJavaScriptArray ? CPStringthemeAttributeCacheString(aValue) : stringify(aValue)),
attribute = transformValueDict[aValueString];
if (!attribute)
{
attribute = transformValueDict[aValueString] = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue defaultAttribute:_themeDefaultAttribute];
if (aValue !== undefined && aValue !== nil)
attribute._values = @{ CPThemeStateNormalString: aValue };
}
return attribute;
}
- (_CPThemeAttribute)attributeBySettingValue:(id)aValue forState:(ThemeState)aState
{
var shouldRemoveValue = aValue === undefined || aValue === nil,
transformStateDict = shouldRemoveValue ? self._removeValueTransformCache || (self._removeValueTransformCache = {}) : self._setValueTransformCache || (self._setValueTransformCache = {}),
stateString = String(aState),
transformValueDict = transformStateDict[stateString] || (transformStateDict[stateString] = {}),
aValueString = aValue == null ? aValue : aValue._UID || (aValue.isa === _CPJavaScriptArray ? CPStringthemeAttributeCacheString(aValue) : stringify(aValue)),
attribute = transformValueDict[aValueString];
if (!attribute)
{
attribute = transformValueDict[aValueString] = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue defaultAttribute:_themeDefaultAttribute];
var values = [_values copy];
// var values = _values;
/* if (values != null)
{
values = [values copy];
*/ if (shouldRemoveValue)
[values removeObjectForKey:stateString];
else
[values setObject:aValue forKey:stateString];
attribute._values = values;
/* }
else
{
if (!shouldRemoveValue)
{
values = [[CPDictionary alloc] init];
[values setObject:aValue forKey:stateString];
// values = @{stateString: aValue};
attribute._values = values;
}
}
*/ }
return attribute;
}
/*- (void)setValue:(id)aValue
{
_cache = {};
@@ -615,7 +710,7 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
[_values removeObjectForKey:String(aState)];
else
[_values setObject:aValue forKey:String(aState)];
}
}*/
- (id)value
{
@@ -639,7 +734,7 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
if (aState._stateNameCount > 1)
{
var states = [_values allKeys],
count = states.length,
count = states ? states.length : 0,
largestThemeState = 0;
while (count--)
@@ -674,52 +769,76 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
_cache[stateName] = value;
return value;
/* var now = [CPDate new];
var elapsedSeconds = [now timeIntervalSinceReferenceDate] - [start timeIntervalSinceReferenceDate];
CPLog.trace(@"valueForState:" + aState + " in " + elapsedSeconds + @" seconds");
*/ return value;
}
- (void)setParentAttribute:(_CPThemeAttribute)anAttribute
/*- (void)setParentAttribute:(_CPThemeAttribute)anAttribute
{
if (_themeDefaultAttribute === anAttribute)
return;
_cache = { };
_themeDefaultAttribute = anAttribute;
}
}*/
- (_CPThemeAttribute)attributeMergedWithAttribute:(_CPThemeAttribute)anAttribute
{
var mergedAttribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue];
var mergedAttribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue defaultAttribute:_themeDefaultAttribute];
mergedAttribute._values = [_values copy];
[mergedAttribute._values addEntriesFromDictionary:anAttribute._values];
if (anAttribute._values)
mergedAttribute._values ? [mergedAttribute._values addEntriesFromDictionary:anAttribute._values] : [anAttribute._values copy];
return mergedAttribute;
}
@end
// This is used to pass 'parrentAttribute' to the coder
var ParentAttributeForCoder = nil;
@implementation _CPThemeAttribute (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
var aName = [aCoder decodeObjectForKey:@"name"],
aDefaultValue = [aCoder decodeObjectForKey:@"defaultValue"],
defaultAttributeCache = CPThemeAttributeCache[aName] || (CPThemeAttributeCache[aName] = {}),
defaultAttributeUID = ParentAttributeForCoder ? ParentAttributeForCoder._UID : nil, // Uses global variable as
defaultValueCache = defaultAttributeCache[defaultAttributeUID] || (defaultAttributeCache[defaultAttributeUID] = {}),
aDefaultValueString = aDefaultValue == null ? aDefaultValue : aDefaultValue._UID || (aDefaultValue.isa === _CPJavaScriptArray ? CPStringthemeAttributeCacheString(aDefaultValue) : stringify(aDefaultValue)),
attribute = defaultValueCache[aDefaultValueString];
if (attribute)
self = attribute;
else
self = [super init];
if (self)
{
_cache = {};
defaultValueCache[aDefaultValueString] = self;
_name = [aCoder decodeObjectForKey:@"name"];
_defaultValue = [aCoder decodeObjectForKey:@"defaultValue"];
_cache = {};
_name = aName;
_values = @{};
_defaultValue = aDefaultValue;
if ([aCoder containsValueForKey:@"value"])
{
var state = String(CPThemeStateNormal);
var state;
if ([aCoder containsValueForKey:@"state"])
state = [aCoder decodeObjectForKey:@"state"];
else
state = CPThemeStateNormalString;
[_values setObject:[aCoder decodeObjectForKey:"value"] forKey:state];
self = [self attributeBySettingValue:[aCoder decodeObjectForKey:"value"] forState:state];
}
else
{
@@ -731,7 +850,7 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
{
var key = keys[count];
[_values setObject:[encodedValues objectForKey:key] forKey:key];
self = [self attributeBySettingValue:[encodedValues objectForKey:key] forState:key];
}
}
}
@@ -745,7 +864,7 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
[aCoder encodeObject:_defaultValue forKey:@"defaultValue"];
var keys = [_values allKeys],
count = keys.length;
count = keys ? keys.length : 0;
if (count === 1)
{
@@ -783,7 +902,7 @@ function CPThemeAttributeEncode(aCoder, aThemeAttribute)
{
var state = [values allKeys][0];
if (state === String(CPThemeStateNormal))
if (state === CPThemeStateNormalString)
{
[aCoder encodeObject:[values objectForKey:state] forKey:key];
@@ -803,28 +922,27 @@ function CPThemeAttributeEncode(aCoder, aThemeAttribute)
function CPThemeAttributeDecode(aCoder, anAttributeName, aDefaultValue, aTheme, aClass)
{
var key = "$a" + anAttributeName;
var key = "$a" + anAttributeName,
parentAttribute = (aTheme && aClass) ? [aTheme attributeWithName:anAttributeName forClass:aClass] : nil;
if (![aCoder containsValueForKey:key])
var attribute = [[_CPThemeAttribute alloc] initWithName:anAttributeName defaultValue:aDefaultValue];
var attribute = [_CPThemeAttribute attributeWithName:anAttributeName defaultValue:aDefaultValue defaultAttribute:parentAttribute];
else
{
ParentAttributeForCoder = parentAttribute;
var attribute = [aCoder decodeObjectForKey:key];
ParentAttributeForCoder = nil;
if (!attribute || !attribute.isa || ![attribute isKindOfClass:[_CPThemeAttribute class]])
{
var themeAttribute = [[_CPThemeAttribute alloc] initWithName:anAttributeName defaultValue:aDefaultValue];
var themeAttribute = [_CPThemeAttribute attributeWithName:anAttributeName defaultValue:aDefaultValue defaultAttribute:parentAttribute];
[themeAttribute setValue:attribute];
attribute = themeAttribute;
attribute = [themeAttribute attributeBySettingValue:attribute];
}
}
if (aTheme && aClass)
[attribute setParentAttribute:[aTheme attributeWithName:anAttributeName forClass:aClass]];
return attribute;
}
+13 -2
View File
@@ -3386,8 +3386,19 @@ setBoundsOrigin:
[self unsetThemeState:CPThemeStateAppearanceVibrantDark];
}
[_subviews makeObjectsPerformSelector:@selector(_recomputeAppearance)];
}
// var start = [CPDate new];
for (var i = 0, size = [_subviews count]; i < size; i++)
{
[[_subviews objectAtIndex:i] _recomputeAppearance];
}
// [_subviews makeObjectsPerformSelector:@selector(_recomputeAppearance)];
/* var now = [CPDate new];
var elapsedSeconds = [now timeIntervalSinceReferenceDate] - [start timeIntervalSinceReferenceDate];
CPLog.trace(@"_recomputeAppearance " + [_subviews count] + " subviews in " + elapsedSeconds + @" seconds");
*/}
@end
+14 -6
View File
@@ -231,10 +231,14 @@ var ItemSizes = { },
value = attributeValueState[1],
state = attributeValueState[2];
if (state)
[aView setValue:value forThemeAttribute:attribute inState:state];
else
if (state) {
if (state.isa && [state isKindOfClass:CPArray])
[aView setValue:value forThemeAttribute:attribute inStates:state];
else
[aView setValue:value forThemeAttribute:attribute inState:state];
} else {
[aView setValue:value forThemeAttribute:attribute];
}
}
}
@@ -303,10 +307,14 @@ var ItemSizes = { },
}
}
if (state)
[aView setValue:value forThemeAttribute:attribute inState:state];
else
if (state) {
if (state.isa && [state isKindOfClass:CPArray])
[aView setValue:value forThemeAttribute:attribute inStates:state];
else
[aView setValue:value forThemeAttribute:attribute inState:state];
} else {
[aView setValue:value forThemeAttribute:attribute];
}
}
}
}
+2 -2
View File
@@ -171,9 +171,9 @@ var _CPAutocompleteMenuMaximumHeight = 307;
var dataView = [tableColumn dataView],
fontNormal = [dataView valueForThemeAttribute:@"font" inState:CPThemeStateTableDataView],
fontSelected = [dataView valueForThemeAttribute:@"font" inState:[CPThemeStateTableDataView, CPThemeStateSelectedDataView]],
fontSelected = [dataView valueForThemeAttribute:@"font" inStates:[CPThemeStateTableDataView, CPThemeStateSelectedDataView]],
contentInsetNormal = [dataView valueForThemeAttribute:@"content-inset" inState:CPThemeStateTableDataView],
contentInsetSelected = [dataView valueForThemeAttribute:@"content-inset" inState:[CPThemeStateTableDataView, CPThemeStateSelectedDataView]];
contentInsetSelected = [dataView valueForThemeAttribute:@"content-inset" inStates:[CPThemeStateTableDataView, CPThemeStateSelectedDataView]];
var mergedString = contentArray.join("\n");
+77 -19
View File
@@ -244,9 +244,7 @@ var CPViewThemeClassKey = @"CPViewThemeClassKey",
while (count--)
{
var attributeName = attributes[count--],
attribute = [[_CPThemeAttribute alloc] initWithName:attributeName defaultValue:attributes[count]];
[attribute setParentAttribute:[theme attributeWithName:attributeName forClass:themeClass]];
attribute = [_CPThemeAttribute attributeWithName:attributeName defaultValue:attributes[count] defaultAttribute:[theme attributeWithName:attributeName forClass:themeClass]];
_themeAttributes[attributeName] = attribute;
}
@@ -303,48 +301,104 @@ var CPViewThemeClassKey = @"CPViewThemeClassKey",
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(ThemeState)aState
{
if (aState.isa && [aState isKindOfClass:CPArray])
aState = CPThemeState.apply(null, aState);
#if DEBUG
if (aState.isa && [aState isKindOfClass:CPArray])
[CPException raise:CPInvalidArgumentException reason:self + @": aState can't be an array. Please use 'setValue:forThemeAttribute:inStates:' instead: " + aState];
#endif
if (!_themeAttributes || !_themeAttributes[aName])
var themeAttr = _themeAttributes && _themeAttributes[aName];
if (!themeAttr)
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
[_themeAttributes[aName] setValue:aValue forState:aState];
var a = [themeAttr attributeBySettingValue:aValue forState:aState];
//print("setValue:forThemeAttribute:inState:" + aState + ": " + aName + ": " + aValue + "oldAttribute: " + [themeAttr._values description]);
_themeAttributes[aName] = a;
}
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inStates:(CPArray)states
{
var i = [states count],
aState = [states objectAtIndex:--i];
while (i > 0)
{
aState = aState.and([states objectAtIndex:--i]);
}
var themeAttr = _themeAttributes && _themeAttributes[aName];
if (!themeAttr)
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
var a = [themeAttr attributeBySettingValue:aValue forState:aState];
//print("setValue:forThemeAttribute:inStates:" + aState + ": " + aName + ": " + aValue + "oldAttribute: " + [themeAttr._values description]);
_themeAttributes[aName] = a;
}
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName
{
if (!_themeAttributes || !_themeAttributes[aName])
var themeAttr = _themeAttributes && _themeAttributes[aName];
if (!themeAttr)
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
[_themeAttributes[aName] setValue:aValue];
var a = [themeAttr attributeBySettingValue:aValue];
//print("setValue:forThemeAttribute:" + ": " + aName + ": " + aValue + "oldAttribute: " + [themeAttr._values description]);
_themeAttributes[aName] = a;
}
- (id)valueForThemeAttribute:(CPString)aName inState:(ThemeState)aState
{
#if DEBUG
if (aState.isa && [aState isKindOfClass:CPArray])
aState = CPThemeState.apply(null, aState);
[CPException raise:CPInvalidArgumentException reason:@"aState can't be an array. Please use 'valueForThemeAttribute:inStates:' instead: " + aState];
#endif
if (!_themeAttributes || !_themeAttributes[aName])
var themeAttr = _themeAttributes && _themeAttributes[aName];
if (!themeAttr)
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
return [_themeAttributes[aName] valueForState:aState];
return [themeAttr valueForState:aState];
}
- (id)valueForThemeAttribute:(CPString)aName inStates:(CPArray)states
{
var i = [states count],
aState = [states objectAtIndex:--i];
while (i > 0)
{
aState = aState.and([states objectAtIndex:--i]);
}
var themeAttr = _themeAttributes && _themeAttributes[aName];
if (!themeAttr)
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
return [themeAttr valueForState:aState];
}
- (id)valueForThemeAttribute:(CPString)aName
{
if (!_themeAttributes || !_themeAttributes[aName])
var themeAttr = _themeAttributes && _themeAttributes[aName];
if (!themeAttr)
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
return [_themeAttributes[aName] value];
return [themeAttr value];
}
- (id)currentValueForThemeAttribute:(CPString)aName
{
if (!_themeAttributes || !_themeAttributes[aName])
var themeAttr = _themeAttributes && _themeAttributes[aName];
if (!themeAttr)
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
return [_themeAttributes[aName] valueForState:_themeState];
return [themeAttr valueForState:_themeState];
}
- (BOOL)hasThemeAttribute:(CPString)aName
@@ -369,10 +423,14 @@ var CPViewThemeClassKey = @"CPViewThemeClassKey",
value = attributeValueState[1],
state = attributeValueState[2];
if (state)
[self setValue:value forThemeAttribute:attribute inState:state];
else
if (state) {
if (state.isa && [state isKindOfClass:CPArray])
[self setValue:value forThemeAttribute:attribute inStates:state];
else
[self setValue:value forThemeAttribute:attribute inState:state];
} else {
[self setValue:value forThemeAttribute:attribute];
}
}
}