diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index 26b1089d8..c68941af1 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -474,6 +474,16 @@ CPRunContinuesResponse = -1002; _mainMenu = aMenu; } +- (void)orderFrontStandardAboutPanel:(id)aSender +{ + [self orderFrontStandardAboutPanelWithOptions:nil]; +} + +- (void)orderFrontStandardAboutPanelWithOptions:(CPDictionary)aDictionary +{ + // FIXME: Implement. +} + // Posting Actions /*! Tries to perform the action with an argument. Performs diff --git a/AppKit/CPButton.j b/AppKit/CPButton.j index 9317a2992..626ac1e3c 100644 --- a/AppKit/CPButton.j +++ b/AppKit/CPButton.j @@ -46,9 +46,9 @@ CPImageOverlaps = 6; /* @group CPButtonState */ -CPOnState = 1; -CPOffState = 0; -CPMixedState = -1; +CPOnState = 1; +CPOffState = 0; +CPMixedState = -1; /* @group CPBezelStyle */ @@ -70,24 +70,30 @@ CPHUDBezelStyle = -1; /* @group CPButtonType */ -CPMomentaryLightButton = 0; -CPPushOnPushOffButton = 1; -CPToggleButton = 2; -CPSwitchButton = 3; -CPRadioButton = 4; -CPMomentaryChangeButton = 5; -CPOnOffButton = 6; -CPMomentaryPushInButton = 7; -CPMomentaryPushButton = 0; -CPMomentaryLight = 7; +CPMomentaryLightButton = 0; +CPPushOnPushOffButton = 1; +CPToggleButton = 2; +CPSwitchButton = 3; // Deprecated, use CPCheckBox instead. +CPRadioButton = 4; // Deprecated, use CPRadio instead. +CPMomentaryChangeButton = 5; +CPOnOffButton = 6; +CPMomentaryPushInButton = 7; +CPMomentaryPushButton = 0; +CPMomentaryLight = 7; +CPNoButtonMask = 0; +CPContentsButtonMask = 1; +CPPushInButtonMask = 2; +CPGrayButtonMask = 4; +CPBackgroundButtonMask = 8; -var CPHUDBezelStyleTextColor = nil; +CPNoCellMask = CPNoButtonMask; +CPContentsCellMask = CPContentsButtonMask; +CPPushInCellMask = CPPushInButtonMask; +CPChangeGrayCellMask = CPGrayButtonMask; +CPChangeBackgroundCellMask = CPBackgroundButtonMask; -var _CPButtonClassName = nil, - _CPButtonBezelStyleSizes = {}, - _CPButtonBezelStyleIdentifiers = {}, - _CPButtonBezelStyleHighlightedIdentifier = @"Highlighted"; +CPButtonStateMixed = CPThemeState("mixed"); /*! @class CPButton @@ -97,8 +103,6 @@ var _CPButtonClassName = nil, */ @implementation CPButton : CPControl { - int _tag; - int _state; BOOL _allowsMixedState; CPString _title; @@ -107,26 +111,32 @@ var _CPButtonClassName = nil, CPImage _image; CPImage _alternateImage; - // Layout Views - CPView _bezelView; - _CPImageAndTextView _contentView; - + CPInteger _showsStateBy; + CPInteger _highlightsBy; + BOOL _imageDimsWhenDisabled; + // NS-style Display Properties CPBezelStyle _bezelStyle; - BOOL _isBordered; CPControlSize _controlSize; } + (id)standardButtonWithTitle:(CPString)aTitle { + var button = [[CPButton alloc] init]; + + [button setTitle:aTitle]; + + return button; } -+ (id)standardCheckboxWithTitle:(CPString)aTitle ++ (id)standardCheckBoxWithTitle:(CPString)aTitle { + return [CPCheckBox standardButtonWithTitle:aTitle]; } -- (id)standardRadioButtonWithTitle:(CPString)aTitle +- (id)standardRadioWithTitle:(CPString)aTitle { + return [CPRadio standardButtonWithTitle:aTitle]; } + (CPString)themeClass @@ -176,40 +186,84 @@ var _CPButtonClassName = nil, */ - (void)setAllowsMixedState:(BOOL)aFlag { + aFlag = !!aFlag; + + if (_allowsMixedState === aFlag) + return; + _allowsMixedState = aFlag; + + if (!_allowsMixedState) + [self unsetThemeState:CPButtonStateMixed]; } -/*! - Sets the button to its next state. -*/ -- (int)nextState +- (void)setObjectValue:(id)anObjectValue { - if (_state == CPOffState) - return CPOnState; - else - return (_state >= CPOnState && _allowsMixedState) ? CPMixedState : CPOffState; + if (!anObjectValue || anObjectValue === @"" || ([anObjectValue intValue] === 0)) + anObjectValue = CPOffState; + + else if (![anObjectValue isKindOfClass:[CPNumber class]]) + anObjectValue = CPOnState; + + else if (anObjectValue > CPOnState) + anObjectValue = CPOnState + + else if (anObjectValue < CPOffState) + if ([self allowsMixedState]) + anObjectValue = CPMixedState; + + else + anObjectValue = CPOnState; + + [super setObjectValue:anObjectValue]; + + switch ([self objectValue]) + { + case CPMixedState: [self unsetThemeState:CPThemeStateSelected]; + [self setThemeState:CPButtonStateMixed]; + break; + + case CPOnState: [self unsetThemeState:CPButtonStateMixed]; + [self setThemeState:CPThemeStateSelected]; + break; + + case CPOffState: [self unsetThemeState:CPThemeStateSelected | CPButtonStateMixed]; + } +} + +- (CPInteger)nextState +{ + if ([self allowsMixedState]) + { + var value = [self state]; + + return value - ((value === -1) ? -2 : 1); + } + + return 1 - [self state]; } - (void)setNextState { [self setState:[self nextState]]; } + /*! Sets the button's state to aState. @param aState Possible states are any of the CPButton globals: CPOffState, CPOnState, CPMixedState */ -- (void)setState:(int)aState +- (void)setState:(CPInteger)aState { - _state = aState; + [self setIntValue:aState]; } /*! Returns the button's current state */ -- (int)state +- (CPInteger)state { - return _state; + return [self intValue]; } - (void)setTitle:(CPString)aTitle @@ -283,32 +337,96 @@ var _CPButtonClassName = nil, return _alternateImage; } -/*! - Highlights the receiver based on aFlag. - @param If YES the button will highlight, NO the button will unhighlight. -*/ -- (void)highlight:(BOOL)aFlag +- (void)setShowsStateBy:(CPInteger)aMask { - [super highlight:aFlag]; - - [self drawBezelWithHighlight:aFlag]; + if (_showsStateBy === aMask) + return; + + _showsStateBy = aMask; + + [self setNeedsDisplay:YES]; + [self setNeedsLayout]; } -/*! - Sets button's tag. - @param aTag the button's new tag -*/ -- (void)setTag:(int)aTag +- (CPInteger)showsStateBy { - _tag = aTag; + return _showsStateBy; } -/*! - Returns the button's tag. -*/ -- (int)tag +- (void)setHighlightsBy:(CPInteger)aMask { - return _tag; + if (_highlightsBy === aMask) + return; + + _highlightsBy = aMask; + + if ([self hasThemeState:CPThemeStateHighlighted]) + { + [self setNeedsDisplay:YES]; + [self setNeedsLayout]; + } +} + +- (void)setButtonType:(CPButtonType)aButtonType +{ + switch (buttonType) + { + case CPMomentaryLightButton: [self setHighlightsBy:CPChangeBackgroundCellMask]; + [self setShowsStateBy:CPNoCellMask]; + break; + + case CPMomentaryPushInButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask]; + [self setShowsStateBy:CPNoCellMask]; + break; + + case CPMomentaryChangeButton: [self setHighlightsBy:CPContentsCellMask]; + [self setShowsStateBy:CPNoCellMask]; + break; + + case CPPushOnPushOffButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask]; + [self setShowsStateBy:CPChangeBackgroundCellMask]; + break; + + case CPOnOffButton: [self setHighlightsBy:CPChangeBackgroundCellMask]; + [self setShowsStateBy:CPChangeBackgroundCellMask]; + break; + + case CPToggleButton: [self setHighlightsBy:CPPushInCellMask | NSContentsCellMask]; + [self setShowsStateBy:CPContentsCellMask]; + break; + + case CPSwitchButton: [CPException raise:CPInvalidArgumentException + reason:"The CPSwitchButton type is not supported in Cappuccino, use the CPCheckBox class instead."]; + + case CPRadioButton: [CPException raise:CPInvalidArgumentException + reason:"The CPRadioButton type is not supported in Cappuccino, use the CPRadio class instead."]; + + default: [CPException raise:CPInvalidArgumentException + reason:"Unknown button type."]; + } + + [self setImageDimsWhenDisabled:YES]; +} + +- (void)setImageDimsWhenDisabled:(BOOL)imageShouldDimWhenDisabled +{ + imageShouldDimWhenDisabled = !!imageShouldDimWhenDisabled; + + if (_imageDimsWhenDisabled === imageShouldDimWhenDisabled) + return; + + _imageDimsWhenDisabled = imageShouldDimWhenDisabled; + + if (_imageDimsWhenDisabled) + { + [self setNeedsDisplay:YES]; + [self setNeedsLayout]; + } +} + +- (BOOL)imageDimsWhenDisabled +{ + return _imageDimsWhenDisabled; } - (BOOL)startTrackingAt:(CGPoint)aPoint @@ -321,35 +439,11 @@ var _CPButtonClassName = nil, - (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp { [self highlight:NO]; - + [super stopTracking:lastPoint at:aPoint mouseIsUp:mouseIsUp]; -} -/* @ignore */ -- (void)drawBezelWithHighlight:(BOOL)shouldHighlight -{ return; - _bezelBorderNeedsUpdate = ![self window]; - - if (_bezelBorderNeedsUpdate) - return; - - [self setBackgroundColorWithName:shouldHighlight ? CPControlHighlightedBackgroundColor : CPControlNormalBackgroundColor]; -} - -- (CPView)createBezelView -{ - var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()]; - - [view setHitTests:NO]; - - return view; -} - -- (CPView)createContentView -{ - var view = [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()]; - - return view; + if (mouseIsUp && CGRectContainsPoint([self bounds], aPoint)) + [self setNextState]; } - (CGRect)contentRectForBounds:(CGRect)bounds @@ -494,15 +588,8 @@ var CPButtonImageKey = @"CPButtonImageKey", CPButtonAlternateImageKey = @"CPButtonAlternateImageKey", CPButtonTitleKey = @"CPButtonTitleKey", CPButtonAlternateTitleKey = @"CPButtonAlternateTitleKey", - CPButtonContentInsetKey = @"CPButtonContentInsetKey", - CPButtonBezelInsetKey = @"CPButtonBezelInsetKey", - CPButtonBezelColorKey = @"CPButtonBezelColorKey", - CPButtonImageAndTitleViewKey = @"CPButtonImageAndTitleViewKey", - CPButtonImagePositionKey = @"CPButtonImagePositionKey", - CPButtonImageScalingKey = @"CPButtonImageScalingKey", CPButtonIsBorderedKey = @"CPButtonIsBorderedKey", - CPButtonBezelStyleKey = @"CPButtonBezelStyleKey", - CPButtonImageAndTitleViewKey = @"CPButtonImageAndTitleViewKey"; + CPButtonBezelStyleKey = @"CPButtonBezelStyleKey"; @implementation CPButton (CPCoding) @@ -549,3 +636,6 @@ var CPButtonImageKey = @"CPButtonImageKey", } @end + +@import "CPCheckBox.j" +@import "CPRadio.j" diff --git a/AppKit/CPCheckBox.j b/AppKit/CPCheckBox.j new file mode 100644 index 000000000..487c51813 --- /dev/null +++ b/AppKit/CPCheckBox.j @@ -0,0 +1,63 @@ +/* + * CPCheckBox.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 "CPButton.j" + + +@implementation CPCheckBox : CPButton +{ +} + ++ (CPButton)standardButtonWithTitle:(CPString)aTitle +{ + var button = [[CPCheckBox alloc] init]; + + [button setTitle:aTitle]; + + return button; +} + ++ (CPString)themeClass +{ + return @"check-box"; +} + +- (id)initWithFrame:(CGRect)aFrame +{ + self = [super initWithFrame:aFrame]; + + if (self) + { + [self setHighlightsBy:CPContentsCellMask]; + [self setShowsStateBy:CPContentsCellMask]; + + // Defaults? + [self setImagePosition:CPImageLeft]; + [self setAlignment:CPLeftTextAlignment]; + + [self setBordered:YES]; + } + + return self; +} + +@end diff --git a/AppKit/CPMenuItem.j b/AppKit/CPMenuItem.j index e0d163690..cf32d3241 100644 --- a/AppKit/CPMenuItem.j +++ b/AppKit/CPMenuItem.j @@ -113,11 +113,11 @@ { if ([_menu autoenablesItems]) return; - + _isEnabled = isEnabled; - + [_menuItemView setDirty]; - + [_menu itemChanged:self]; } @@ -686,7 +686,7 @@ CPControlKeyMask */ - (void)setView:(CPView)aView { - if (_view == aView) + if (_view === aView) return; _view = aView; @@ -754,19 +754,23 @@ CPControlKeyMask var CPMenuItemTitleKey = @"CPMenuItemTitleKey", CPMenuItemTargetKey = @"CPMenuItemTargetKey", CPMenuItemActionKey = @"CPMenuItemActionKey", - + CPMenuItemIsEnabledKey = @"CPMenuItemIsEnabledKey", CPMenuItemIsHiddenKey = @"CPMenuItemIsHiddenKey", - + CPMenuItemTagKey = @"CPMenuItemTagKey", - + CPMenuItemImageKey = @"CPMenuItemImageKey", CPMenuItemAlternateImageKey = @"CPMenuItemAlternateImageKey", - + CPMenuItemSubmenuKey = @"CPMenuItemSubmenuKey", CPMenuItemMenuKey = @"CPMenuItemMenuKey", - - CPMenuItemRepresentedObjectKey = @"CPMenuItemRepresentedObjectKey"; + + CPMenuItemRepresentedObjectKey = @"CPMenuItemRepresentedObjectKey", + CPMenuItemViewKey = @"CPMenuItemViewKey"; + +#define DEFAULT_VALUE(aKey, aDefaultValue) [aCoder containsValueForKey:(aKey)] ? [aCoder decodeObjectForKey:(aKey)] : (aDefaultValue) +#define ENCODE_IFNOT(aKey, aValue, aDefaultValue) if ((aValue) !== (aDefaultValue)) [aCoder encodeObject:(aValue) forKey:(aKey)]; @implementation CPMenuItem (CPCoding) /*! @@ -787,22 +791,21 @@ var CPMenuItemTitleKey = @"CPMenuItemTitleKey", _target = [aCoder decodeObjectForKey:CPMenuItemTargetKey]; _action = [aCoder decodeObjectForKey:CPMenuItemActionKey]; - _isEnabled = [aCoder decodeObjectForKey:CPMenuItemIsEnabledKey]; - _isHidden = [aCoder decodeObjectForKey:CPMenuItemIsHiddenKey]; - - _tag = [aCoder containsValueForKey:CPMenuItemTagKey] ? [aCoder decodeObjectForKey:CPMenuItemTagKey] : 0; + _isEnabled = DEFAULT_VALUE(CPMenuItemIsEnabledKey, YES); + _isHidden = DEFAULT_VALUE(CPMenuItemIsHiddenKey, NO); + _tag = DEFAULT_VALUE(CPMenuItemTagKey, 0); // int _state; - - _image = [aCoder decodeObjectForKey:CPMenuItemImageKey]; - _alternateImage = [aCoder decodeObjectForKey:CPMenuItemAlternateImageKey]; + + _image = DEFAULT_VALUE(CPMenuItemImageKey, nil); + _alternateImage = DEFAULT_VALUE(CPMenuItemAlternateImageKey, nil); // CPImage _onStateImage; // CPImage _offStateImage; // CPImage _mixedStateImage; - _submenu = [aCoder decodeObjectForKey:CPMenuItemSubmenuKey]; - _menu = [aCoder decodeObjectForKey:CPMenuItemMenuKey]; - + _submenu = DEFAULT_VALUE(CPMenuItemSubmenuKey, nil); + _menu = DEFAULT_VALUE(CPMenuItemMenuKey, nil); + // CPString _keyEquivalent; // unsigned _keyEquivalentModifierMask; @@ -810,12 +813,11 @@ var CPMenuItemTitleKey = @"CPMenuItemTitleKey", // BOOL _isAlternate; // int _indentationLevel; - + // CPString _toolTip; - _representedObject = [aCoder decodeObjectForKey:CPMenuItemRepresentedObjectKey]; -// id _representedObject; -// CPView _view; + _representedObject = DEFAULT_VALUE(CPMenuItemRepresentedObjectKey, nil); + _view = DEFAULT_VALUE(CPMenuItemViewKey, nil); } return self; @@ -832,19 +834,19 @@ var CPMenuItemTitleKey = @"CPMenuItemTitleKey", [aCoder encodeObject:_target forKey:CPMenuItemTargetKey]; [aCoder encodeObject:_action forKey:CPMenuItemActionKey]; - [aCoder encodeObject:_isEnabled forKey:CPMenuItemIsEnabledKey]; - [aCoder encodeObject:_isHidden forKey:CPMenuItemIsHiddenKey]; + ENCODE_IFNOT(CPMenuItemIsEnabledKey, _isEnabled, YES); + ENCODE_IFNOT(CPMenuItemIsHiddenKey, _isHidden, NO); - if (_tag !== 0) - [aCoder encodeObject:_tag forKey:CPMenuItemTagKey]; + ENCODE_IFNOT(CPMenuItemTagKey, _tag, 0); - [aCoder encodeObject:_image forKey:CPMenuItemImageKey]; - [aCoder encodeObject:_alternateImage forKey:CPMenuItemAlternateImageKey]; + ENCODE_IFNOT(CPMenuItemImageKey, _image, nil); + ENCODE_IFNOT(CPMenuItemAlternateImageKey, _alternateImage, nil); - [aCoder encodeObject:_submenu forKey:CPMenuItemSubmenuKey]; - [aCoder encodeObject:_menu forKey:CPMenuItemMenuKey]; - - [aCoder encodeObject:_representedObject forKey:CPMenuItemRepresentedObjectKey]; + ENCODE_IFNOT(CPMenuItemSubmenuKey, _submenu, nil); + ENCODE_IFNOT(CPMenuItemMenuKey, _menu, nil); + + ENCODE_IFNOT(CPMenuItemRepresentedObjectKey, _representedObject, nil); + ENCODE_IFNOT(CPMenuItemViewKey, _view, nil) } @end diff --git a/AppKit/CPRadio.j b/AppKit/CPRadio.j new file mode 100644 index 000000000..a19df54f0 --- /dev/null +++ b/AppKit/CPRadio.j @@ -0,0 +1,159 @@ +/* + * CPRadio.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 "CPButton.j" + + +@implementation CPRadio : CPButton +{ + CPRadioGroup _radioGroup; +} + ++ (CPButton)standardButtonWithTitle:(CPString)aTitle +{ + var button = [[CPRadio alloc] init]; + + [button setTitle:aTitle]; + + return button; +} + ++ (CPString)themeClass +{ + return @"radio"; +} + +// Designated Initializer +- (id)initWithFrame:(CGRect)aFrame radioGroup:(CPRadioGroup)aRadioGroup +{ + self = [super initWithFrame:aFrame]; + + if (self) + { + _radioGroup = aRadioGroup || [CPRadioGroup new]; + + [self setHighlightsBy:CPContentsCellMask]; + [self setShowsStateBy:CPContentsCellMask]; + + // Defaults? + [self setImagePosition:CPImageLeft]; + [self setAlignment:CPLeftTextAlignment]; + + [self setBordered:YES]; + } + + return self; +} + +- (id)initWithFrame:(CGRect)aFrame +{ + return [self initWithFrame:aFrame radioGroup:nil]; +} + +- (CPInteger)nextState +{ + return CPOnState; +} + +- (void)setRadioGroup:(CPRadioGroup)aRadioGroup +{ + if (_radioGroup === aRadioGroup) + return; + + [_radioGroup _removeRadio:self]; + _radioGroup = aRadioGroup; + [_radioGroup _addRadio:self]; +} + +- (CPRadioGroup)radioGroup +{ + return _radioGroup; +} + +- (void)setObjectValue:(id)aValue +{ + [super setObjectValue:aValue]; + + if ([self state] === CPOnState) + [_radioGroup _setSelectedRadio:self]; +} + +@end + +@implementation CPRadioGroup : CPObject +{ + CPSet _radios; + CPRadio _selectedRadio; +} + +- (id)init +{ + self = [super init]; + + if (self) + { + _radios = [CPSet set]; + _selectedRadio = nil; + } + + return self; +} + +- (void)_addRadio:(CPRadio)aRadio +{ + [_radios addObject:aRadio]; + + if ([aRadio state] === CPOnState) + [self _setSelectedRadio:aRadio]; +} + +- (void)_removeRadio:(CPRadio)aRadio +{ + if (_selectedRadio === aRadio) + _selectedRadio = nil; + + [_radios removeObject:aRadio]; +} + +- (void)_setSelectedRadio:(CPRadio)aRadio +{ + if (_selectedRadio === aRadio) + return; + + [_selectedRadio setState:CPOffState]; + _selectedRadio = aRadio; +} + +- (CPRadio)selectedRadio +{ + return _selectedRadio; +} + +- (CPArray)radios +{ + return [_radios allObjects]; +} + +@end diff --git a/AppKit/CPView.j b/AppKit/CPView.j index 6db16de7c..b3230a4e6 100644 --- a/AppKit/CPView.j +++ b/AppKit/CPView.j @@ -552,11 +552,35 @@ var DOMElementPrototype = nil, return enclosingMenuItem;*/ } -- (int)tag +- (void)setTag:(CPInteger)aTag +{ + _tag = aTag; +} + +- (CPInteger)tag { return _tag; } +- (void)viewWithTag:(CPInteger)aTag +{ + if ([self tag] === aTag) + return self; + + var index = 0, + count = _subviews.length; + + for (; index < count; ++index) + { + var view = [_subviews[index] viewWithTag:aTag]; + + if (view) + return view; + } + + return nil; +} + /*! Returns whether the view is flipped. @return YES if the view is flipped. NO, otherwise. @@ -1930,6 +1954,11 @@ setBoundsOrigin: @implementation CPView (Theming) #pragma mark Theme States +- (unsigned)themeState +{ + return _themeState; +} + - (BOOL)hasThemeState:(CPThemeState)aState { return !!(_themeState & ((typeof aState === "string") ? CPThemeState(aState) : aState)); @@ -2192,7 +2221,12 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask", _tag = [aCoder decodeIntForKey:CPViewTagKey]; _window = [aCoder decodeObjectForKey:CPViewWindowKey]; - _subviews = [aCoder decodeObjectForKey:CPViewSubviewsKey]; + + if ([aCoder containsValueForKey:CPViewSubviewsKey]) + _subviews = [aCoder decodeObjectForKey:CPViewSubviewsKey]; + else + _subviews = []; + _superview = [aCoder decodeObjectForKey:CPViewSuperviewKey]; _autoresizingMask = [aCoder decodeIntForKey:CPViewAutoresizingMaskKey] || 0; @@ -2223,7 +2257,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask", [self setBackgroundColor:[aCoder decodeObjectForKey:CPViewBackgroundColorKey]]; _theme = [CPTheme defaultTheme]; - _themeState = [aCoder decodeIntForKey:CPViewThemeStateKey]; + _themeState = CPThemeState([aCoder decodeIntForKey:CPViewThemeStateKey]); _themeAttributes = {}; var theClass = [self class], @@ -2257,14 +2291,17 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask", { [super encodeWithCoder:aCoder]; - if (_tag != -1) + if (_tag !== -1) [aCoder encodeInt:_tag forKey:CPViewTagKey]; [aCoder encodeRect:_frame forKey:CPViewFrameKey]; [aCoder encodeRect:_bounds forKey:CPViewBoundsKey]; [aCoder encodeConditionalObject:_window forKey:CPViewWindowKey]; - [aCoder encodeObject:_subviews forKey:CPViewSubviewsKey]; + + if (_subviews.length > 0) + [aCoder encodeObject:_subviews forKey:CPViewSubviewsKey]; + [aCoder encodeConditionalObject:_superview forKey:CPViewSuperviewKey]; [aCoder encodeInt:_autoresizingMask forKey:CPViewAutoresizingMaskKey]; @@ -2281,7 +2318,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask", [aCoder encodeConditionalObject:[self nextKeyView] forKey:CPViewNextKeyViewKey]; [aCoder encodeConditionalObject:[self previousKeyView] forKey:CPViewPreviousKeyViewKey]; - [aCoder encodeInt:_themeState forKey:CPViewThemeStateKey]; + [aCoder encodeInt:CPThemeStateName(_themeState) forKey:CPViewThemeStateKey]; for (var attributeName in _themeAttributes) if (_themeAttributes.hasOwnProperty(attributeName)) diff --git a/AppKit/Themes/Aristo/Resources/check-box-bezel-selected.png b/AppKit/Themes/Aristo/Resources/check-box-bezel-selected.png new file mode 100644 index 000000000..7d4ee2983 Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/check-box-bezel-selected.png differ diff --git a/AppKit/Themes/Aristo/Resources/check-box-bezel.png b/AppKit/Themes/Aristo/Resources/check-box-bezel.png new file mode 100644 index 000000000..d25d8c9d1 Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/check-box-bezel.png differ diff --git a/AppKit/Themes/Aristo/Resources/radio-bezel-selected.png b/AppKit/Themes/Aristo/Resources/radio-bezel-selected.png new file mode 100644 index 000000000..5987c9d53 Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/radio-bezel-selected.png differ diff --git a/AppKit/Themes/Aristo/Resources/radio-bezel.png b/AppKit/Themes/Aristo/Resources/radio-bezel.png new file mode 100644 index 000000000..d9b61ad38 Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/radio-bezel.png differ diff --git a/AppKit/Themes/Aristo/ThemeDescriptors.j b/AppKit/Themes/Aristo/ThemeDescriptors.j index 213a59704..4e00f026b 100644 --- a/AppKit/Themes/Aristo/ThemeDescriptors.j +++ b/AppKit/Themes/Aristo/ThemeDescriptors.j @@ -7,6 +7,7 @@ */ @import +@import @implementation AristoThemeDescriptor : CPObject @@ -252,6 +253,42 @@ return button; } ++ (CPRadioButton)themedRadioButton +{ + var button = [[CPRadio alloc] initWithFrame:CGRectMake(0.0, 0.0, 120.0, 17.0)]; + + [button setTitle:@"Hello Friend!"]; + + var bezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:"radio-bezel.png" size:CGSizeMake(17.0, 17.0)]), + bezelColorSelected = PatternColor([_CPCibCustomResource imageResourceWithName:"radio-bezel-selected.png" size:CGSizeMake(17.0, 17.0)]); + + [button setValue:CPLeftTextAlignment forThemeAttribute:@"alignment" inState:CPThemeStateBordered]; + [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateBordered]; + [button setValue:CGInsetMake(0.0, 0.0, 0.0, 20.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered]; + [button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered]; + [button setValue:bezelColorSelected forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateSelected]; + + return button; +} + ++ (CPRadioButton)themedCheckBoxButton +{ + var button = [[CPCheckBox alloc] initWithFrame:CGRectMake(0.0, 0.0, 120.0, 17.0)]; + + [button setTitle:@"Another option"]; + + var bezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:"check-box-bezel.png" size:CGSizeMake(15.0, 15.0)]), + bezelColorSelected = PatternColor([_CPCibCustomResource imageResourceWithName:"check-box-bezel-selected.png" size:CGSizeMake(15.0, 16.0)]); + + [button setValue:CPLeftTextAlignment forThemeAttribute:@"alignment" inState:CPThemeStateBordered]; + [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateBordered]; + [button setValue:CGInsetMake(0.0, 0.0, 0.0, 20.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered]; + [button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered]; + [button setValue:bezelColorSelected forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateSelected]; + + return button; +} + + (CPPopUpButton)themedPopUpButton { var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:NO], diff --git a/External/Rakefile b/External/Rakefile index 5b31563f4..d976681e0 100644 --- a/External/Rakefile +++ b/External/Rakefile @@ -29,6 +29,15 @@ file_d $ENVIRONMENT_JACK_PRODUCT => [$ENVIRONMENT_NARWHAL_PRODUCT] do cp_r('jack', $ENVIRONMENT_JACK_PRODUCT) end -task :build => [$ENVIRONMENT_NARWHAL_PRODUCT, $ENVIRONMENT_BROWSERJS_PRODUCT, $ENVIRONMENT_JACK_PRODUCT, $ENVIRONMENT_NARWHAL_EXECUTABLE] +task :update_submodules do + if executable_exists? "git" + system %{cd .. && git submodule update --init} + else + puts "Git not installed" + rake abort + end +end + +task :build => [:update_submodules, $ENVIRONMENT_NARWHAL_PRODUCT, $ENVIRONMENT_BROWSERJS_PRODUCT, $ENVIRONMENT_JACK_PRODUCT, $ENVIRONMENT_NARWHAL_EXECUTABLE] CLOBBER.include($ENVIRONMENT_NARWHAL_PRODUCT, $ENVIRONMENT_BROWSERJS_PRODUCT, $ENVIRONMENT_JACK_PRODUCT, $ENVIRONMENT_NARWHAL_EXECUTABLE) diff --git a/Rakefile b/Rakefile index 299f83a79..2ae19fb41 100644 --- a/Rakefile +++ b/Rakefile @@ -72,12 +72,12 @@ file_d $STARTER_DOWNLOAD_README => [$STARTER_README] do end task :install => [:downloads] do - if ENV['prefix'] - prefix = "--prefix #{ENV['prefix']}" - else - prefix = '' - end - system %{cd #{$TOOLS_DOWNLOAD} && sudo sh ./install-tools #{prefix} } + if ENV['prefix'] + prefix = "--prefix #{ENV['prefix']}" + else + prefix = '' + end + system %{cd #{$TOOLS_DOWNLOAD} && sudo sh ./install-tools #{prefix} } end task :test => [:build] do @@ -101,12 +101,12 @@ task :docs do end task :submodules do - if executable_exists? "git" - system %{git submodule init} - system %{git submodule update} - else - puts "Git not installed" - end + if executable_exists? "git" + system %{cd .. && git submodule update --init} + else + puts "Git not installed" + rake abort + end end =begin