diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index d11e0d8f7..26b1089d8 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -27,6 +27,7 @@ @import "CPMenu.j" @import "CPResponder.j" @import "CPDocumentController.j" +@import "CPThemeBlend.j" var CPMainCibFile = @"CPMainCibFile", CPMainCibFileHumanFriendly = @"Main cib file base name"; @@ -807,7 +808,7 @@ var _CPAppBootstrapperActions = nil; + (BOOL)loadDefaultTheme { - var blend = [[CPBlend alloc] initWithContentsOfURL:[[CPBundle bundleForClass:[CPApplication class]] pathForResource:@"Aristo.blend"]]; + var blend = [[CPThemeBlend alloc] initWithContentsOfURL:[[CPBundle bundleForClass:[CPApplication class]] pathForResource:@"Aristo.blend"]]; [blend loadWithDelegate:self]; diff --git a/AppKit/CPButton.j b/AppKit/CPButton.j index 0c3d8a36b..9317a2992 100644 --- a/AppKit/CPButton.j +++ b/AppKit/CPButton.j @@ -107,12 +107,6 @@ var _CPButtonClassName = nil, CPImage _image; CPImage _alternateImage; - // Display Properties - CPThemedValue _bezelInset; - CPThemedValue _contentInset; - - CPThemedValue _bezelColor; - // Layout Views CPView _bezelView; _CPImageAndTextView _contentView; @@ -123,7 +117,24 @@ var _CPButtonClassName = nil, CPControlSize _controlSize; } -+ (id)themedAttributes ++ (id)standardButtonWithTitle:(CPString)aTitle +{ +} + ++ (id)standardCheckboxWithTitle:(CPString)aTitle +{ +} + +- (id)standardRadioButtonWithTitle:(CPString)aTitle +{ +} + ++ (CPString)themeClass +{ + return @"button"; +} + ++ (id)themeAttributes { return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMakeZero(), nil, 24.0] forKeys:[@"bezel-inset", @"content-inset", @"bezel-color", @"default-height"]]; @@ -136,10 +147,10 @@ var _CPButtonClassName = nil, if (self) { // Should we instead override the defaults? - [self setValue:CPCenterTextAlignment forThemedAttributeName:@"alignment"]; - [self setValue:CPCenterVerticalTextAlignment forThemedAttributeName:@"vertical-alignment"]; - [self setValue:CPImageLeft forThemedAttributeName:@"image-position"]; - [self setValue:CPScaleNone forThemedAttributeName:@"image-scaling"]; + [self setValue:CPCenterTextAlignment forThemeAttribute:@"alignment"]; + [self setValue:CPCenterVerticalTextAlignment forThemeAttribute:@"vertical-alignment"]; + [self setValue:CPImageLeft forThemeAttribute:@"image-position"]; + [self setValue:CPScaleNone forThemeAttribute:@"image-scaling"]; _controlSize = CPRegularControlSize; @@ -343,7 +354,7 @@ var _CPButtonClassName = nil, - (CGRect)contentRectForBounds:(CGRect)bounds { - var contentInset = [self currentValueForThemedAttributeName:@"content-inset"]; + var contentInset = [self currentValueForThemeAttribute:@"content-inset"]; if (_CGInsetIsEmpty(contentInset)) return bounds; @@ -361,7 +372,7 @@ var _CPButtonClassName = nil, if (![self isBordered]) return _CGRectMakeZero(); - var bezelInset = [self currentValueForThemedAttributeName:@"bezel-inset"]; + var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"]; if (_CGInsetIsEmpty(bezelInset)) return bounds; @@ -380,8 +391,8 @@ var _CPButtonClassName = nil, - (void)sizeToFit { var size = [([self title] || " ") sizeWithFont:[self font]], - contentInset = [self currentValueForThemedAttributeName:@"content-inset"], - defaultHeight = [self currentValueForThemedAttributeName:@"default-height"]; + contentInset = [self currentValueForThemeAttribute:@"content-inset"], + defaultHeight = [self currentValueForThemeAttribute:@"default-height"]; [self setFrameSize:CGSizeMake(size.width + contentInset.left + contentInset.right, defaultHeight)]; } @@ -420,41 +431,35 @@ var _CPButtonClassName = nil, relativeToEphemeralSubviewNamed:@"content-view"]; if (bezelView) - [bezelView setBackgroundColor:[self currentValueForThemedAttributeName:@"bezel-color"]]; - + [bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]]; + var contentView = [self layoutEphemeralSubviewNamed:@"content-view" positioned:CPWindowAbove relativeToEphemeralSubviewNamed:@"bezel-view"]; if (contentView) { - [contentView setText:((_controlState & CPControlStateHighlighted) && _alternateTitle) ? _alternateTitle : _title]; - [contentView setImage:((_controlState & CPControlStateHighlighted) && _alternateImage) ? _alternateImage : _image]; - - [contentView setFont:[self currentValueForThemedAttributeName:@"font"]]; - [contentView setTextColor:[self currentValueForThemedAttributeName:@"text-color"]]; - [contentView setAlignment:[self currentValueForThemedAttributeName:@"alignment"]]; - [contentView setVerticalAlignment:[self currentValueForThemedAttributeName:@"vertical-alignment"]]; - [contentView setLineBreakMode:[self currentValueForThemedAttributeName:@"line-break-mode"]]; - [contentView setTextShadowColor:[self currentValueForThemedAttributeName:@"text-shadow-color"]]; - [contentView setTextShadowOffset:[self currentValueForThemedAttributeName:@"text-shadow-offset"]]; - [contentView setImagePosition:[self currentValueForThemedAttributeName:@"image-position"]]; - [contentView setImageScaling:[self currentValueForThemedAttributeName:@"image-scaling"]]; + [contentView setText:([self hasThemeState:CPThemeStateHighlighted] && _alternateTitle) ? _alternateTitle : _title]; + [contentView setImage:([self hasThemeState:CPThemeStateHighlighted] && _alternateImage) ? _alternateImage : _image]; + + [contentView setFont:[self currentValueForThemeAttribute:@"font"]]; + [contentView setTextColor:[self currentValueForThemeAttribute:@"text-color"]]; + [contentView setAlignment:[self currentValueForThemeAttribute:@"alignment"]]; + [contentView setVerticalAlignment:[self currentValueForThemeAttribute:@"vertical-alignment"]]; + [contentView setLineBreakMode:[self currentValueForThemeAttribute:@"line-break-mode"]]; + [contentView setTextShadowColor:[self currentValueForThemeAttribute:@"text-shadow-color"]]; + [contentView setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]]; + [contentView setImagePosition:[self currentValueForThemeAttribute:@"image-position"]]; + [contentView setImageScaling:[self currentValueForThemeAttribute:@"image-scaling"]]; } } - (void)setDefaultButton:(BOOL)shouldBeDefaultButton { - if ((!!(_controlState & CPControlStateDefault)) === shouldBeDefaultButton) - return; - if (shouldBeDefaultButton) - _controlState |= CPControlStateDefault; + [self setThemeState:CPThemeStateDefault]; else - _controlState &= ~CPControlStateDefault; - - [self setNeedsLayout]; - [self setNeedsDisplay:YES]; + [self unsetThemeState:CPThemeStateDefault]; } @end @@ -471,21 +476,15 @@ var _CPButtonClassName = nil, - (void)setBordered:(BOOL)shouldBeBordered { - if ((!!(_controlState & CPControlStateBordered)) === shouldBeBordered) - return; - if (shouldBeBordered) - _controlState |= CPControlStateBordered; + [self setThemeState:CPThemeStateBordered]; else - _controlState &= ~CPControlStateBordered; - - [self setNeedsLayout]; - [self setNeedsDisplay:YES]; + [self unsetThemeState:CPThemeStateBordered]; } - (BOOL)isBordered { - return !!(_controlState & CPControlStateBordered); + return [self hasThemeState:CPThemeStateBordered]; } @end diff --git a/AppKit/CPButtonBar.j b/AppKit/CPButtonBar.j index 75658bcca..5bf1b00f3 100644 --- a/AppKit/CPButtonBar.j +++ b/AppKit/CPButtonBar.j @@ -8,7 +8,7 @@ { } -+ (id)themedAttributes ++ (id)themeAttributes { return [CPDictionary dictionaryWithObjects:[nil] forKeys:[@"bezel-color"]]; @@ -43,7 +43,7 @@ relativeToEphemeralSubviewNamed:@""]; if (bezelView) - [bezelView setBackgroundColor:[self currentValueForThemedAttributeName:@"bezel-color"]]; + [bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]]; } - (void)addSubview:(CPView)aSubview diff --git a/AppKit/CPColorPicker.j b/AppKit/CPColorPicker.j index 8e52553f4..5fafd56e3 100644 --- a/AppKit/CPColorPicker.j +++ b/AppKit/CPColorPicker.j @@ -113,8 +113,8 @@ _brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(0, (aFrame.size.height - 34), aFrame.size.width, 15)]; - [_brightnessSlider setValue:15.0 forThemedAttributeName:@"track-width"]; - [_brightnessSlider setValue:[CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPColorPicker class]] pathForResource:@"brightness_bar.png"]]] forThemedAttributeName:@"track-color"]; + [_brightnessSlider setValue:15.0 forThemeAttribute:@"track-width"]; + [_brightnessSlider setValue:[CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPColorPicker class]] pathForResource:@"brightness_bar.png"]]] forThemeAttribute:@"track-color"]; [_brightnessSlider setMinValue:0.0]; [_brightnessSlider setMaxValue:100.0]; diff --git a/AppKit/CPControl.j b/AppKit/CPControl.j index 058071110..611919cb0 100644 --- a/AppKit/CPControl.j +++ b/AppKit/CPControl.j @@ -99,18 +99,16 @@ var CPControlBlackColor = [CPColor blackColor]; unsigned _trackingMouseDownFlags; CGPoint _previousTrackingLocation; - CPControlState _controlState; - JSObject _ephemeralSubviewsForNames; CPSet _ephereralSubviews; - CPString _toolTip; + CPString _toolTip; // FIXME: Who uses this? BOOL _isBezeled; } -+ (CPDictionary)themedAttributes ++ (CPDictionary)themeAttributes { return [CPDictionary dictionaryWithObjects:[ CPLeftTextAlignment, CPTopVerticalTextAlignment, CPLineBreakByClipping, [CPColor blackColor], [CPFont systemFontOfSize:12.0], nil, _CGSizeMakeZero(), CPImageLeft, CPScaleToFit] @@ -123,8 +121,6 @@ var CPControlBlackColor = [CPColor blackColor]; if (self) { - _controlState = CPControlStateNormal; - _sendActionOn = CPLeftMouseUpMask; _trackingMouseDownFlags = 0; } @@ -493,11 +489,11 @@ var CPControlBlackColor = [CPColor blackColor]; #define BRIDGE(UPPERCASE, LOWERCASE, ATTRIBUTENAME) \ - (void)set##UPPERCASE:(id)aValue\ {\ -[self setValue:aValue forThemedAttributeName:ATTRIBUTENAME];\ +[self setValue:aValue forThemeAttribute:ATTRIBUTENAME];\ }\ - (id)LOWERCASE\ {\ -return [self valueForThemedAttributeName:ATTRIBUTENAME];\ +return [self valueForThemeAttribute:ATTRIBUTENAME];\ } BRIDGE(Alignment, alignment, "alignment") @@ -510,28 +506,17 @@ BRIDGE(TextShadowOffset, textShadowOffset, "text-shadow-offset") BRIDGE(ImagePosition, imagePosition, "image-position") BRIDGE(ImageScaling, imageScaling, "image-scaling") -- (int)controlState -{ - return _controlState; -} - - (void)setEnabled:(BOOL)isEnabled { - if ((!(_controlState & CPControlStateDisabled)) === isEnabled) - return; - if (isEnabled) - _controlState &= ~CPControlStateDisabled; + [self unsetThemeState:CPThemeStateDisabled]; else - _controlState |= CPControlStateDisabled; - - [self setNeedsLayout]; - [self setNeedsDisplay:YES]; + [self setThemeState:CPThemeStateDisabled]; } - (BOOL)isEnabled { - return !(_controlState & CPControlStateDisabled); + return ![self hasThemeState:CPThemeStateDisabled]; } - (void)highlight:(BOOL)shouldHighlight @@ -541,21 +526,15 @@ BRIDGE(ImageScaling, imageScaling, "image-scaling") - (void)setHighlighted:(BOOL)isHighlighted { - if ((!!(_controlState & CPControlStateHighlighted)) === isHighlighted) - return; - if (isHighlighted) - _controlState |= CPControlStateHighlighted; + [self setThemeState:CPThemeStateHighlighted]; else - _controlState &= ~CPControlStateHighlighted; - - [self setNeedsLayout]; - [self setNeedsDisplay:YES]; + [self unsetThemeState:CPThemeStateHighlighted]; } - (BOOL)isHighlighted { - return !!(_controlState & CPControlStateHighlighted); + return [self hasThemeState:CPThemeStateHighlighted]; } - (CPView)createEphemeralSubviewNamed:(CPString)aViewName @@ -631,8 +610,6 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey"; if (self) { - _controlState = [aCoder decodeObjectForKey:CPControlControlStateKey]; - [self setObjectValue:[aCoder decodeObjectForKey:CPControlValueKey]]; [self setTarget:[aCoder decodeObjectForKey:CPControlTargetKey]]; @@ -668,7 +645,6 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey"; if (subviews) _subviews = subviews; - [aCoder encodeObject:_controlState forKey:CPControlControlStateKey]; [aCoder encodeObject:_value forKey:CPControlValueKey]; /*[aCoder encodeBool:_isEnabled forKey:CPControlIsEnabledKey]; diff --git a/AppKit/CPImageView.j b/AppKit/CPImageView.j index a80a30d82..aa9d12332 100644 --- a/AppKit/CPImageView.j +++ b/AppKit/CPImageView.j @@ -205,7 +205,7 @@ var LEFT_SHADOW_INSET = 3.0, [super setImageScaling:anImageScaling]; #if PLATFORM(DOM) - if ([self currentValueForThemedAttributeName:@"image-scaling"] === CPScaleToFit) + if ([self currentValueForThemeAttribute:@"image-scaling"] === CPScaleToFit) { CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, 0.0, 0.0); } @@ -254,7 +254,7 @@ var LEFT_SHADOW_INSET = 3.0, var bounds = [self bounds], image = [self image], - imageScaling = [self currentValueForThemedAttributeName:@"image-scaling"], + imageScaling = [self currentValueForThemeAttribute:@"image-scaling"], x = 0.0, y = 0.0, insetWidth = (_hasShadow ? HORIZONTAL_SHADOW_INSET : 0.0), diff --git a/AppKit/CPPopUpButton.j b/AppKit/CPPopUpButton.j index bc68954dc..7ac5901f5 100644 --- a/AppKit/CPPopUpButton.j +++ b/AppKit/CPPopUpButton.j @@ -30,7 +30,7 @@ var VISIBLE_MARGIN = 7.0; -CPPopUpButtonStatePullsDown = 1 << 12; +CPPopUpButtonStatePullsDown = CPThemeState("pulls-down"); /*! @class CPPopUpButton @@ -44,6 +44,11 @@ CPPopUpButtonStatePullsDown = 1 << 12; CPMenu _menu; } ++ (CPString)themeClass +{ + return "popup-button"; +} + /*! Initializes the pop-up button to the specified size. @param aFrame the size for the button @@ -59,9 +64,9 @@ CPPopUpButtonStatePullsDown = 1 << 12; _selectedIndex = CPNotFound; _preferredEdge = CPMaxYEdge; - [self setValue:CPImageLeft forThemedAttributeName:@"image-position"]; - [self setValue:CPLeftTextAlignment forThemedAttributeName:@"alignment"]; - [self setValue:CPLineBreakByTruncatingTail forThemedAttributeName:@"line-break-mode"]; + [self setValue:CPImageLeft forThemeAttribute:@"image-position"]; + [self setValue:CPLeftTextAlignment forThemeAttribute:@"alignment"]; + [self setValue:CPLineBreakByTruncatingTail forThemeAttribute:@"line-break-mode"]; [self setMenu:[[CPMenu alloc] initWithTitle:@""]]; @@ -85,21 +90,21 @@ CPPopUpButtonStatePullsDown = 1 << 12; */ - (void)setPullsDown:(BOOL)shouldPullDown { - if ((!!(_controlState & CPPopUpButtonStatePullsDown)) === shouldPullDown) - return; - if (shouldPullDown) - _controlState |= CPPopUpButtonStatePullsDown; + var changed = [self setThemeState:CPPopUpButtonStatePullsDown]; else - _controlState &= ~CPPopUpButtonStatePullsDown; + var changed = [self unsetThemeState:CPPopUpButtonStatePullsDown]; + + if (!changed) + return; var items = [_menu itemArray]; - + if ([items count] <= 0) return; [items[0] setHidden:[self pullsDown]]; - + [self synchronizeTitleAndSelectedItem]; } @@ -108,7 +113,7 @@ CPPopUpButtonStatePullsDown = 1 << 12; */ - (BOOL)pullsDown { - return _controlState & CPPopUpButtonStatePullsDown; + return [self hasThemeState:CPPopUpButtonStatePullsDown]; } // Inserting and Deleting Items diff --git a/AppKit/CPScroller.j b/AppKit/CPScroller.j index cecfec70d..f4721f7e5 100644 --- a/AppKit/CPScroller.j +++ b/AppKit/CPScroller.j @@ -71,7 +71,12 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob"; CGPoint _trackingStartPoint; } -+ (id)themedAttributes ++ (CPString)themeClass +{ + return "scroller"; +} + ++ (id)themeAttributes { return [CPDictionary dictionaryWithObjects:[ _CGInsetMakeZero(), nil, nil, nil, nil, @@ -181,14 +186,14 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob"; return _knobProportion; } -- (id)currentValueForThemedAttributeName:(CPString)anAttributeName +- (id)currentValueForThemeAttribute:(CPString)anAttributeName { - var controlState = _controlState; + var themeState = _themeState; if (NAMES_FOR_PARTS[_hitPart] + "-color" !== anAttributeName) - controlState &= ~CPControlStateHighlighted; + themeState &= ~CPThemeStateHighlighted; - return [self valueForThemedAttributeName:anAttributeName inControlState:controlState]; + return [self valueForThemeAttribute:anAttributeName inState:themeState]; } // Calculating Layout @@ -261,18 +266,18 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob"; // At this point we know we're going to need arrows. _usableParts = CPAllScrollerParts; - var trackOverlapInset = [self currentValueForThemedAttributeName:@"track-overlap-inset"], + var trackOverlapInset = [self currentValueForThemeAttribute:@"track-overlap-inset"], width = _CGRectGetWidth(bounds), height = _CGRectGetHeight(bounds); if ([self isVertical]) { - var decrementLineSize = [self currentValueForThemedAttributeName:"decrement-line-size"], - incrementLineSize = [self currentValueForThemedAttributeName:"increment-line-size"], + var decrementLineSize = [self currentValueForThemeAttribute:"decrement-line-size"], + incrementLineSize = [self currentValueForThemeAttribute:"increment-line-size"], effectiveDecrementLineHeight = decrementLineSize.height - trackOverlapInset.top, effectiveIncrementLineHeight = incrementLineSize.height - trackOverlapInset.bottom, slotHeight = height - effectiveDecrementLineHeight - effectiveIncrementLineHeight, - minimumKnobSize = [self currentValueForThemedAttributeName:"minimum-knob-size"], + minimumKnobSize = [self currentValueForThemeAttribute:"minimum-knob-size"], knobHeight = MAX(minimumKnobSize.height, (slotHeight * _knobProportion)), knobLocation = effectiveDecrementLineHeight + (slotHeight - knobHeight) * [self floatValue]; @@ -286,12 +291,12 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob"; else { - var decrementLineSize = [self currentValueForThemedAttributeName:"decrement-line-size"], - incrementLineSize = [self currentValueForThemedAttributeName:"increment-line-size"], + var decrementLineSize = [self currentValueForThemeAttribute:"decrement-line-size"], + incrementLineSize = [self currentValueForThemeAttribute:"increment-line-size"], effectiveDecrementLineWidth = decrementLineSize.width - trackOverlapInset.left, effectiveIncrementLineWidth = incrementLineSize.width - trackOverlapInset.right; slotWidth = width - effectiveDecrementLineWidth - effectiveIncrementLineWidth, - minimumKnobSize = [self currentValueForThemedAttributeName:"minimum-knob-size"], + minimumKnobSize = [self currentValueForThemeAttribute:"minimum-knob-size"], knobWidth = MAX(minimumKnobSize.width, (slotWidth * _knobProportion)), knobLocation = effectiveDecrementLineWidth + (slotWidth - knobWidth) * [self floatValue]; @@ -377,7 +382,7 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob"; view = [self layoutEphemeralSubviewNamed:part positioned:CPWindowAbove relativeToEphemeralSubviewNamed:PARTS_ARRANGEMENT[index - 1]]; if (view) - [view setBackgroundColor:[self currentValueForThemedAttributeName:NAMES_FOR_PARTS[part] + "-color"]]; + [view setBackgroundColor:[self currentValueForThemeAttribute:NAMES_FOR_PARTS[part] + "-color"]]; } } @@ -534,9 +539,9 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob"; _isVertical = width < height ? 1 : (width > height ? 0 : -1); if (_isVertical === 1) - _controlState |= CPControlStateVertical; + [self setThemeState:CPThemeStateVertical]; else if (_isVertical === 0) - _controlState &= ~CPControlStateVertical; + [self unsetThemeState:CPThemeStateVertical]; } - (void)setFrameSize:(CGSize)aSize diff --git a/AppKit/CPSegmentedControl.j b/AppKit/CPSegmentedControl.j index bfe81764f..74c4c870f 100644 --- a/AppKit/CPSegmentedControl.j +++ b/AppKit/CPSegmentedControl.j @@ -49,7 +49,7 @@ CPSegmentSwitchTrackingMomentary = 2; @implementation CPSegmentedControl : CPControl { CPArray _segments; - CPArray _controlStates; + CPArray _themeStates; int _selectedSegment; int _segmentStyle; @@ -59,7 +59,12 @@ CPSegmentSwitchTrackingMomentary = 2; BOOL _trackingHighlighted; } -+ (id)themedAttributes ++ (CPString)themeClass +{ + return "segmented-control"; +} + ++ (id)themeAttributes { return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMakeZero(), nil, nil, nil, nil, 1.0, 24.0] forKeys:[@"bezel-inset", @"content-inset", @"left-segment-bezel-color", @"right-segment-bezel-color", @"center-segment-bezel-color", @"divider-bezel-color", @"divider-thickness", @"default-height"]]; @@ -68,7 +73,7 @@ CPSegmentSwitchTrackingMomentary = 2; - (id)initWithFrame:(CGRect)aRect { _segments = []; - _controlStates = []; + _themeStates = []; self = [super initWithFrame:aRect]; @@ -111,7 +116,7 @@ CPSegmentSwitchTrackingMomentary = 2; _segments[index] = [[_CPSegmentItem alloc] init]; _segments[index].frame.size.height = height; - _controlStates[index] = CPControlStateNormal; + _themeStates[index] = CPThemeStateNormal; } } else if (aCount < _segments.length) @@ -384,7 +389,7 @@ CPSegmentSwitchTrackingMomentary = 2; segment.selected = isSelected; - _controlStates[aSegment] = isSelected ? CPControlStateSelected : CPControlStateNormal; + _themeStates[aSegment] = isSelected ? CPThemeStateSelected : CPThemeStateNormal; // We need to do some cleanup if we only allow one selection. if (isSelected) @@ -396,7 +401,7 @@ CPSegmentSwitchTrackingMomentary = 2; if (_trackingMode == CPSegmentSwitchTrackingSelectOne && oldSelectedSegment != aSegment && oldSelectedSegment != -1) { _segments[oldSelectedSegment].selected = NO; - _controlStates[oldSelectedSegment] = CPControlStateNormal; + _themeStates[oldSelectedSegment] = CPThemeStateNormal; [self drawSegmentBezel:oldSelectedSegment highlight:NO]; } @@ -467,30 +472,30 @@ CPSegmentSwitchTrackingMomentary = 2; - (void)drawSegmentBezel:(int)aSegment highlight:(BOOL)shouldHighlight { if (shouldHighlight) - _controlStates[aSegment] |= CPControlStateHighlighted; + _themeStates[aSegment] |= CPThemeStateHighlighted; else - _controlStates[aSegment] &= ~CPControlStateHighlighted; + _themeStates[aSegment] &= ~CPThemeStateHighlighted; [self setNeedsLayout]; } - (float)_leftOffsetForSegment:(unsigned)segment { - var bezelInset = [self currentValueForThemedAttributeName:@"bezel-inset"]; + var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"]; if (segment == 0) return bezelInset.left; - var thickness = [self currentValueForThemedAttributeName:@"divider-thickness"]; + var thickness = [self currentValueForThemeAttribute:@"divider-thickness"]; return [self _leftOffsetForSegment:segment - 1] + [self widthForSegment:segment - 1] + thickness; } - (CGRect)rectForEphemeralSubviewNamed:(CPString)aName { - var height = [self currentValueForThemedAttributeName:@"default-height"], - contentInset = [self currentValueForThemedAttributeName:@"content-inset"], - bezelInset = [self currentValueForThemedAttributeName:@"bezel-inset"], + var height = [self currentValueForThemeAttribute:@"default-height"], + contentInset = [self currentValueForThemeAttribute:@"content-inset"], + bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"], bounds = [self bounds]; if (aName === "left-segment-bezel") @@ -521,7 +526,7 @@ CPSegmentSwitchTrackingMomentary = 2; var segment = parseInt(aName.substring("divider-bezel-".length), 10), width = [self widthForSegment:segment], left = [self _leftOffsetForSegment:segment], - thickness = [self currentValueForThemedAttributeName:@"divider-thickness"]; + thickness = [self currentValueForThemeAttribute:@"divider-thickness"]; return CGRectMake(left + width, bezelInset.top, thickness, height); } @@ -536,8 +541,8 @@ CPSegmentSwitchTrackingMomentary = 2; - (void)layoutSubviews { - var leftCapColor = [self valueForThemedAttributeName:@"left-segment-bezel-color" - inControlState:_controlStates[0]]; + var leftCapColor = [self valueForThemeAttribute:@"left-segment-bezel-color" + inState:_themeStates[0]]; var leftBezelView = [self layoutEphemeralSubviewNamed:@"left-segment-bezel" positioned:CPWindowBelow @@ -545,8 +550,8 @@ CPSegmentSwitchTrackingMomentary = 2; [leftBezelView setBackgroundColor:leftCapColor]; - var rightCapColor = [self valueForThemedAttributeName:@"right-segment-bezel-color" - inControlState:_controlStates[_controlStates.length - 1]]; + var rightCapColor = [self valueForThemeAttribute:@"right-segment-bezel-color" + inState:_themeStates[_themeStates.length - 1]]; var rightBezelView = [self layoutEphemeralSubviewNamed:@"right-segment-bezel" positioned:CPWindowBelow @@ -554,10 +559,10 @@ CPSegmentSwitchTrackingMomentary = 2; [rightBezelView setBackgroundColor:rightCapColor]; - for (var i=0, count = _controlStates.length; i height ? 0 : -1); if (_isVertical === 1) - _controlState |= CPControlStateVertical; + [self setThemeState:CPThemeStateVertical]; else if (_isVertical === 0) - _controlState &= ~CPControlStateVertical; + [self unsetThemeState:CPThemeStateVertical]; } - (int)isVertical @@ -263,14 +265,14 @@ CPCircularSlider = 1; relativeToEphemeralSubviewNamed:@"knob-view"]; if (trackView) - [trackView setBackgroundColor:[self currentValueForThemedAttributeName:@"track-color"]]; + [trackView setBackgroundColor:[self currentValueForThemeAttribute:@"track-color"]]; var knobView = [self layoutEphemeralSubviewNamed:@"knob-view" positioned:CPWindowAbove relativeToEphemeralSubviewNamed:@"track-view"]; if (knobView) - [knobView setBackgroundColor:[self currentValueForThemedAttributeName:"knob-color"]]; + [knobView setBackgroundColor:[self currentValueForThemeAttribute:"knob-color"]]; } - (BOOL)tracksMouseOutsideOfFrame @@ -284,7 +286,7 @@ CPCircularSlider = 1; knobRect = [self knobRectForBounds:bounds], trackRect = [self trackRectForBounds:bounds]; - if (_controlState & CPControlStateCircular) + if ([self hasThemeState:CPThemeStateCircular]) { var knobWidth = _CGRectGetWidth(knobRect); @@ -295,7 +297,7 @@ CPCircularSlider = 1; dx = aPoint.x - _CGRectGetMidX(trackRect), dy = aPoint.y - _CGRectGetMidY(trackRect); - return MAX(0.0, MIN(1.0, 1.0 - (3*PI_2 - ATAN2(dy, dx))%PI2 / PI2)) * ([self maxValue] - minValue) + minValue; + return MAX(0.0, MIN(1.0, 1.0 - (3 * PI_2 - ATAN2(dy, dx)) % PI2 / PI2)) * ([self maxValue] - minValue) + minValue; } else if ([self isVertical]) { diff --git a/AppKit/CPTableColumn.j b/AppKit/CPTableColumn.j index 897f27145..3cdc65e8f 100644 --- a/AppKit/CPTableColumn.j +++ b/AppKit/CPTableColumn.j @@ -95,7 +95,7 @@ CPTableColumnUserResizingMask = 2; _maxWidth = 1000.0; var dataView = [[CPTextField alloc] initWithFrame:CPRectMakeZero()]; - [dataView setValue:[CPColor whiteColor] forThemedAttributeName:"text-color" inControlState:CPControlStateHighlighted]; + [dataView setValue:[CPColor whiteColor] forThemeAttribute:"text-color" inState:CPThemeStateHighlighted]; [self setDataView:dataView]; diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 21dd731e5..d8b9ebe14 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -25,7 +25,7 @@ @import "CPStringDrawing.j" @import "CPCompatibility.j" -#include "CoreGraphics/CGGeometry.j" +#include "CoreGraphics/CGGeometry.h" #include "Platform/Platform.h" #include "Platform/DOM/CPDOMDisplayServer.h" @@ -109,8 +109,8 @@ var CPSecureTextFieldCharacter = "\u2022"; @end -CPTextFieldStateRounded = 1 << 12; -CPTextFieldStatePlaceholder = 1 << 13; +CPTextFieldStateRounded = CPThemeState("rounded"); +CPTextFieldStatePlaceholder = CPThemeState("placeholder"); /*! This control displays editable text in a Cappuccino application. @@ -137,10 +137,15 @@ CPTextFieldStatePlaceholder = 1 << 13; CPControlSize _controlSize; } -+ (id)themedAttributes ++ (CPString)themeClass { - return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMake(2.0, 2.0, 2.0, 2.0), _CGInsetMake(2.0, 2.0, 2.0, 2.0), nil] - forKeys:[@"bezel-inset", @"content-inset", @"bezeled-content-inset", @"bezel-color"]]; + return "textfield"; +} + ++ (id)themeAttributes +{ + return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMake(2.0, 2.0, 2.0, 2.0), nil] + forKeys:[@"bezel-inset", @"content-inset", @"bezel-color"]]; } /* @ignore */ @@ -308,7 +313,7 @@ CPTextFieldStatePlaceholder = 1 << 13; _sendActionOn = CPKeyUpMask | CPKeyDownMask; - [self setValue:CPLeftTextAlignment forThemedAttributeName:@"alignment"]; + [self setValue:CPLeftTextAlignment forThemeAttribute:@"alignment"]; } return self; @@ -373,16 +378,10 @@ CPTextFieldStatePlaceholder = 1 << 13; */ - (void)setBezeled:(BOOL)shouldBeBezeled { - if ((!!(_controlState & CPControlStateBezeled)) === shouldBeBezeled) - return; - if (shouldBeBezeled) - _controlState |= CPControlStateBezeled; + [self setThemeState:CPThemeStateBezeled]; else - _controlState &= ~CPControlStateBezeled; - - [self setNeedsLayout]; - [self setNeedsDisplay:YES]; + [self unsetThemeState:CPThemeStateBezeled]; } /*! @@ -390,7 +389,7 @@ CPTextFieldStatePlaceholder = 1 << 13; */ - (BOOL)isBezeled { - return !!(_controlState & CPControlStateBezeled); + return [self hasThemeState:CPThemeStateBezeled]; } /*! @@ -401,16 +400,10 @@ CPTextFieldStatePlaceholder = 1 << 13; { var shouldBeRounded = aBezelStyle === CPTextFieldRoundedBezel; - if ((!!(_controlState & CPTextFieldStateRounded)) === shouldBeRounded) - return; - if (shouldBeRounded) - _controlState |= CPTextFieldStateRounded; + [self setThemeState:CPTextFieldStateRounded]; else - _controlState &= ~CPTextFieldStateRounded; - - [self setNeedsLayout]; - [self setNeedsDisplay:YES]; + [self unsetThemeState:CPTextFieldStateRounded]; } /*! @@ -418,7 +411,7 @@ CPTextFieldStatePlaceholder = 1 << 13; */ - (CPTextFieldBezelStyle)bezelStyle { - if (_controlState & CPTextFieldStateRounded) + if ([self hasThemeState:CPTextFieldStateRounded]) return CPTextFieldRoundedBezel; return CPTextFieldSquareBezel; @@ -430,16 +423,10 @@ CPTextFieldStatePlaceholder = 1 << 13; */ - (void)setBordered:(BOOL)shouldBeBordered { - if ((!!(_controlState & CPControlStateBordered)) === shouldBeBordered) - return; - if (shouldBeBordered) - _controlState |= CPControlStateBordered; + [self setThemeState:CPThemeStateBordered]; else - _controlState &= ~CPControlStateBordered; - - [self setNeedsLayout]; - [self setNeedsDisplay:YES]; + [self unsetThemeState:CPThemeStateBordered]; } /*! @@ -447,7 +434,7 @@ CPTextFieldStatePlaceholder = 1 << 13; */ - (BOOL)isBordered { - return !!(_controlState & CPControlStateBordered); + return [self hasThemeState:CPThemeStateBordered]; } /*! @@ -508,7 +495,7 @@ CPTextFieldStatePlaceholder = 1 << 13; if (CPTextFieldInputOwner && [CPTextFieldInputOwner window] !== [self window]) [[CPTextFieldInputOwner window] makeFirstResponder:nil]; - _controlState |= CPControlStateEditing; + [self setThemeState:CPThemeStateEditing]; [self _updatePlaceholderState]; @@ -520,8 +507,8 @@ CPTextFieldStatePlaceholder = 1 << 13; element = [self _inputElement]; element.value = string; - element.style.color = [[self currentValueForThemedAttributeName:@"text-color"] cssString]; - element.style.font = [[self currentValueForThemedAttributeName:@"font"] cssString]; + element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString]; + element.style.font = [[self currentValueForThemeAttribute:@"font"] cssString]; element.style.zIndex = 1000; var contentRect = [self contentRectForBounds:[self bounds]]; @@ -563,7 +550,7 @@ CPTextFieldStatePlaceholder = 1 << 13; /* @ignore */ - (BOOL)resignFirstResponder { - _controlState &= ~CPControlStateEditing; + [self unsetThemeState:CPThemeStateEditing]; [self _updatePlaceholderState]; @@ -635,19 +622,12 @@ CPTextFieldStatePlaceholder = 1 << 13; - (void)_updatePlaceholderState { - var string = [self stringValue], - controlState = _controlState; + var string = [self stringValue]; - if ((!string || [string length] === 0) && !(_controlState & CPControlStateEditing)) - _controlState |= CPTextFieldStatePlaceholder; + if ((!string || [string length] === 0) && ![self hasThemeState:CPThemeStateEditing]) + [self setThemeState:CPTextFieldStatePlaceholder]; else - _controlState &= ~CPTextFieldStatePlaceholder; - - if (_controlState !== controlState) - { - [self setNeedsLayout]; - [self setNeedsDisplay:YES]; - } + [self unsetThemeState:CPTextFieldStatePlaceholder]; } /*! @@ -662,7 +642,7 @@ CPTextFieldStatePlaceholder = 1 << 13; _placeholderString = aStringValue; // Only update things if we need to show the placeholder - if (_controlState & CPTextFieldStatePlaceholder) + if ([self hasThemeState:CPTextFieldStatePlaceholder]) { [self setNeedsLayout]; [self setNeedsDisplay:YES]; @@ -684,7 +664,7 @@ CPTextFieldStatePlaceholder = 1 << 13; - (void)sizeToFit { var size = [([self stringValue] || " ") sizeWithFont:[self font]], - contentInset = [self currentValueForThemedAttributeName:@"content-inset"]; + contentInset = [self currentValueForThemeAttribute:@"content-inset"]; [self setFrameSize:CGSizeMake(size.width + contentInset.left + contentInset.right, size.height + contentInset.top + contentInset.bottom)]; } @@ -749,7 +729,7 @@ CPTextFieldStatePlaceholder = 1 << 13; - (CGRect)contentRectForBounds:(CGRect)bounds { - var contentInset = [self currentValueForThemedAttributeName:@"content-inset"]; + var contentInset = [self currentValueForThemeAttribute:@"content-inset"]; if (!contentInset) return bounds; @@ -764,7 +744,7 @@ CPTextFieldStatePlaceholder = 1 << 13; - (CGRect)bezelRectForBounds:(CFRect)bounds { - var bezelInset = [self currentValueForThemedAttributeName:@"bezel-inset"]; + var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"]; if (_CGInsetIsEmpty(bezelInset)) return bounds; @@ -816,7 +796,7 @@ CPTextFieldStatePlaceholder = 1 << 13; relativeToEphemeralSubviewNamed:@"content-view"]; if (bezelView) - [bezelView setBackgroundColor:[self currentValueForThemedAttributeName:@"bezel-color"]]; + [bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]]; var contentView = [self layoutEphemeralSubviewNamed:@"content-view" positioned:CPWindowAbove @@ -824,11 +804,11 @@ CPTextFieldStatePlaceholder = 1 << 13; if (contentView) { - [contentView setHidden:_controlState & CPControlStateEditing]; + [contentView setHidden:[self hasThemeState:CPThemeStateEditing]]; var string = ""; - if (_controlState & CPTextFieldStatePlaceholder) + if ([self hasThemeState:CPTextFieldStatePlaceholder]) string = [self placeholderString]; else { @@ -840,13 +820,13 @@ CPTextFieldStatePlaceholder = 1 << 13; [contentView setText:string]; - [contentView setTextColor:[self currentValueForThemedAttributeName:@"text-color"]]; - [contentView setFont:[self currentValueForThemedAttributeName:@"font"]]; - [contentView setAlignment:[self currentValueForThemedAttributeName:@"alignment"]]; - [contentView setVerticalAlignment:[self currentValueForThemedAttributeName:@"vertical-alignment"]]; - [contentView setLineBreakMode:[self currentValueForThemedAttributeName:@"line-break-mode"]]; - [contentView setTextShadowColor:[self currentValueForThemedAttributeName:@"text-shadow-color"]]; - [contentView setTextShadowOffset:[self currentValueForThemedAttributeName:@"text-shadow-offset"]]; + [contentView setTextColor:[self currentValueForThemeAttribute:@"text-color"]]; + [contentView setFont:[self currentValueForThemeAttribute:@"font"]]; + [contentView setAlignment:[self currentValueForThemeAttribute:@"alignment"]]; + [contentView setVerticalAlignment:[self currentValueForThemeAttribute:@"vertical-alignment"]]; + [contentView setLineBreakMode:[self currentValueForThemeAttribute:@"line-break-mode"]]; + [contentView setTextShadowColor:[self currentValueForThemeAttribute:@"text-shadow-color"]]; + [contentView setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]]; } } diff --git a/AppKit/CPTheme.j b/AppKit/CPTheme.j index e4c39a17f..d1a6750ad 100644 --- a/AppKit/CPTheme.j +++ b/AppKit/CPTheme.j @@ -21,123 +21,16 @@ */ @import -@import -@import - -@import "CPThemedAttribute.j" +@import -@implementation CPBlend : CPObject -{ - CPBundle _bundle; - CPArray _themes @accessors(readonly); - id _loadDelegate; -} - -- (id)initWithContentsOfURL:(CPURL)aURL -{ - self = [super init]; - - if (self) - { - _bundle = [[CPBundle alloc] initWithPath:aURL + "/Info.plist"]; - } - - return self; -} - -- (void)loadWithDelegate:(id)aDelegate -{ - _loadDelegate = aDelegate; - - [_bundle loadWithDelegate:self]; -} - -- (void)bundleDidFinishLoading:(CPBundle)aBundle -{ - var paths = [_bundle objectForInfoDictionaryKey:@"CPBundleReplacedFiles"], - index = 0, - count = paths.length, - bundlePath = [_bundle bundlePath]; - - while (count--) - { - var path = paths[count]; - - if ([path pathExtension] === "keyedtheme") - { - var unarchiver = [[_CPThemeKeyedUnarchiver alloc] - initForReadingWithData:[CPData dataWithString:objj_files[bundlePath + '/' + path].contents] - bundle:_bundle]; - - [unarchiver decodeObjectForKey:@"root"]; - - [unarchiver finishDecoding]; - } - } - - [_loadDelegate blendDidFinishLoading:self]; -} - -@end - -var CPThemesByName = nil, - CPThemeDefaultTheme = nil, - - CPThemeViewClass = Nil, - CPThemeWindowClass = Nil; +var CPThemesByName = { }, + CPThemeDefaultTheme = nil; @implementation CPTheme : CPObject { - CPString _name; - Class _activeClass; - JSObject _classTable; -} - -+ (void)initialize -{ - if (self !== [CPTheme class]) - return; - - CPThemesByName = {}; - - CPThemeViewClass = [CPView class]; - CPThemeWindowClass = [CPWindow class]; - - var bundle = [CPBundle bundleForClass:self]; - defaultThemePath = [bundle objectForInfoDictionaryKey:@"Default Themes Path"], - defaultThemeName = [bundle objectForInfoDictionaryKey:@"Default Theme Name"]; - - if (!defaultThemePath) - return; - - defaultThemePath = [bundle pathForResource:defaultThemePath]; - - var file = objj_files[defaultThemePath + "/Info.plist"]; - - if (!file) - return; - - // Oh boy are we tricky. - var infoDictionary = CPPropertyListCreateFromData([CPData dataWithString:objj_files[defaultThemePath + "/Info.plist"].contents]); - - themes = [infoDictionary objectForKey:@"CPBundleReplacedFiles"], - - themeIndex = 0, - themeCount = [themes count]; - - for (; themeIndex < themeCount; ++themeIndex) - { - var unarchiver = [[_CPThemeKeyedUnarchiver alloc] - initForReadingWithData:[CPData dataWithString:objj_files[defaultThemePath + '/' + themes[themeIndex]].contents] - bundle:file.bundle]; - - [unarchiver decodeObjectForKey:@"root"]; - - [unarchiver finishDecoding]; - } - - [self setDefaultTheme:[CPTheme themeNamed:defaultThemeName]]; + CPString _name; + CPDictionary _attributes; } + (void)setDefaultTheme:(CPTheme)aTheme @@ -155,24 +48,18 @@ var CPThemesByName = nil, return CPThemesByName[aName]; } -+ (void)loadThemesAtURL:(CPURL)aURL delegate:(id)aLoadDelegate -{ - -} - - (id)initWithName:(CPString)aName { self = [super init]; - + if (self) { _name = aName; - _classTable = {}; - _classTable[[[self class] className]] = {}; - - CPThemesByName[_name] = aName; + _attributes = [CPDictionary dictionary]; + + CPThemesByName[_name] = self; } - + return self; } @@ -181,160 +68,124 @@ var CPThemesByName = nil, return _name; } -- (void)setActiveClass:(Class)aClass +- (_CPThemeAttribute)_attributeWithName:(CPString)aName forClass:(CPString)aClass { - _activeClass = aClass; -} + var attributes = [_attributes objectForKey:aClass]; -- (Class)activeClass -{ - return _activeClass; -} + if (!attributes) + return nil; -- (id)valueForAttributeName:(CPString)anAttributeName inClass:(CPClass)aClass -{ - if (!aClass) - return nil; - - var className = [aClass className], - table = _classTable[className]; - - if (!table) - return nil; - - var value = table[anAttributeName]; - - if (!value) - return nil; - - return value; + return [attributes objectForKey:aName]; } - (void)takeThemeFromObject:(id)anObject { - var attributes = [anObject _themedAttributes], + var attributes = [anObject _themeAttributeDictionary], attributeName = nil, attributeNames = [attributes keyEnumerator], - objectClass = [anObject class]; - + objectThemeClass = [[anObject class] themeClass]; + while (attributeName = [attributeNames nextObject]) - [self addValue:[attributes objectForKey:attributeName] forAttributeName:attributeName inClass:objectClass]; + [self _recordAttribute:[attributes objectForKey:attributeName] forClass:objectThemeClass]; } -- (void)setDefaultValue:(id)aValue forAttributeName:(CPString)anAttributeName +- (void)_recordAttribute:(_CPThemeAttribute)anAttribute forClass:(CPString)aClass { - [self addValue:aValue forAttributeName:anAttributeName inClass:[self class]]; -} + var attributes = [_attributes objectForKey:aClass]; -- (void)addValue:(id)aValue forAttributeName:(CPString)anAttributeName inClass:(Class)aClass -{ - if (!aValue) - return; - - var className = [aClass className], - table = _classTable[className]; - - if (!table) + if (!attributes) { - var classNames = []; - - while (!table && (aClass !== CPThemeViewClass) && (aClass !== CPThemeWindowClass)) - { - classNames.push(className); - - aClass = [aClass superclass]; - className = [aClass className]; - table = _classTable[className]; - } - - if (!table) - table = _classTable[[[self class] className]]; - - var count = [classNames count]; - - while (count--) - { - className = classNames[count]; - - _classTable[className] = {}; - _classTable[className].prototype = table; - - table = _classTable[className]; - } + attributes = [CPDictionary dictionary]; + + [_attributes setObject:attributes forKey:aClass]; } - var existingAttribute = table[anAttributeName]; + var name = [anAttribute name], + existingAttribute = [attributes objectForKey:name]; if (existingAttribute) - table[anAttributeName] = [existingAttribute themedAttributeMergedWithThemedAttribute:aValue]; + [attributes setObject:[existingAttribute attributeMergedWithAttribute:anAttribute] forKey:name]; else - table[anAttributeName] = aValue; + [attributes setObject:anAttribute forKey:name]; } @end -var CPThemeNameKey = @"CPThemeNameKey", - CPThemeClassNamesArrayKey = @"CPThemeClassNamesArrayKey"; +var CPThemeNameKey = @"CPThemeNameKey", + CPThemeAttributesKey = @"CPThemeAttributesKey"; @implementation CPTheme (CPCoding) - (id)initWithCoder:(CPCoder)aCoder { self = [super init]; - - _name = [aCoder decodeObjectForKey:CPThemeNameKey]; - _classTable = {}; - - CPThemesByName[_name] = self; - + if (self) { - var classNamesArray = [aCoder decodeObjectForKey:CPThemeClassNamesArrayKey], - count = classNamesArray.length; + _name = [aCoder decodeObjectForKey:CPThemeNameKey]; + /* + var themeClasses = [aCoder decodeObjectForKey:CPThemeClassesKey], + count = themeClasses.length; + while (count--) { - var className = classNamesArray[count], - theClass = objj_getClass(className), - values = [aCoder decodeObjectForKey:className], - keys = [values allKeys], - keyCount = keys.length; - - while (keyCount--) + var themeClass = themeClasses[count], + attributes = [CPDictionary dictionary], + encodedAttributeNames = [aCoder decodeObjectForKey:@"$c" + themeClass], + encodedCount = encodedAttributeNames.length; + + while (encodedCount--) { - var key = keys[keyCount]; + var attributeName = encodedAttributeNames[encodedCount]; - [self addValue:[values objectForKey:key] forAttributeName:key inClass:theClass]; + [attributes setObject:CPThemeAttributeDecode(aCoder, attributeName, nil, nil, nil) forKey:attributeName]; } + + [_attributes setObject:attributes forKey:themeClass]; } + + */ + + _attributes = [aCoder decodeObjectForKey:CPThemeAttributesKey]; + + CPThemesByName[_name] = self; } - + return self; } - (void)encodeWithCoder:(CPCoder)aCoder { - var classNamesArray = []; + [aCoder encodeObject:_name forKey:CPThemeNameKey]; + /* - for (var className in _classTable) + var themeClasses = [], + classNames = [_attributes keyEnumerator], + className = nil; + + while (className = [classNames nextObject]) { - if (_classTable.hasOwnProperty(className)) + var attributeNames = [], + attributes = [_attributes objectForKey:className], + attribute = nil; + + while (attribute = [attributes nextObject]) + if (CPThemeAttributeEncode(aCoder, attribute)) + attributeNames.push([attribute name]); + + if (attributeNames.length > 0) { - var values = _classTable[className], - valuesDictionary = [CPDictionary dictionary]; + [aCoder encodeObject:attributeNames forKey:"$c" + themeClass]; - for (var key in values) - if (key !== "prototype" && values.hasOwnProperty(key)) - [valuesDictionary setObject:values[key] forKey:key]; - - [aCoder encodeObject:valuesDictionary forKey:className]; - - classNamesArray.push(className); + themeClasses.push(themeClass); } } - [aCoder encodeObject:_name forKey:CPThemeNameKey]; - [aCoder encodeObject:classNamesArray forKey:CPThemeClassNamesArrayKey]; + [aCoder encodeObject:themeClasses forKey:CPThemeClassesKey]; + */ + + [aCoder encodeObject:_attributes forKey:CPThemeAttributesKey]; } @end @@ -347,10 +198,10 @@ var CPThemeNameKey = @"CPThemeNameKey", - (id)initForReadingWithData:(CPData)data bundle:(CPBundle)aBundle { self = [super initForReadingWithData:data]; - + if (self) _bundle = aBundle; - + return self; } @@ -365,3 +216,337 @@ var CPThemeNameKey = @"CPThemeNameKey", } @end + +var CPThemeStates = {}, + CPThemeStateNames = {}, + CPThemeStateCount = 0; + +function CPThemeState(aStateName) +{ + var state = CPThemeStates[aStateName]; + + if (state === undefined) + { + if (aStateName.indexOf('+') === -1) + state = 1 << CPThemeStateCount++; + else + { + var state = 0, + states = aStateName.split('+'), + count = states.length; + + while (count--) + { + var stateName = states[count], + individualState = CPThemeStates[stateName]; + + if (individualState === undefined) + { + individualState = 1 << CPThemeStateCount++; + CPThemeStates[stateName] = individualState; + CPThemeStateNames[individualState] = stateName; + } + + state |= individualState; + } + } + + CPThemeStates[aStateName] = state; + CPThemeStateNames[state] = aStateName; + } + + return state; +} + +function CPThemeStateName(aState) +{ + var name = CPThemeStateNames[aState]; + + if (name !== undefined) + return name; + + if (!(aState & (aState - 1))) + return ""; + + var state = 1, + name = ""; + + for (; state < aState; state <<= 1) + if (aState & state) + name += (name.length === 0 ? '' : '+') + CPThemeStateNames[state]; + + CPThemeStateNames[aState] = name; + + return name; +} + +CPThemeStateNames[0] = "normal"; +CPThemeStateNormal = CPThemeStates["normal"] = 0; +CPThemeStateDisabled = CPThemeState("disabled"); +CPThemeStateHighlighted = CPThemeState("highlighted"); +CPThemeStateSelected = CPThemeState("selected"); +CPThemeStateBezeled = CPThemeState("bezeled"); +CPThemeStateBordered = CPThemeState("bordered"); +CPThemeStateEditable = CPThemeState("editable"); +CPThemeStateEditing = CPThemeState("editing"); +CPThemeStateVertical = CPThemeState("vertical"); +CPThemeStateDefault = CPThemeState("default"); +CPThemeStateCircular = CPThemeState("circular"); + +@implementation _CPThemeAttribute : CPObject +{ + CPString _name; + id _defaultValue; + CPDictionary _values; + + JSObject _cache; + CPThemeAttribute _parentAttribute; +} + +- (id)initWithName:(CPString)aName defaultValue:(id)aDefaultValue +{ + self = [super init]; + + if (self) + { + _cache = { }; + _name = aName; + _defaultValue = aDefaultValue; + _values = [CPDictionary dictionary]; + } + + return self; +} + +- (CPString)name +{ + return _name; +} + +- (id)defaultValue +{ + return _defaultValue; +} + +- (void)setValue:(id)aValue +{ + _cache = {}; + + if (aValue === undefined || aValue === nil) + _values = [CPDictionary dictionary]; + else + _values = [CPDictionary dictionaryWithObject:aValue forKey:String(CPThemeStateNormal)]; +} + +- (void)setValue:(id)aValue forState:(CPThemeState)aState +{ + _cache = { }; + + if ((aValue === undefined) || (aValue === nil)) + [_values removeObjectForKey:String(aState)]; + else + [_values setObject:aValue forKey:String(aState)]; +} + +- (id)value +{ + return [self valueForState:CPThemeStateNormal]; +} + +- (id)valueForState:(CPThemeState)aState +{ + var value = _cache[aState]; + + // This can be nil. + if (value !== undefined) + return value; + + value = [_values objectForKey:String(aState)]; + + // If we don't have a value, and we have a non-normal state... + if ((value === undefined || value === nil) && aState !== CPThemeStateNormal) + { + // If this is a composite state (not a power of 2), find the closest partial subset match. + if (aState & (aState - 1)) + { + var highestOneCount = 0, + states = [_values allKeys], + count = states.length; + + while (count--) + { + // states[count] is a string! + var state = Number(states[count]); + + // A & B = A iff A < B + if ((state & aState) === state) + { + var oneCount = cachedNumberOfOnes[state]; + + if (oneCount === undefined) + oneCount = numberOfOnes(state); + + if (oneCount > highestOneCount) + { + highestOneCount = oneCount; + value = [_values objectForKey:String(state)]; + } + } + } + } + + // Still don't have a value? OK, let's use the normal value. + if (value === undefined || value === nil) + value = [_values objectForKey:String(CPThemeStateNormal)]; + } + + if (value === undefined || value === nil) + value = [_parentAttribute valueForState:aState]; + + if (value === undefined || value === nil) + value = _defaultValue; + + _cache[aState] = value; + + return value; +} + +- (void)setParentAttribute:(CPThemeAttribute)anAttribute +{ + if (_parentAttribute === anAttribute) + return; + + _cache = { }; + _parentAttribute = anAttribute; +} + +- (CPThemeAttribute)attributeMergedWithAttribute:(_CPThemeAttribute)anAttribute +{ + var mergedAttribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue]; + + mergedAttribute._values = [_values copy]; + [mergedAttribute._values addEntriesFromDictionary:anAttribute._values]; + + return mergedAttribute; +} + +@end + +@implementation _CPThemeAttribute (CPCoding) + +- (id)initWithCoder:(CPCoder)aCoder +{ + self = [super init]; + + if (self) + { + _cache = {}; + + _name = [aCoder decodeObjectForKey:@"name"]; + _values = [CPDictionary dictionary]; + + var encodedValues = [aCoder decodeObjectForKey:@"values"], + keys = [encodedValues allKeys], + count = keys.length; + + while (count--) + { + var key = keys[count]; + + [_values setObject:[encodedValues objectForKey:key] forKey:CPThemeState(key)]; + } + } + + return self; +} + +- (void)encodeWithCoder:(CPCoder)aCoder +{ + var encodedValues = [CPDictionary dictionary], + keys = [_values allKeys], + count = keys.length; + + while (count--) + { + var key = keys[count]; + + [encodedValues setObject:[_values objectForKey:key] forKey:CPThemeStateName(Number(key))]; + } + + [aCoder encodeObject:_name forKey:@"name"]; + [aCoder encodeObject:encodedValues forKey:@"values"]; +} + +@end + +var cachedNumberOfOnes = [ 0 /*000000*/, 1 /*000001*/, 1 /*000010*/, 2 /*000011*/, 1 /*000100*/, 2 /*000101*/, 2 /*000110*/, + 3 /*000111*/, 1 /*001000*/, 2 /*001001*/, 2 /*001010*/, 3 /*001011*/, 2 /*001100*/, 3 /*001101*/, + 3 /*001110*/, 4 /*001111*/, 1 /*010000*/, 2 /*010001*/, 2 /*010010*/, 3 /*010011*/, 2 /*010100*/, + 3 /*010101*/, 3 /*010110*/, 4 /*010111*/, 2 /*011000*/, 3 /*011001*/, 3 /*011010*/, 4 /*011011*/, + 3 /*011100*/, 4 /*011101*/, 4 /*011110*/, 5 /*011111*/, 1 /*100000*/, 2 /*100001*/, 2 /*100010*/, + 3 /*100011*/, 2 /*100100*/, 3 /*100101*/, 3 /*100110*/, 4 /*100111*/, 2 /*101000*/, 3 /*101001*/, + 3 /*101010*/, 4 /*101011*/, 3 /*101100*/, 4 /*101101*/, 4 /*101110*/, 5 /*101111*/, 2 /*110000*/, + 3 /*110001*/, 3 /*110010*/, 4 /*110011*/, 3 /*110100*/, 4 /*110101*/, 4 /*110110*/, 5 /*110111*/, + 3 /*111000*/, 4 /*111001*/, 4 /*111010*/, 5 /*111011*/, 4 /*111100*/, 5 /*111101*/, 5 /*111110*/, + 6 /*111111*/ ]; + +var numberOfOnes = function(aNumber) +{ + var count = 0, + slot = aNumber; + + while (aNumber) + { + ++count; + aNumber &= (aNumber - 1); + } + + cachedNumberOfOnes[slot] = count; + + return count; +} + +numberOfOnes.displayName = "numberOfOnes"; + +function CPThemeAttributeEncode(aCoder, aThemeAttribute) +{ + var values = aThemeAttribute._values, + count = [values count]; + + if (count === 1) + { + var key = [values allKeys][0]; + + if (Number(key) === 0) + return [aCoder encodeObject:[values objectForKey:key] forKey:"$a" + [aThemeAttribute name]]; + } + + if (count >= 1) + [aCoder encodeObject:aThemeAttribute forKey:"$a" + [aThemeAttribute name]]; +} + +function CPThemeAttributeDecode(aCoder, anAttributeName, aDefaultValue, aTheme, aClass) +{ + var key = "$a" + anAttributeName; + + if (![aCoder containsValueForKey:key]) + var attribute = [[_CPThemeAttribute alloc] initWithName:anAttributeName defaultValue:aDefaultValue]; + + else + { + var attribute = [aCoder decodeObjectForKey:key]; + + if (!attribute.isa || ![attribute isKindOfClass:[_CPThemeAttribute class]]) + { + var themeAttribute = [[_CPThemeAttribute alloc] initWithName:anAttributeName defaultValue:aDefaultValue]; + + [themeAttribute setValue:attribute]; + + attribute = themeAttribute; + } + } + + [attribute setParentAttribute:[aTheme _attributeWithName:anAttributeName forClass:aClass]]; + + return attribute; +} diff --git a/AppKit/CPThemeBlend.j b/AppKit/CPThemeBlend.j new file mode 100644 index 000000000..b6f981e46 --- /dev/null +++ b/AppKit/CPThemeBlend.j @@ -0,0 +1,82 @@ +/* + * CPThemeBlend.j + * AppKit + * + * Created by Francisco Tolmasky. + * Copyright 2009, 280 North, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +@import + +@import +@import +@import + + +@implementation CPThemeBlend : CPObject +{ + CPBundle _bundle; + CPArray _themes @accessors(readonly); + id _loadDelegate; +} + +- (id)initWithContentsOfURL:(CPURL)aURL +{ + self = [super init]; + + if (self) + { + _bundle = [[CPBundle alloc] initWithPath:aURL + "/Info.plist"]; + } + + return self; +} + +- (void)loadWithDelegate:(id)aDelegate +{ + _loadDelegate = aDelegate; + + [_bundle loadWithDelegate:self]; +} + +- (void)bundleDidFinishLoading:(CPBundle)aBundle +{ + var paths = [_bundle objectForInfoDictionaryKey:@"CPBundleReplacedFiles"], + index = 0, + count = paths.length, + bundlePath = [_bundle bundlePath]; + + while (count--) + { + var path = paths[count]; + + if ([path pathExtension] === "keyedtheme") + { + var unarchiver = [[_CPThemeKeyedUnarchiver alloc] + initForReadingWithData:[CPData dataWithString:objj_files[bundlePath + '/' + path].contents] + bundle:_bundle]; + + [unarchiver decodeObjectForKey:@"root"]; + + [unarchiver finishDecoding]; + } + } + + [_loadDelegate blendDidFinishLoading:self]; +} + +@end diff --git a/AppKit/CPThemedAttribute.j b/AppKit/CPThemedAttribute.j deleted file mode 100644 index e25590412..000000000 --- a/AppKit/CPThemedAttribute.j +++ /dev/null @@ -1,267 +0,0 @@ - -@import - - -CPControlStateNormal = 0, -CPControlStateHighlighted = 1 << 0, -CPControlStateDisabled = 1 << 1, -CPControlStateSelected = 1 << 2, -CPControlStateDefault = 1 << 3, -CPControlStateBordered = 1 << 4, -CPControlStateBezeled = 1 << 5, -CPControlStateVertical = 1 << 6, -CPControlStateEditable = 1 << 7, -CPControlStateEditing = 1 << 8; -CPControlStateHorizontal = 1 << 9; -CPControlStateCircular = 1 << 10; - -var BIT_COUNT = [ 0 /*00000*/, 1 /*00001*/, 1 /*00010*/, 2 /*00011*/, 1 /*00100*/, 2 /*00101*/, 2 /*00110*/, 3 /*00111*/, - 1 /*01000*/, 2 /*01001*/, 2 /*01010*/, 3 /*01011*/, 2 /*01100*/, 3 /*01101*/, 3 /*01110*/, 4 /*01111*/, - 1 /*10000*/, 2 /*10001*/, 2 /*10010*/, 3 /*10011*/, 2 /*10100*/, 3 /*10101*/, 3 /*10110*/, 4 /*10111*/, - 2 /*11000*/, 3 /*11001*/, 3 /*11010*/, 4 /*11011*/, 3 /*11100*/, 4 /*11101*/, 4 /*11110*/, 5 /*11111*/], - bit_count = function(bits) - { - var count = 0; - - while (bits) - { - ++count; - bits &= (bits - 1); - } - - return count ; - } - -@implementation CPThemedAttribute : CPObject -{ - JSObject _cache; - - CPString _name; - id _defaultValue; - - CPTheme _theme; - Class _themedClass; - - CPDictionary _values; - CPThemedAttribute _attributeFromTheme; -} - -- (id)initWithName:(CPString)aName defaultValue:(id)aDefaultValue theme:(CPTheme)aTheme class:(Class)aClass -{ - self = [super init]; - - if (self) - { - _cache = {}; - - _name = aName; - - _defaultValue = aDefaultValue; - - _theme = aTheme; - _themedClass = aClass; - - _values = [CPDictionary dictionary]; - _attributeFromTheme = [_theme valueForAttributeName:_name inClass:_themedClass]; - } - - return self; -} - -- (void)setName:(CPString)aName -{ - _name = aName; -} - -- (CPString)name -{ - return _name; -} - -- (void)setDefaultValue:(id)aValue -{ - _cache = {}; - _defaultValue = aValue; -} - -- (void)setTheme:(CPTheme)aTheme -{ - if (_theme === aTheme) - return; - - _cache = {}; - _theme = aTheme; - _attributeFromTheme = [_theme valueForAttributeName:_name inClass:_themedClass]; -} - -- (void)setThemedClass:(Class)aClass -{ - if (_themedClass === aClass) - return; - - _cache = {}; - _themedClass = aClass; - _attributeFromTheme = [_theme valueForAttributeName:_name inClass:_themedClass]; -} - -- (void)setValue:(id)aValue -{ - _cache = {}; - - if (aValue === undefined || aValue === nil) - _values = [CPDictionary dictionary]; - else - _values = [CPDictionary dictionaryWithObject:aValue forKey:String(CPControlStateNormal)]; -} - -- (id)value -{ - return [self valueForControlState:CPControlStateNormal]; -} - -- (void)setValue:(id)aValue forControlState:(CPControlState)aState -{ - //delete _cache[aState]; - _cache = {}; - - if ((aValue === undefined) || (aValue === nil)) - [_values removeObjectForKey:String(aState)]; - else - [_values setObject:aValue forKey:String(aState)]; -} - -- (id)valueForControlState:(CPControlState)aState -{ - var value = _cache[aState]; - - // This can be nil. - if (value !== undefined) - return value; - - value = [_values objectForKey:String(aState)]; - - // If we don't have a value, and we have a non-normal state... - if ((value === undefined || value === nil) && aState > 0) - { - // If this is a composite state, find the closest partial subset match. - if (aState & (aState - 1)) - { - var highestBitCount = 0, - states = [_values allKeys], - count = states.length; - - while (count--) - { - // state is a string! - state = Number(states[count]); - - // A & B = A iff A < B - if ((state & aState) === state) - { - var bitCount = (state < BIT_COUNT.length) ? BIT_COUNT[state] : bit_count(state); - - if (bitCount > highestBitCount) - { - highestBitCount = bitCount; - value = [_values objectForKey:String(state)]; - } - } - } - } - - // Still don't have a value? OK, let's use the normal value. - if (value === undefined || value === nil) - value = [_values objectForKey:String(CPControlStateNormal)]; - } - - if (value === undefined || value === nil) - value = [_attributeFromTheme valueForControlState:aState]; - - if (value === undefined || value === nil) - value = _defaultValue; - - _cache[aState] = value; - - return value; -} - -- (CPThemedAttribute)themedAttributeMergedWithThemedAttribute:(CPThemedAttribute)aThemedAttribute -{ - var mergedAttribute = CPThemedAttributeMake(_name, _defaultValue, _theme, _themedClass); - - mergedAttribute._values = [_values copy]; - [mergedAttribute._values addEntriesFromDictionary:aThemedAttribute._values]; - - return mergedAttribute; -} - -- (id)initWithCoder:(CPCoder)aCoder -{ - self = [super init]; - - if (self) - { - _cache = {}; - _values = [aCoder decodeObjectForKey:@"values"]; - } - - return self; -} - -- (void)encodeWithCoder:(CPCoder)aCoder -{ - [aCoder encodeObject:_values forKey:@"values"]; -} - -@end - -function CPThemedAttributeMake(aName, aDefaultValue, aTheme, aClass) -{ - return [[CPThemedAttribute alloc] initWithName:aName defaultValue:aDefaultValue theme:aTheme class:aClass]; -} - -function CPThemedAttributeEncode(aCoder, aThemedAttribute) -{ - var values = aThemedAttribute._values, - count = [values count]; - - if (count === 1) - { - var key = [values allKeys][0]; - - if (Number(key) === 0) - return [aCoder encodeObject:[values objectForKey:key] forKey:"$a" + [aThemedAttribute name]]; - } - - if (count >= 1) - [aCoder encodeObject:aThemedAttribute forKey:"$a" + [aThemedAttribute name]]; -} - -function CPThemedAttributeDecode(aCoder, anAttributeName, aDefaultValue, aTheme, aClass) -{ - var key = "$a" + anAttributeName; - - if (![aCoder containsValueForKey:key]) - return CPThemedAttributeMake(anAttributeName, aDefaultValue, aTheme, aClass); - - var attribute = [aCoder decodeObjectForKey:key]; - - if (!attribute.isa || ![attribute isKindOfClass:[CPThemedAttribute class]]) - { - var themedAttribute = CPThemedAttributeMake(anAttributeName, aDefaultValue, aTheme, aClass); - - [themedAttribute setValue:attribute]; - - attribute = themedAttribute; - } - - else - { - [attribute setName:anAttributeName]; - [attribute setDefaultValue:aDefaultValue]; - [attribute setTheme:aTheme]; - [attribute setThemedClass:aClass]; - } - - return attribute; -} diff --git a/AppKit/CPView.j b/AppKit/CPView.j index 894cb547b..71237bacd 100644 --- a/AppKit/CPView.j +++ b/AppKit/CPView.j @@ -85,11 +85,8 @@ CPViewMaxYMargin = 32; CPViewBoundsDidChangeNotification = @"CPViewBoundsDidChangeNotification"; CPViewFrameDidChangeNotification = @"CPViewFrameDidChangeNotification"; -var _DOMOriginUpdateMask = 1 << 0, - _DOMSizeUpdateMask = 1 << 1; - -var _CPViewNotificationCenter = nil, - _CachedThemedAttributes = nil; +var CachedNotificationCenter = nil, + CachedThemeAttributes = nil; #if PLATFORM(DOM) var DOMElementPrototype = nil, @@ -178,7 +175,8 @@ var DOMElementPrototype = nil, // Theming Support CPTheme _theme; - JSObject _themedAttributes; + JSObject _themeAttributes; + unsigned _themeState; // Key View Support CPView _nextKeyView; @@ -191,7 +189,7 @@ var DOMElementPrototype = nil, */ + (void)initialize { - if (self != [CPView class]) + if (self !== [CPView class]) return; #if PLATFORM(DOM) @@ -205,7 +203,7 @@ var DOMElementPrototype = nil, style.zIndex = 0; #endif - _CPViewNotificationCenter = [CPNotificationCenter defaultCenter]; + CachedNotificationCenter = [CPNotificationCenter defaultCenter]; } - (id)init @@ -255,9 +253,9 @@ var DOMElementPrototype = nil, #endif _theme = [CPTheme defaultTheme]; - _themedAttributes = {}; - - [self _loadThemedAttributes]; + _themeState = CPThemeStateNormal; + + [self _loadThemeAttributes]; } return self; @@ -588,7 +586,7 @@ var DOMElementPrototype = nil, _inhibitFrameAndBoundsChangedNotifications = NO; if (_postsFrameChangedNotifications) - [_CPViewNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self]; + [CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self]; } /*! @@ -639,7 +637,7 @@ var DOMElementPrototype = nil, origin.y = aPoint.y; if (_postsFrameChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications) - [_CPViewNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self]; + [CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self]; #if PLATFORM(DOM) CPDOMDisplayServerSetStyleLeftTop(_DOMElement, _superview ? _superview._boundsTransform : NULL, origin.x, origin.y); @@ -717,7 +715,7 @@ var DOMElementPrototype = nil, #endif if (_postsFrameChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications) - [_CPViewNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self]; + [CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self]; } /*! @@ -738,7 +736,7 @@ var DOMElementPrototype = nil, _inhibitFrameAndBoundsChangedNotifications = NO; if (_postsBoundsChangedNotifications) - [_CPViewNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self]; + [CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self]; } /*! @@ -790,7 +788,7 @@ var DOMElementPrototype = nil, #endif if (_postsBoundsChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications) - [_CPViewNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self]; + [CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self]; } /*! @@ -828,7 +826,7 @@ var DOMElementPrototype = nil, } if (_postsBoundsChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications) - [_CPViewNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self]; + [CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self]; } @@ -1358,7 +1356,7 @@ setFrameOrigin: _postsFrameChangedNotifications = shouldPostFrameChangedNotifications; if (_postsFrameChangedNotifications) - [_CPViewNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self]; + [CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self]; } /*! @@ -1389,7 +1387,7 @@ setBoundsOrigin: _postsBoundsChangedNotifications = shouldPostBoundsChangedNotifications; if (_postsBoundsChangedNotifications) - [_CPViewNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self]; + [CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self]; } /*! @@ -1930,67 +1928,118 @@ setBoundsOrigin: @end @implementation CPView (Theming) +#pragma mark Theme States -+ (CPDictionary)themedAttributes +- (BOOL)hasThemeState:(CPThemeState)aState +{ + return !!(_themeState & ((typeof aState === "string") ? CPThemeState(aState) : aState)); +} + +- (BOOL)setThemeState:(CPThemeState)aState +{ + var newState = (typeof aState === "string") ? CPThemeState(aState) : aState; + + if (_themeState & newState) + return NO; + + _themeState |= newState; + + [self setNeedsLayout]; + [self setNeedsDisplay:YES]; + + return YES; +} + +- (BOOL)unsetThemeState:(CPThemeState)aState +{ + var newState = ((typeof aState === "string") ? CPThemeState(aState) : aState); + + if (!(_themeState & newState)) + return NO; + + _themeState &= ~newState; + + [self setNeedsLayout]; + [self setNeedsDisplay:YES]; + + return YES; +} + +#pragma mark Theme Attributes + ++ (CPString)themeClass { return nil; } -+ (CPArray)_themedAttributes ++ (CPDictionary)themeAttributes { - if (!_CachedThemedAttributes) - _CachedThemedAttributes = {}; + return nil; +} + ++ (CPArray)_themeAttributes +{ + if (!CachedThemeAttributes) + CachedThemeAttributes = {}; var theClass = [self class], CPViewClass = [CPView class], attributes = []; - - while (theClass && theClass !== CPViewClass) + + for (; theClass && theClass !== CPViewClass; theClass = [theClass superclass]) { - var cachedAttributes = _CachedThemedAttributes[class_getName(theClass)]; - + var cachedAttributes = CachedThemeAttributes[class_getName(theClass)]; + if (cachedAttributes) { attributes = attributes.length ? attributes.concat(cachedAttributes) : attributes; - _CachedThemedAttributes[[self className]] = attributes; - + CachedThemeAttributes[[self className]] = attributes; + break; } + + var attributeDictionary = [theClass themeAttributes]; - var attributeDictionary = [theClass themedAttributes]; - - if (attributeDictionary) + if (!attributeDictionary) + continue; + + var attributeKeys = [attributeDictionary allKeys], + attributeCount = attributeKeys.length; + + while (attributeCount--) { - var attributeKeys = [attributeDictionary allKeys], - attributeCount = attributeKeys.length; - - while (attributeCount--) - { - var attributeName = attributeKeys[attributeCount]; - - attributes.push([attributeDictionary objectForKey:attributeName]); - attributes.push(attributeName); - } + var attributeName = attributeKeys[attributeCount]; + + attributes.push([attributeDictionary objectForKey:attributeName]); + attributes.push(attributeName); } - - theClass = [theClass superclass]; } - + return attributes; } -- (void)_loadThemedAttributes +- (void)_loadThemeAttributes { - var theme = [self theme], - theClass = [self class], - attributes = [theClass _themedAttributes]; + var theClass = [self class], + attributes = [theClass _themeAttributes], count = attributes.length; + + if (!count) + return; + + var theme = [self theme], + themeClass = [theClass themeClass]; + + _themeAttributes = {}; while (count--) { - var attributeName = attributes[count--]; + var attributeName = attributes[count--], + attribute = [[_CPThemeAttribute alloc] initWithName:attributeName defaultValue:attributes[count]]; + + [attribute setParentAttribute:[theme _attributeWithName:attributeName forClass:themeClass]]; - _themedAttributes[attributeName] = CPThemedAttributeMake(attributeName, attributes[count], theme, theClass); + _themeAttributes[attributeName] = attribute; } } @@ -2011,73 +2060,87 @@ setBoundsOrigin: - (void)viewDidChangeTheme { - var theme = [self theme]; - - for (var attributeName in _themedAttributes) - if (_themedAttributes.hasOwnProperty(attributeName)) - [_themedAttributes[attributeName] setTheme:theme]; + if (!_themeAttributes) + return; + + var theme = [self theme], + themeClass = [[self class] themeClass]; + + for (var attributeName in _themeAttributes) + if (_themeAttributes.hasOwnProperty(attributeName)) + [_themeAttributes[attributeName] setParentAttribute:[theme _attributeWithName:attributeName forClass:themeClass]]; } -- (CPDictionary)_themedAttributes +- (CPDictionary)_themeAttributeDictionary { var dictionary = [CPDictionary dictionary]; - - for (var attributeName in _themedAttributes) - if (_themedAttributes.hasOwnProperty(attributeName)) - [dictionary setObject:_themedAttributes[attributeName] forKey:attributeName]; - + + if (_themeAttributes) + { + var theme = [self theme]; + + for (var attributeName in _themeAttributes) + if (_themeAttributes.hasOwnProperty(attributeName)) + [dictionary setObject:_themeAttributes[attributeName] forKey:attributeName]; + } + return dictionary; } -- (void)setValue:(id)aValue forThemedAttributeName:(CPString)aName inControlState:(CPControlState)aControlState +- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(CPThemeState)aState { - var attribute = _themedAttributes[aName]; + if (!_themeAttributes || !_themeAttributes[aName]) + [CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"]; - if (!attribute) - return; + var currentValue = [self currentValueForThemeAttribute:aName]; - var currentValue = [self currentValueForThemedAttributeName:aName]; + [_themeAttributes[aName] setValue:aValue forState:aState]; - [attribute setValue:aValue forControlState:aControlState]; - - if ([self currentValueForThemedAttributeName:aName] === currentValue) + if ([self currentValueForThemeAttribute:aName] === currentValue) return; [self setNeedsDisplay:YES]; [self setNeedsLayout]; } -- (void)setValue:(id)aValue forThemedAttributeName:(CPString)aName +- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName { - var attribute = _themedAttributes[aName]; + if (!_themeAttributes || !_themeAttributes[aName]) + [CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"]; - if (!attribute) - return; + var currentValue = [self currentValueForThemeAttribute:aName]; - var currentValue = [self currentValueForThemedAttributeName:aName]; + [_themeAttributes[aName] setValue:aValue]; - [attribute setValue:aValue]; - - if ([self currentValueForThemedAttributeName:aName] === currentValue) + if ([self currentValueForThemeAttribute:aName] === currentValue) return; [self setNeedsDisplay:YES]; [self setNeedsLayout]; } -- (id)valueForThemedAttributeName:(CPString)aName inControlState:(CPControlState)aControlState +- (id)valueForThemeAttribute:(CPString)aName inState:(CPThemeState)aState { - return [_themedAttributes[aName] valueForControlState:aControlState]; + if (!_themeAttributes || !_themeAttributes[aName]) + [CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"]; + + return [_themeAttributes[aName] valueForState:aState]; } -- (id)valueForThemedAttributeName:(CPString)aName +- (id)valueForThemeAttribute:(CPString)aName { - return [_themedAttributes[aName] value]; + if (!_themeAttributes || !_themeAttributes[aName]) + [CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"]; + + return [_themeAttributes[aName] value]; } -- (void)currentValueForThemedAttributeName:(CPString)aName +- (void)currentValueForThemeAttribute:(CPString)aName { - return [_themedAttributes[aName] valueForControlState:_controlState];//[self controlStateForThemedAttributeName:aName]]; + if (!_themeAttributes || !_themeAttributes[aName]) + [CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"]; + + return [_themeAttributes[aName] valueForState:_themeState]; } @end @@ -2093,6 +2156,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask", CPViewSubviewsKey = @"CPViewSubviewsKey", CPViewSuperviewKey = @"CPViewSuperviewKey", CPViewTagKey = @"CPViewTagKey", + CPViewThemeStateKey = @"CPViewThemeStateKey", CPViewWindowKey = @"CPViewWindowKey", CPViewNextKeyViewKey = @"CPViewNextKeyViewKey", CPViewPreviousKeyViewKey = @"CPViewPreviousKeyViewKey"; @@ -2160,17 +2224,19 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask", [self setBackgroundColor:[aCoder decodeObjectForKey:CPViewBackgroundColorKey]]; _theme = [CPTheme defaultTheme]; - _themedAttributes = {}; - + _themeState = [aCoder decodeIntForKey:CPViewThemeStateKey]; + _themeAttributes = {}; + var theClass = [self class], - attributes = [theClass _themedAttributes], + themeClass = [theClass themeClass], + attributes = [theClass _themeAttributes], count = attributes.length; - + while (count--) { var attributeName = attributes[count--]; - - _themedAttributes[attributeName] = CPThemedAttributeDecode(aCoder, attributeName, attributes[count], _theme, theClass); + + _themeAttributes[attributeName] = CPThemeAttributeDecode(aCoder, attributeName, attributes[count], _theme, themeClass); } [self setNeedsDisplay:YES]; @@ -2209,9 +2275,11 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask", [aCoder encodeConditionalObject:[self nextKeyView] forKey:CPViewNextKeyViewKey]; [aCoder encodeConditionalObject:[self previousKeyView] forKey:CPViewPreviousKeyViewKey]; - for (var attributeName in _themedAttributes) - if (_themedAttributes.hasOwnProperty(attributeName)) - CPThemedAttributeEncode(aCoder, _themedAttributes[attributeName]); + [aCoder encodeInt:_themeState forKey:CPViewThemeStateKey]; + + for (var attributeName in _themeAttributes) + if (_themeAttributes.hasOwnProperty(attributeName)) + CPThemeAttributeEncode(aCoder, _themeAttributes[attributeName]); } @end diff --git a/AppKit/Themes/Aristo/Resources/popup-bezel-right-pullsdown.png b/AppKit/Themes/Aristo/Resources/popup-bezel-right-pullsdown.png index a17bed227..6694b670a 100644 Binary files a/AppKit/Themes/Aristo/Resources/popup-bezel-right-pullsdown.png and b/AppKit/Themes/Aristo/Resources/popup-bezel-right-pullsdown.png differ diff --git a/AppKit/Themes/Aristo/Resources/scroller-horizontal-knob-left.png b/AppKit/Themes/Aristo/Resources/scroller-horizontal-knob-left.png index 8b417a826..48b0753a6 100644 Binary files a/AppKit/Themes/Aristo/Resources/scroller-horizontal-knob-left.png and b/AppKit/Themes/Aristo/Resources/scroller-horizontal-knob-left.png differ diff --git a/AppKit/Themes/Aristo/Resources/scroller-right-arrow.png b/AppKit/Themes/Aristo/Resources/scroller-right-arrow.png index 3ae19c5eb..9d5c64cec 100644 Binary files a/AppKit/Themes/Aristo/Resources/scroller-right-arrow.png and b/AppKit/Themes/Aristo/Resources/scroller-right-arrow.png differ diff --git a/AppKit/Themes/Aristo/ThemeDescriptors.j b/AppKit/Themes/Aristo/ThemeDescriptors.j index 7a2c4eec0..9fb8d5fbe 100644 --- a/AppKit/Themes/Aristo/ThemeDescriptors.j +++ b/AppKit/Themes/Aristo/ThemeDescriptors.j @@ -7,7 +7,7 @@ */ @import -@import + @implementation AristoThemeDescriptor : CPObject { @@ -21,34 +21,34 @@ + (CPScroller)themedVerticalScroller { var scroller = [[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, 17.0, 170.0)], - trackColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-vertical-track.png" size:CGSizeMake(17.0, 1.0)]), - disabledTrackColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-vertical-track-disabled.png" size:CGSizeMake(17.0, 1.0)]); + trackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-vertical-track.png" size:CGSizeMake(17.0, 1.0)]), + disabledTrackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-vertical-track-disabled.png" size:CGSizeMake(17.0, 1.0)]); - [scroller setValue:CGSizeMake(15.0, 19.0) forThemedAttributeName:@"minimum-knob-size" inControlState:CPControlStateVertical]; + [scroller setValue:CGSizeMake(15.0, 19.0) forThemeAttribute:@"minimum-knob-size" inState:CPThemeStateVertical]; - [scroller setValue:CGInsetMake(9.0, 9.0, 9.0, 9.0) forThemedAttributeName:@"track-overlap-inset" inControlState:CPControlStateVertical]; - [scroller setValue:trackColor forThemedAttributeName:@"knob-slot-color" inControlState:CPControlStateVertical]; - [scroller setValue:disabledTrackColor forThemedAttributeName:@"knob-slot-color" inControlState:CPControlStateVertical | CPControlStateDisabled]; + [scroller setValue:CGInsetMake(9.0, 9.0, 9.0, 9.0) forThemeAttribute:@"track-overlap-inset" inState:CPThemeStateVertical]; + [scroller setValue:trackColor forThemeAttribute:@"knob-slot-color" inState:CPThemeStateVertical]; + [scroller setValue:disabledTrackColor forThemeAttribute:@"knob-slot-color" inState:CPThemeStateVertical | CPThemeStateDisabled]; - var arrowColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-up-arrow.png" size:CGSizeMake(17.0, 30.0)]), - highlightedArrowColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-up-arrow-highlighted.png" size:CGSizeMake(17.0, 30.0)]), - disabledArrowColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-up-arrow-disabled.png" size:CGSizeMake(17.0, 30.0)]); + var arrowColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-up-arrow.png" size:CGSizeMake(17.0, 30.0)]), + highlightedArrowColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-up-arrow-highlighted.png" size:CGSizeMake(17.0, 30.0)]), + disabledArrowColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-up-arrow-disabled.png" size:CGSizeMake(17.0, 30.0)]); - [scroller setValue:CGSizeMake(17.0, 30.0) forThemedAttributeName:@"decrement-line-size" inControlState:CPControlStateVertical]; - [scroller setValue:arrowColor forThemedAttributeName:@"decrement-line-color" inControlState:CPControlStateVertical]; - [scroller setValue:highlightedArrowColor forThemedAttributeName:@"decrement-line-color" inControlState:CPControlStateVertical | CPControlStateHighlighted], - [scroller setValue:disabledArrowColor forThemedAttributeName:@"decrement-line-color" inControlState:CPControlStateVertical | CPControlStateDisabled]; + [scroller setValue:CGSizeMake(17.0, 30.0) forThemeAttribute:@"decrement-line-size" inState:CPThemeStateVertical]; + [scroller setValue:arrowColor forThemeAttribute:@"decrement-line-color" inState:CPThemeStateVertical]; + [scroller setValue:highlightedArrowColor forThemeAttribute:@"decrement-line-color" inState:CPThemeStateVertical | CPThemeStateHighlighted], + [scroller setValue:disabledArrowColor forThemeAttribute:@"decrement-line-color" inState:CPThemeStateVertical | CPThemeStateDisabled]; - var arrowColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-down-arrow.png" size:CGSizeMake(17.0, 30.0)]), - highlightedArrowColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-down-arrow-highlighted.png" size:CGSizeMake(17.0, 30.0)]), - disabledArrowColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-down-arrow-disabled.png" size:CGSizeMake(17.0, 30.0)]); + var arrowColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-down-arrow.png" size:CGSizeMake(17.0, 30.0)]), + highlightedArrowColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-down-arrow-highlighted.png" size:CGSizeMake(17.0, 30.0)]), + disabledArrowColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-down-arrow-disabled.png" size:CGSizeMake(17.0, 30.0)]); - [scroller setValue:CGSizeMake(17.0, 30.0) forThemedAttributeName:@"increment-line-size"]; - [scroller setValue:arrowColor forThemedAttributeName:@"increment-line-color" inControlState:CPControlStateVertical]; - [scroller setValue:highlightedArrowColor forThemedAttributeName:@"increment-line-color" inControlState:CPControlStateVertical | CPControlStateHighlighted]; - [scroller setValue:disabledArrowColor forThemedAttributeName:@"increment-line-color" inControlState:CPControlStateVertical | CPControlStateDisabled]; + [scroller setValue:CGSizeMake(17.0, 30.0) forThemeAttribute:@"increment-line-size"]; + [scroller setValue:arrowColor forThemeAttribute:@"increment-line-color" inState:CPThemeStateVertical]; + [scroller setValue:highlightedArrowColor forThemeAttribute:@"increment-line-color" inState:CPThemeStateVertical | CPThemeStateHighlighted]; + [scroller setValue:disabledArrowColor forThemeAttribute:@"increment-line-color" inState:CPThemeStateVertical | CPThemeStateDisabled]; - var knobColor = PatterColor([[CPThreePartImage alloc] initWithImageSlices: + var knobColor = PatternColor([[CPThreePartImage alloc] initWithImageSlices: [ [_CPCibCustomResource imageResourceWithName:"scroller-vertical-knob-top.png" size:CGSizeMake(15.0, 8.0)], [_CPCibCustomResource imageResourceWithName:"scroller-vertical-knob-center.png" size:CGSizeMake(15.0, 1.0)], @@ -56,7 +56,7 @@ ] isVertical:YES]); - [scroller setValue:knobColor forThemedAttributeName:@"knob-color" inControlState:CPControlStateVertical]; + [scroller setValue:knobColor forThemeAttribute:@"knob-color" inState:CPThemeStateVertical]; [scroller setFloatValue:0.1 knobProportion:0.5]; @@ -64,36 +64,36 @@ } + (CPScroller)themedHorizontalScroller -{CPControlStateHorizontal = 0; +{ var scroller = [[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, 170.0, 17.0)], - trackColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-horizontal-track.png" size:CGSizeMake(1.0, 17.0)]), - disabledTrackColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-vertical-track-disabled.png" size:CGSizeMake(17.0, 1.0)]); + trackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-horizontal-track.png" size:CGSizeMake(1.0, 17.0)]), + disabledTrackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-vertical-track-disabled.png" size:CGSizeMake(17.0, 1.0)]); [scroller setBackgroundColor:[CPColor blueColor]]; - [scroller setValue:CGSizeMake(19.0, 15.0) forThemedAttributeName:@"minimum-knob-size" inControlState:CPControlStateHorizontal]; + [scroller setValue:CGSizeMake(19.0, 15.0) forThemeAttribute:@"minimum-knob-size"]; - [scroller setValue:CGInsetMake(9.0, 9.0, 9.0, 9.0) forThemedAttributeName:@"track-overlap-inset" inControlState:CPControlStateHorizontal]; - [scroller setValue:trackColor forThemedAttributeName:@"knob-slot-color" inControlState:CPControlStateHorizontal]; - [scroller setValue:disabledTrackColor forThemedAttributeName:@"knob-slot-color" inControlState:CPControlStateHorizontal | CPControlStateDisabled]; + [scroller setValue:CGInsetMake(9.0, 9.0, 9.0, 9.0) forThemeAttribute:@"track-overlap-inset" ]; + [scroller setValue:trackColor forThemeAttribute:@"knob-slot-color"]; + [scroller setValue:disabledTrackColor forThemeAttribute:@"knob-slot-color" inState:CPThemeStateDisabled]; - var arrowColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-left-arrow.png" size:CGSizeMake(32.0, 17.0)]), - highlightedArrowColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-up-arrow-highlighted.png" size:CGSizeMake(17.0, 30.0)]), - disabledArrowColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-up-arrow-disabled.png" size:CGSizeMake(17.0, 30.0)]); + var arrowColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-left-arrow.png" size:CGSizeMake(32.0, 17.0)]), + highlightedArrowColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-left-arrow-highlighted.png" size:CGSizeMake(17.0, 30.0)]), + disabledArrowColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-left-arrow-disabled.png" size:CGSizeMake(17.0, 30.0)]); - [scroller setValue:CGSizeMake(32.0, 17.0) forThemedAttributeName:@"decrement-line-size" inControlState:CPControlStateHorizontal]; - [scroller setValue:arrowColor forThemedAttributeName:@"decrement-line-color" inControlState:CPControlStateHorizontal]; - [scroller setValue:highlightedArrowColor forThemedAttributeName:@"decrement-line-color" inControlState:CPControlStateHorizontal | CPControlStateHighlighted], - [scroller setValue:disabledArrowColor forThemedAttributeName:@"decrement-line-color" inControlState:CPControlStateHorizontal | CPControlStateDisabled]; + [scroller setValue:CGSizeMake(32.0, 17.0) forThemeAttribute:@"decrement-line-size"]; + [scroller setValue:arrowColor forThemeAttribute:@"decrement-line-color"]; + [scroller setValue:highlightedArrowColor forThemeAttribute:@"decrement-line-color" inState:CPThemeStateHighlighted], + [scroller setValue:disabledArrowColor forThemeAttribute:@"decrement-line-color" inState:CPThemeStateDisabled]; - var arrowColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-right-arrow.png" size:CGSizeMake(31.0, 17.0)]), - highlightedArrowColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-down-arrow-highlighted.png" size:CGSizeMake(17.0, 30.0)]), - disabledArrowColor = PatterColor([_CPCibCustomResource imageResourceWithName:"scroller-down-arrow-disabled.png" size:CGSizeMake(17.0, 30.0)]); + var arrowColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-right-arrow.png" size:CGSizeMake(31.0, 17.0)]), + highlightedArrowColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-right-arrow-highlighted.png" size:CGSizeMake(17.0, 30.0)]), + disabledArrowColor = PatternColor([_CPCibCustomResource imageResourceWithName:"scroller-right-arrow-disabled.png" size:CGSizeMake(17.0, 30.0)]); - [scroller setValue:CGSizeMake(31.0, 17.0) forThemedAttributeName:@"increment-line-size"]; - [scroller setValue:arrowColor forThemedAttributeName:@"increment-line-color" inControlState:CPControlStateHorizontal]; - [scroller setValue:highlightedArrowColor forThemedAttributeName:@"increment-line-color" inControlState:CPControlStateHorizontal | CPControlStateHighlighted]; - [scroller setValue:disabledArrowColor forThemedAttributeName:@"increment-line-color" inControlState:CPControlStateHorizontal | CPControlStateDisabled]; + [scroller setValue:CGSizeMake(31.0, 17.0) forThemeAttribute:@"increment-line-size"]; + [scroller setValue:arrowColor forThemeAttribute:@"increment-line-color"]; + [scroller setValue:highlightedArrowColor forThemeAttribute:@"increment-line-color" inState:CPThemeStateHighlighted]; + [scroller setValue:disabledArrowColor forThemeAttribute:@"increment-line-color" inState:CPThemeStateDisabled]; - var knobColor = PatterColor([[CPThreePartImage alloc] initWithImageSlices: + var knobColor = PatternColor([[CPThreePartImage alloc] initWithImageSlices: [ [_CPCibCustomResource imageResourceWithName:"scroller-horizontal-knob-left.png" size:CGSizeMake(11.0, 15.0)], [_CPCibCustomResource imageResourceWithName:"scroller-horizontal-knob-center.png" size:CGSizeMake(1.0, 15.0)], @@ -101,7 +101,7 @@ ] isVertical:NO]); - [scroller setValue:knobColor forThemedAttributeName:@"knob-color" inControlState:CPControlStateHorizontal]; + [scroller setValue:knobColor forThemeAttribute:@"knob-color"]; [scroller setFloatValue:0.1 knobProportion:0.5]; @@ -139,17 +139,15 @@ [textfield setBezeled:YES]; - [textfield setValue:bezelColor forThemedAttributeName:@"bezel-color" inControlState:CPControlStateBezeled]; - [textfield setValue:bezelFocusedColor forThemedAttributeName:@"bezel-color" inControlState:CPControlStateBezeled|CPControlStateEditing]; + [textfield setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBezeled]; + [textfield setValue:bezelFocusedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBezeled|CPThemeStateEditing]; + [textfield setValue:[CPFont systemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateBezeled]; + [textfield setValue:CGInsetMake(9.0, 8.0, 5.0, 7.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBezeled]; - [textfield setValue:[CPFont systemFontOfSize:12.0] forThemedAttributeName:@"font"]; + [textfield setValue:CGInsetMake(4.0, 4.0, 3.0, 4.0) forThemeAttribute:@"bezel-inset" inState:CPThemeStateBezeled]; + [textfield setValue:CGInsetMake(0.0, 0.0, 0.0, 0.0) forThemeAttribute:@"bezel-inset" inState:CPThemeStateBezeled|CPThemeStateEditing]; - [textfield setValue:CGInsetMake(9.0, 8.0, 5.0, 7.0) forThemedAttributeName:@"content-inset" inControlState:CPControlStateBezeled]; - - [textfield setValue:CGInsetMake(4.0, 4.0, 3.0, 4.0) forThemedAttributeName:@"bezel-inset" inControlState:CPControlStateBezeled]; - [textfield setValue:CGInsetMake(0.0, 0.0, 0.0, 0.0) forThemedAttributeName:@"bezel-inset" inControlState:CPControlStateBezeled|CPControlStateEditing]; - - [textfield setValue:[CPColor colorWithCalibratedRed:189.0 / 255.0 green:199.0 / 255.0 blue:211.0 / 255.0 alpha:1.0] forThemedAttributeName:@"text-color" inControlState:CPTextFieldStatePlaceholder]; + [textfield setValue:[CPColor colorWithCalibratedRed:189.0 / 255.0 green:199.0 / 255.0 blue:211.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color" inState:CPTextFieldStatePlaceholder]; [textfield setPlaceholderString:"cheese cheese"]; [textfield setStringValue:""]; @@ -178,16 +176,16 @@ [textfield setBezeled:YES]; [textfield setBezelStyle:CPTextFieldRoundedBezel]; - [textfield setValue:bezelColor forThemedAttributeName:@"bezel-color" inControlState:CPControlStateBezeled | CPTextFieldStateRounded]; - [textfield setValue:bezelFocusedColor forThemedAttributeName:@"bezel-color" inControlState:CPControlStateBezeled | CPTextFieldStateRounded | CPControlStateEditing]; + [textfield setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBezeled | CPTextFieldStateRounded]; + [textfield setValue:bezelFocusedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBezeled | CPTextFieldStateRounded | CPThemeStateEditing]; - [textfield setValue:[CPFont systemFontOfSize:12.0] forThemedAttributeName:@"font"]; - [textfield setValue:CGInsetMake(9.0, 14.0, 6.0, 14.0) forThemedAttributeName:@"content-inset" inControlState:CPControlStateBezeled | CPTextFieldStateRounded]; + [textfield setValue:[CPFont systemFontOfSize:12.0] forThemeAttribute:@"font"]; + [textfield setValue:CGInsetMake(9.0, 14.0, 6.0, 14.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBezeled | CPTextFieldStateRounded]; - [textfield setValue:CGInsetMake(4.0, 4.0, 4.0, 4.0) forThemedAttributeName:@"bezel-inset" inControlState:CPControlStateBezeled|CPTextFieldStateRounded]; - [textfield setValue:CGInsetMake(0.0, 0.0, 0.0, 0.0) forThemedAttributeName:@"bezel-inset" inControlState:CPControlStateBezeled|CPTextFieldStateRounded|CPControlStateEditing]; + [textfield setValue:CGInsetMake(4.0, 4.0, 4.0, 4.0) forThemeAttribute:@"bezel-inset" inState:CPThemeStateBezeled|CPTextFieldStateRounded]; + [textfield setValue:CGInsetMake(0.0, 0.0, 0.0, 0.0) forThemeAttribute:@"bezel-inset" inState:CPThemeStateBezeled|CPTextFieldStateRounded|CPThemeStateEditing]; - [textfield setValue:[CPColor colorWithCalibratedRed:189.0 / 255.0 green:199.0 / 255.0 blue:211.0 / 255.0 alpha:1.0] forThemedAttributeName:@"text-color" inControlState:CPTextFieldStatePlaceholder]; + [textfield setValue:[CPColor colorWithCalibratedRed:189.0 / 255.0 green:199.0 / 255.0 blue:211.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color" inState:CPTextFieldStatePlaceholder]; [textfield setPlaceholderString:"cheese cheese"]; [textfield setStringValue:""]; @@ -235,28 +233,29 @@ [button setTitle:@"Cancel"]; - [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemedAttributeName:@"font" inControlState:CPControlStateBordered]; - [button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemedAttributeName:@"text-color"]; - [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemedAttributeName:@"text-shadow-color" inControlState:CPControlStateBordered]; - [button setValue:CGSizeMake(0.0, 1.0) forThemedAttributeName:@"text-shadow-offset" inControlState:CPControlStateBordered]; - [button setValue:CPLineBreakByTruncatingTail forThemedAttributeName:@"line-break-mode"]; + [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateBordered]; + [button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"]; + [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateBordered]; + [button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateBordered]; + [button setValue:CPLineBreakByTruncatingTail forThemeAttribute:@"line-break-mode"]; - [button setValue:bezelColor forThemedAttributeName:@"bezel-color" inControlState:CPControlStateBordered]; - [button setValue:highlightedBezelColor forThemedAttributeName:@"bezel-color" inControlState:CPControlStateBordered|CPControlStateHighlighted]; - [button setValue:CGInsetMake(0.0, 5.0, 0.0, 5.0) forThemedAttributeName:@"content-inset" inControlState:CPControlStateBordered]; + [button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered]; + [button setValue:highlightedBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateHighlighted]; + [button setValue:CGInsetMake(0.0, 5.0, 0.0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered]; - [button setValue:defaultBezelColor forThemedAttributeName:@"bezel-color" inControlState:CPControlStateBordered|CPControlStateDefault]; - [button setValue:defaultHighlightedBezelColor forThemedAttributeName:@"bezel-color" inControlState:CPControlStateBordered|CPControlStateHighlighted|CPControlStateDefault]; - [button setValue:[CPColor colorWithCalibratedRed:13.0/255.0 green:51.0/255.0 blue:70.0/255.0 alpha:1.0] forThemedAttributeName:@"text-color" inControlState:CPControlStateDefault]; + [button setValue:defaultBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateDefault]; + [button setValue:defaultHighlightedBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateHighlighted|CPThemeStateDefault]; + [button setValue:[CPColor colorWithCalibratedRed:13.0/255.0 green:51.0/255.0 blue:70.0/255.0 alpha:1.0] forThemeAttribute:@"text-color" inState:CPThemeStateDefault]; - [button setValue:24.0 forThemedAttributeName:@"default-height"]; + [button setValue:24.0 forThemeAttribute:@"default-height"]; return button; } + (CPPopUpButton)themedPopUpButton { - var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:NO],color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:NO], + color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: [ [_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)], [_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)], @@ -266,18 +265,43 @@ [button setTitle:@"Pop Up"]; - [button setValue:color forThemedAttributeName:@"bezel-color" inControlState:CPControlStateBordered]; - [button setValue:CGInsetMake(0, 5, 0, 27.0 + 5.0) forThemedAttributeName:@"content-inset" inControlState:CPControlStateBordered]; - [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemedAttributeName:@"font"]; - [button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemedAttributeName:@"text-color"]; - [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemedAttributeName:@"text-shadow-color"]; - [button setValue:CGSizeMake(0.0, 1.0) forThemedAttributeName:@"text-shadow-offset"]; + [button setValue:color forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered]; + [button setValue:CGInsetMake(0, 5, 0, 27.0 + 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered]; + [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font"]; + [button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"]; + [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color"]; + [button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset"]; [button addItemWithTitle:@"item"]; return button; } ++ (CPPopUpButton)themedPullDownMenu +{ + var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:YES], + color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: + [ + [_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)], + [_CPCibCustomResource imageResourceWithName:"popup-bezel-right-pullsdown.png" size:CGSizeMake(27.0, 24.0)] + ] + isVertical:NO]]; + + [button setTitle:@"Pop Up"]; + + [button setValue:color forThemeAttribute:@"bezel-color" inState:CPPopUpButtonStatePullsDown|CPThemeStateBordered]; + [button setValue:CGInsetMake(0, 5, 0, 27.0 + 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered]; + [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font"]; + [button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"]; + [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color"]; + [button setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset"]; + + [button addItemWithTitle:@"item"]; + + return button; +} + + (CPPopUpButton)themedSegmentedControl { var segmentedControl = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 24.0)]; @@ -298,87 +322,64 @@ [segmentedControl setTag:3 forSegment:2]; //various colors - var centerBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-center.png" size:CGSizeMake(1.0, 24.0)]], - dividerBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-divider.png" size:CGSizeMake(1.0, 24.0)]], - centerHighlightedBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)]], - dividerHighlightedBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-divider.png" size:CGSizeMake(1.0, 24.0)]], - leftHighlightedBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)]], - rightHighlightedBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)]], - inactiveCenterBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-inactive-center.png" size:CGSizeMake(1.0, 24.0)]], - inactiveDividerBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-inactive-divider.png" size:CGSizeMake(1.0, 24.0)]], - inactiveLeftBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-inactive-left.png" size:CGSizeMake(4.0, 24.0)]], - inactiveRightBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-inactive-right.png" size:CGSizeMake(4.0, 24.0)]], - leftBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-left.png" size:CGSizeMake(4.0, 24.0)]], - rightBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-right.png" size:CGSizeMake(4.0, 24.0)]], - pushedCenterBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-pushed-center.png" size:CGSizeMake(1.0, 24.0)]], - pushedLeftBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-pushed-left.png" size:CGSizeMake(4.0, 24.0)]], - pushedRightBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-pushed-right.png" size:CGSizeMake(4.0, 24.0)]]; - pushedHighlightedCenterBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-pushed-highlighted-center.png" size:CGSizeMake(1.0, 24.0)]], - pushedHighlightedLeftBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-pushed-highlighted-left.png" size:CGSizeMake(4.0, 24.0)]], - pushedHighlightedRightBezelColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-pushed-highlighted-right.png" size:CGSizeMake(4.0, 24.0)]]; + var centerBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-center.png" size:CGSizeMake(1.0, 24.0)]), + dividerBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-divider.png" size:CGSizeMake(1.0, 24.0)]), + centerHighlightedBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)]), + dividerHighlightedBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-divider.png" size:CGSizeMake(1.0, 24.0)]), + leftHighlightedBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)]), + rightHighlightedBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)]), + inactiveCenterBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-inactive-center.png" size:CGSizeMake(1.0, 24.0)]), + inactiveDividerBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-inactive-divider.png" size:CGSizeMake(1.0, 24.0)]), + inactiveLeftBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-inactive-left.png" size:CGSizeMake(4.0, 24.0)]), + inactiveRightBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-inactive-right.png" size:CGSizeMake(4.0, 24.0)]), + leftBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-left.png" size:CGSizeMake(4.0, 24.0)]), + rightBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-right.png" size:CGSizeMake(4.0, 24.0)]), + pushedCenterBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-pushed-center.png" size:CGSizeMake(1.0, 24.0)]), + pushedLeftBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-pushed-left.png" size:CGSizeMake(4.0, 24.0)]), + pushedRightBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-pushed-right.png" size:CGSizeMake(4.0, 24.0)]); + pushedHighlightedCenterBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-pushed-highlighted-center.png" size:CGSizeMake(1.0, 24.0)]), + pushedHighlightedLeftBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-pushed-highlighted-left.png" size:CGSizeMake(4.0, 24.0)]), + pushedHighlightedRightBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"segmented-control-bezel-pushed-highlighted-right.png" size:CGSizeMake(4.0, 24.0)]); - [segmentedControl setValue:centerBezelColor forThemedAttributeName:@"center-segment-bezel-color" inControlState:CPControlStateNormal]; - [segmentedControl setValue:inactiveCenterBezelColor forThemedAttributeName:@"center-segment-bezel-color" inControlState:CPControlStateDisabled]; - [segmentedControl setValue:centerHighlightedBezelColor forThemedAttributeName:@"center-segment-bezel-color" inControlState:CPControlStateSelected]; - [segmentedControl setValue:pushedCenterBezelColor forThemedAttributeName:@"center-segment-bezel-color" inControlState:CPControlStateHighlighted]; - [segmentedControl setValue:pushedHighlightedCenterBezelColor forThemedAttributeName:@"center-segment-bezel-color" inControlState:CPControlStateHighlighted|CPControlStateSelected]; + [segmentedControl setValue:centerBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateNormal]; + [segmentedControl setValue:inactiveCenterBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateDisabled]; + [segmentedControl setValue:centerHighlightedBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateSelected]; + [segmentedControl setValue:pushedCenterBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateHighlighted]; + [segmentedControl setValue:pushedHighlightedCenterBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateHighlighted|CPThemeStateSelected]; - [segmentedControl setValue:dividerBezelColor forThemedAttributeName:@"divider-bezel-color" inControlState:CPControlStateNormal]; - [segmentedControl setValue:inactiveDividerBezelColor forThemedAttributeName:@"divider-bezel-color" inControlState:CPControlStateDisabled]; - [segmentedControl setValue:dividerHighlightedBezelColor forThemedAttributeName:@"divider-bezel-color" inControlState:CPControlStateSelected]; - [segmentedControl setValue:dividerBezelColor forThemedAttributeName:@"divider-bezel-color" inControlState:CPControlStateHighlighted]; + [segmentedControl setValue:dividerBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateNormal]; + [segmentedControl setValue:inactiveDividerBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateDisabled]; + [segmentedControl setValue:dividerHighlightedBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateSelected]; + [segmentedControl setValue:dividerBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateHighlighted]; - [segmentedControl setValue:rightBezelColor forThemedAttributeName:@"right-segment-bezel-color" inControlState:CPControlStateNormal]; - [segmentedControl setValue:inactiveRightBezelColor forThemedAttributeName:@"right-segment-bezel-color" inControlState:CPControlStateDisabled]; - [segmentedControl setValue:rightHighlightedBezelColor forThemedAttributeName:@"right-segment-bezel-color" inControlState:CPControlStateSelected]; - [segmentedControl setValue:pushedRightBezelColor forThemedAttributeName:@"right-segment-bezel-color" inControlState:CPControlStateHighlighted]; - [segmentedControl setValue:pushedHighlightedRightBezelColor forThemedAttributeName:@"right-segment-bezel-color" inControlState:CPControlStateHighlighted|CPControlStateSelected]; + [segmentedControl setValue:rightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateNormal]; + [segmentedControl setValue:inactiveRightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateDisabled]; + [segmentedControl setValue:rightHighlightedBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateSelected]; + [segmentedControl setValue:pushedRightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateHighlighted]; + [segmentedControl setValue:pushedHighlightedRightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateHighlighted|CPThemeStateSelected]; - [segmentedControl setValue:leftBezelColor forThemedAttributeName:@"left-segment-bezel-color" inControlState:CPControlStateNormal]; - [segmentedControl setValue:inactiveLeftBezelColor forThemedAttributeName:@"left-segment-bezel-color" inControlState:CPControlStateDisabled]; - [segmentedControl setValue:leftHighlightedBezelColor forThemedAttributeName:@"left-segment-bezel-color" inControlState:CPControlStateSelected]; - [segmentedControl setValue:pushedLeftBezelColor forThemedAttributeName:@"left-segment-bezel-color" inControlState:CPControlStateHighlighted]; - [segmentedControl setValue:pushedHighlightedLeftBezelColor forThemedAttributeName:@"left-segment-bezel-color" inControlState:CPControlStateHighlighted|CPControlStateSelected]; + [segmentedControl setValue:leftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateNormal]; + [segmentedControl setValue:inactiveLeftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateDisabled]; + [segmentedControl setValue:leftHighlightedBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateSelected]; + [segmentedControl setValue:pushedLeftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateHighlighted]; + [segmentedControl setValue:pushedHighlightedLeftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateHighlighted|CPThemeStateSelected]; - [segmentedControl setValue:CGInsetMake(0.0, 4.0, 0.0, 4.0) forThemedAttributeName:@"content-inset" inControlState:CPControlStateNormal]; + [segmentedControl setValue:CGInsetMake(0.0, 4.0, 0.0, 4.0) forThemeAttribute:@"content-inset" inState:CPThemeStateNormal]; - [segmentedControl setValue:CGInsetMake(0.0, 0.0, 0.0, 0.0) forThemedAttributeName:@"bezel-inset" inControlState:CPControlStateNormal]; + [segmentedControl setValue:CGInsetMake(0.0, 0.0, 0.0, 0.0) forThemeAttribute:@"bezel-inset" inState:CPThemeStateNormal]; - [segmentedControl setValue:[CPFont boldSystemFontOfSize:12.0] forThemedAttributeName:@"font"]; - [segmentedControl setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemedAttributeName:@"text-color"]; - [segmentedControl setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemedAttributeName:@"text-shadow-color"]; + [segmentedControl setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font"]; + [segmentedControl setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"]; + [segmentedControl setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color"]; + [segmentedControl setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset"]; + [segmentedControl setValue:CPLineBreakByTruncatingTail forThemeAttribute:@"line-break-mode"]; + + [segmentedControl setValue:1.0 forThemeAttribute:@"divider-thickness"]; + [segmentedControl setValue:24.0 forThemeAttribute:@"default-height"]; - [segmentedControl setValue:1.0 forThemedAttributeName:@"divider-thickness"]; - [segmentedControl setValue:24.0 forThemedAttributeName:@"default-height"]; - return segmentedControl; } -+ (CPPopUpButton)themedPullDownMenu -{ - var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:YES], - color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: - [ - [_CPCibCustomResource imageResourceWithName:"button-bezel-left.png" size:CGSizeMake(4.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"button-bezel-center.png" size:CGSizeMake(1.0, 24.0)], - [_CPCibCustomResource imageResourceWithName:"popup-bezel-right-pullsdown.png" size:CGSizeMake(27.0, 24.0)] - ] - isVertical:NO]]; - - [button setTitle:@"Pop Up"]; - - [button setValue:color forThemedAttributeName:@"bezel-color" inControlState:CPPopUpButtonStatePullsDown|CPControlStateBordered]; - [button setValue:CGInsetMake(0, 5, 0, 27.0 + 5.0) forThemedAttributeName:@"content-inset" inControlState:CPControlStateBordered]; - [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemedAttributeName:@"font"]; - [button setValue:[CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0] forThemedAttributeName:@"text-color"]; - [button setValue:[CPColor colorWithCalibratedWhite:240.0 / 255.0 alpha:1.0] forThemedAttributeName:@"text-shadow-color"]; - [button setValue:CGSizeMake(0.0, 1.0) forThemedAttributeName:@"text-shadow-offset"]; - - [button addItemWithTitle:@"item"]; - - return button; -} - + (CPSlider)themedHorizontalSlider { var slider = [[CPSlider alloc] initWithFrame:CGRectMake(0.0, 0.0, 50.0, 24.0)], @@ -390,15 +391,15 @@ ] isVertical:NO]]; - [slider setValue:5.0 forThemedAttributeName:@"track-width"]; - [slider setValue:trackColor forThemedAttributeName:@"track-color"]; + [slider setValue:5.0 forThemeAttribute:@"track-width"]; + [slider setValue:trackColor forThemeAttribute:@"track-color"]; var knobColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob.png" size:CGSizeMake(23.0, 24.0)]]; knobHighlightedColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob-highlighted.png" size:CGSizeMake(23.0, 24.0)]]; - [slider setValue:CGSizeMake(23.0, 24.0) forThemedAttributeName:@"knob-size"]; - [slider setValue:knobColor forThemedAttributeName:@"knob-color"]; - [slider setValue:knobHighlightedColor forThemedAttributeName:@"knob-color" inControlState:CPControlStateHighlighted]; + [slider setValue:CGSizeMake(23.0, 24.0) forThemeAttribute:@"knob-size"]; + [slider setValue:knobColor forThemeAttribute:@"knob-color"]; + [slider setValue:knobHighlightedColor forThemeAttribute:@"knob-color" inState:CPThemeStateHighlighted]; return slider; } @@ -414,15 +415,15 @@ ] isVertical:YES]]; - [slider setValue:5.0 forThemedAttributeName:@"track-width"]; - [slider setValue:trackColor forThemedAttributeName:@"track-color" inControlState:CPControlStateVertical]; + [slider setValue:5.0 forThemeAttribute:@"track-width"]; + [slider setValue:trackColor forThemeAttribute:@"track-color" inState:CPThemeStateVertical]; var knobColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob.png" size:CGSizeMake(23.0, 24.0)]]; knobHighlightedColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"knob-highlighted.png" size:CGSizeMake(23.0, 24.0)]]; - [slider setValue:CGSizeMake(23.0, 24.0) forThemedAttributeName:@"knob-size"]; - [slider setValue:knobColor forThemedAttributeName:@"knob-color"]; - [slider setValue:knobHighlightedColor forThemedAttributeName:@"knob-color" inControlState:CPControlStateHighlighted]; + [slider setValue:CGSizeMake(23.0, 24.0) forThemeAttribute:@"knob-size"]; + [slider setValue:knobColor forThemeAttribute:@"knob-color"]; + [slider setValue:knobHighlightedColor forThemeAttribute:@"knob-color" inState:CPThemeStateHighlighted]; return slider; } @@ -430,18 +431,17 @@ + (CPSlider)themedCircularSlider { var slider = [[CPSlider alloc] initWithFrame:CGRectMake(0.0, 0.0, 32.0, 32.0)], - trackColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"circularSliderBezel.png" size:CGSizeMake(32.0, 32.0)]]; + trackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"circularSliderBezel.png" size:CGSizeMake(32.0, 32.0)]); [slider setSliderType:CPCircularSlider]; - [slider setValue:trackColor forThemedAttributeName:@"track-color" inControlState:CPControlStateCircular]; - [slider setValue:trackColor forThemedAttributeName:@"track-color" inControlState:CPControlStateCircular|CPControlStateVertical]; + [slider setValue:trackColor forThemeAttribute:@"track-color" inState:CPThemeStateCircular]; var knobColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"circularSliderKnob.png" size:CGSizeMake(5.0, 5.0)]], knobHighlightedColor = knobColor; - [slider setValue:CGSizeMake(5.0, 5.0) forThemedAttributeName:@"knob-size" inControlState:CPControlStateCircular]; - [slider setValue:knobColor forThemedAttributeName:@"knob-color" inControlState:CPControlStateCircular]; - [slider setValue:knobHighlightedColor forThemedAttributeName:@"knob-color" inControlState:CPControlStateCircular|CPControlStateHighlighted]; + [slider setValue:CGSizeMake(5.0, 5.0) forThemeAttribute:@"knob-size" inState:CPThemeStateCircular]; + [slider setValue:knobColor forThemeAttribute:@"knob-color" inState:CPThemeStateCircular]; + [slider setValue:knobHighlightedColor forThemeAttribute:@"knob-color" inState:CPThemeStateCircular|CPThemeStateHighlighted]; return slider; } @@ -456,7 +456,7 @@ ] isVertical:NO]]; - [buttonBar setValue:color forThemedAttributeName:@"bezel-color"]; + [buttonBar setValue:color forThemeAttribute:@"bezel-color"]; [buttonBar setNeedsLayout]; views.push(buttonBar); @@ -465,7 +465,7 @@ */ @end -function PatterColor(anImage) +function PatternColor(anImage) { return [CPColor colorWithPatternImage:anImage]; } diff --git a/AppKit/Tools/BlendKit/BKShowcaseController.j b/AppKit/Tools/BlendKit/BKShowcaseController.j index 885417f3e..23f198315 100644 --- a/AppKit/Tools/BlendKit/BKShowcaseController.j +++ b/AppKit/Tools/BlendKit/BKShowcaseController.j @@ -87,6 +87,10 @@ CPTextField _label; } +- (void)setSelected:(BOOL)isSelected +{ +} + - (void)setRepresentedObject:(id)anObject { if (!_label) diff --git a/AppKit/Tools/blend/main.j b/AppKit/Tools/blend/main.j index 4b6faf9cb..46556f71b 100644 --- a/AppKit/Tools/blend/main.j +++ b/AppKit/Tools/blend/main.j @@ -49,7 +49,7 @@ function main() cibFiles.push(argument); } } - + if (descriptorFiles.length === 0) return buildBlendFromCibFiles(cibFiles); @@ -57,26 +57,26 @@ function main() { var themeDescriptorClasses = BKThemeDescriptorClasses(), count = [themeDescriptorClasses count]; - + while (count--) { var theClass = themeDescriptorClasses[count], themeTemplate = [[AKThemeTemplate alloc] init]; - + [themeTemplate setValue:[theClass themeName] forKey:@"name"]; - - var objectTemplates = BKThemeObjectTemplatesForClass(theClass); + + var objectTemplates = BKThemeObjectTemplatesForClass(theClass), data = cibDataFromTopLevelObjects(objectTemplates.concat([themeTemplate])), temporaryCibFile = File.createTempFile("temp", ".cib"), temporaryCibFilePath = temporaryCibFile.getAbsolutePath(), writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(temporaryCibFilePath), "UTF-8")); - + writer.write([data string]); writer.close(); cibFiles.push(temporaryCibFilePath); } - + buildBlendFromCibFiles(cibFiles, outputFilePath, resourcesPath); }); } @@ -131,7 +131,7 @@ function buildBlendFromCibFiles(cibFiles, outputFilePath, resourcesPath) fileContents = [[CPKeyedArchiver archivedDataWithRootObject:theme] string]; replacedFiles.push(filePath); - + staticContent += MARKER_PATH + ';' + filePath.length + ';' + filePath + MARKER_TEXT + ';' + fileContents.length + ';' + fileContents; } @@ -182,7 +182,7 @@ function themeFromCibFile(aFile) var object = topLevelObjects[count]; templates = templates.concat([object blendThemeObjectTemplates]); - + if ([object isKindOfClass:[AKThemeTemplate class]]) theme = [[CPTheme alloc] initWithName:[object valueForKey:@"name"]]; } diff --git a/Foundation/CPDictionary.j b/Foundation/CPDictionary.j index a8fa19611..016759bca 100755 --- a/Foundation/CPDictionary.j +++ b/Foundation/CPDictionary.j @@ -547,10 +547,21 @@ var i = _keys.length; while (i--) - description += _keys[i] +":"+[_buckets[_keys[i]] description]+"\n"; - + { + description += _keys[i] + ":"; + + var object = _buckets[_keys[i]]; + + if (object && object.isa) + description += [object description]; + else + description += object; + + description += "\n"; + } + description += "}"; - + return description; } diff --git a/Foundation/CPKeyedUnarchiver.j b/Foundation/CPKeyedUnarchiver.j index d7c13930b..d646302b9 100644 --- a/Foundation/CPKeyedUnarchiver.j +++ b/Foundation/CPKeyedUnarchiver.j @@ -111,7 +111,7 @@ var _CPKeyedUnarchiverArrayClass = Ni */ + (void)initialize { - if (self != [CPKeyedUnarchiver class]) + if (self !== [CPKeyedUnarchiver class]) return; _CPKeyedUnarchiverArrayClass = [CPArray class]; diff --git a/Tools/nib2cib/NSControl.j b/Tools/nib2cib/NSControl.j index 2d86d9597..c6749b7b7 100644 --- a/Tools/nib2cib/NSControl.j +++ b/Tools/nib2cib/NSControl.j @@ -34,8 +34,6 @@ if (self) { - _controlState = CPControlStateNormal; - [self sendActionOn:CPLeftMouseUpMask]; var cell = [aCoder decodeObjectForKey:@"NSCell"]; diff --git a/Tools/nib2cib/NSTableColumn.j b/Tools/nib2cib/NSTableColumn.j index b92d90ef6..0fb2055d7 100644 --- a/Tools/nib2cib/NSTableColumn.j +++ b/Tools/nib2cib/NSTableColumn.j @@ -38,7 +38,7 @@ //var dataViewCell = [aCoder decodeObjectForKey:@"NSDataCell"]; _dataView = [[CPTextField alloc] initWithFrame:CPRectMakeZero()]; - [_dataView setValue:[CPColor whiteColor] forThemedAttributeName:"text-color" inControlState:CPControlStateHighlighted]; + [_dataView setValue:[CPColor whiteColor] forThemedAttributeName:"text-color" inControlState:CPThemeStateHighlighted]; //_headerView = [aCoder decodeObjectForKey:@"NSHeaderCell"]; _headerView = [[CPTextField alloc] initWithFrame:CPRectMakeZero()]; diff --git a/Tools/nib2cib/NSView.j b/Tools/nib2cib/NSView.j index c3717102a..1b5b5676c 100644 --- a/Tools/nib2cib/NSView.j +++ b/Tools/nib2cib/NSView.j @@ -93,8 +93,9 @@ } } - _themedAttributes = {}; - [self _loadThemedAttributes]; + _themeAttributes = {}; + _themeState = CPThemeStateNormal; + [self _loadThemeAttributes]; } return self;