<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>AppKit/Themes/Aristo/Resources/check-box-bezel-selected.png</filename>
    </added>
    <added>
      <filename>AppKit/Themes/Aristo/Resources/check-box-bezel.png</filename>
    </added>
    <added>
      <filename>AppKit/Themes/Aristo/Resources/radio-bezel-selected.png</filename>
    </added>
    <added>
      <filename>AppKit/Themes/Aristo/Resources/radio-bezel.png</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -46,9 +46,9 @@ CPImageOverlaps = 6;
 
 /*  @group CPButtonState */
 
-CPOnState       = 1;
-CPOffState      = 0;
-CPMixedState    = -1;
+CPOnState                       = 1;
+CPOffState                      = 0;
+CPMixedState                    = -1;
 
 /* @group CPBezelStyle */
 
@@ -70,19 +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;
-
-
-var CPHUDBezelStyleTextColor = nil;
+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;
+
+CPNoCellMask                = CPNoButtonMask;
+CPContentsCellMask          = CPContentsButtonMask;
+CPPushInCellMask            = CPPushInButtonMask;
+CPChangeGrayCellMask        = CPGrayButtonMask;
+CPChangeBackgroundCellMask  = CPBackgroundButtonMask;
+
+CPButtonStateMixed  = CPThemeState(&quot;mixed&quot;);
 
 /*! @class CPButton
 
@@ -100,22 +111,32 @@ var CPHUDBezelStyleTextColor = nil;
     CPImage             _image;
     CPImage             _alternateImage;
 
+    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
@@ -165,18 +186,26 @@ var CPHUDBezelStyleTextColor = nil;
 */
 - (void)setAllowsMixedState:(BOOL)aFlag
 {
+    aFlag = !!aFlag;
+
+    if (_allowsMixedState === aFlag)
+        return;
+
     _allowsMixedState = aFlag;
+
+    if (!_allowsMixedState)
+        [self unsetThemeState:CPButtonStateMixed];
 }
 
 - (void)setObjectValue:(id)anObjectValue
 {
-    if (!anObjectValue || anObjectValue === @&quot;&quot;)
+    if (!anObjectValue || anObjectValue === @&quot;&quot; || ([anObjectValue intValue] === 0))
         anObjectValue = CPOffState;
 
     else if (![anObjectValue isKindOfClass:[CPNumber class]])
         anObjectValue = CPOnState;
 
-    else if (aState &gt; CPOnState)
+    else if (anObjectValue &gt; CPOnState)
         anObjectValue = CPOnState
 
     else if (anObjectValue &lt; CPOffState)
@@ -187,9 +216,22 @@ var CPHUDBezelStyleTextColor = nil;
             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];
+    }
 }
 
-- (int)nextState
+- (CPInteger)nextState
 {
    if ([self allowsMixedState])
    {
@@ -211,7 +253,7 @@ var CPHUDBezelStyleTextColor = nil;
     @param aState Possible states are any of the CPButton globals:
     &lt;code&gt;CPOffState, CPOnState, CPMixedState&lt;/code&gt;
 */
-- (void)setState:(int)aState
+- (void)setState:(CPInteger)aState
 {
     [self setIntValue:aState];
 }
@@ -219,7 +261,7 @@ var CPHUDBezelStyleTextColor = nil;
 /*!
     Returns the button's current state
 */
-- (int)state
+- (CPInteger)state
 {
     return [self intValue];
 }
@@ -295,6 +337,98 @@ var CPHUDBezelStyleTextColor = nil;
     return _alternateImage;
 }
 
+- (void)setShowsStateBy:(CPInteger)aMask
+{
+    if (_showsStateBy === aMask)
+        return;
+
+    _showsStateBy = aMask;
+
+    [self setNeedsDisplay:YES];
+    [self setNeedsLayout];
+}
+
+- (CPInteger)showsStateBy
+{
+    return _showsStateBy;
+}
+
+- (void)setHighlightsBy:(CPInteger)aMask
+{
+    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:&quot;The CPSwitchButton type is not supported in Cappuccino, use the CPCheckBox class instead.&quot;];
+
+        case CPRadioButton:             [CPException raise:CPInvalidArgumentException 
+                                                    reason:&quot;The CPRadioButton type is not supported in Cappuccino, use the CPRadio class instead.&quot;];
+
+        default:                        [CPException raise:CPInvalidArgumentException 
+                                                    reason:&quot;Unknown button type.&quot;];
+    }
+
+    [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
 {
     [self highlight:YES];
@@ -305,8 +439,11 @@ var CPHUDBezelStyleTextColor = nil;
 - (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
 {
     [self highlight:NO];
-    
+
     [super stopTracking:lastPoint at:aPoint mouseIsUp:mouseIsUp];
+
+    if (mouseIsUp &amp;&amp; CGRectContainsPoint([self bounds], aPoint))
+        [self setNextState];
 }
 
 - (CGRect)contentRectForBounds:(CGRect)bounds
@@ -499,3 +636,6 @@ var CPButtonImageKey                = @&quot;CPButtonImageKey&quot;,
 }
 
 @end
+
+@import &quot;CPCheckBox.j&quot;
+@import &quot;CPRadio.j&quot;</diff>
      <filename>AppKit/CPButton.j</filename>
    </modified>
    <modified>
      <diff>@@ -7,6 +7,7 @@
  */
 
 @import &lt;Foundation/CPObject.j&gt;
+@import &lt;AppKit/CPRadio.j&gt;
 
 
 @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:@&quot;Hello Friend!&quot;];
+
+    var bezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:&quot;radio-bezel.png&quot; size:CGSizeMake(17.0, 17.0)]),
+        bezelColorSelected = PatternColor([_CPCibCustomResource imageResourceWithName:&quot;radio-bezel-selected.png&quot; size:CGSizeMake(17.0, 17.0)]);
+
+    [button setValue:CPLeftTextAlignment forThemeAttribute:@&quot;alignment&quot; inState:CPThemeStateBordered];
+    [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@&quot;font&quot; inState:CPThemeStateBordered];
+    [button setValue:CGInsetMake(0.0, 0.0, 0.0, 20.0) forThemeAttribute:@&quot;content-inset&quot; inState:CPThemeStateBordered];
+    [button setValue:bezelColor forThemeAttribute:@&quot;bezel-color&quot; inState:CPThemeStateBordered];    
+    [button setValue:bezelColorSelected forThemeAttribute:@&quot;bezel-color&quot; inState:CPThemeStateBordered | CPThemeStateSelected];
+
+    return button;
+}
+
++ (CPRadioButton)themedCheckBoxButton
+{
+    var button = [[CPCheckBox alloc] initWithFrame:CGRectMake(0.0, 0.0, 120.0, 17.0)];
+    
+    [button setTitle:@&quot;Another option&quot;];
+
+    var bezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:&quot;check-box-bezel.png&quot; size:CGSizeMake(15.0, 15.0)]),
+        bezelColorSelected = PatternColor([_CPCibCustomResource imageResourceWithName:&quot;check-box-bezel-selected.png&quot; size:CGSizeMake(15.0, 16.0)]);
+    
+    [button setValue:CPLeftTextAlignment forThemeAttribute:@&quot;alignment&quot; inState:CPThemeStateBordered];
+    [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@&quot;font&quot; inState:CPThemeStateBordered];
+    [button setValue:CGInsetMake(0.0, 0.0, 0.0, 20.0) forThemeAttribute:@&quot;content-inset&quot; inState:CPThemeStateBordered];
+    [button setValue:bezelColor forThemeAttribute:@&quot;bezel-color&quot; inState:CPThemeStateBordered];    
+    [button setValue:bezelColorSelected forThemeAttribute:@&quot;bezel-color&quot; inState:CPThemeStateBordered | CPThemeStateSelected];
+
+    return button;
+}
+
 + (CPPopUpButton)themedPopUpButton
 {
     var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0) pullsDown:NO],</diff>
      <filename>AppKit/Themes/Aristo/ThemeDescriptors.j</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>738d9186a6775f6542f1187e69ac5f6ea06660c5</id>
    </parent>
  </parents>
  <author>
    <name>Francisco Tolmasky</name>
    <email>francisco@280north.com</email>
  </author>
  <url>http://github.com/280north/cappuccino/commit/94f83a92b7d356552f8c7ba484f3a1928160481c</url>
  <id>94f83a92b7d356552f8c7ba484f3a1928160481c</id>
  <committed-date>2009-05-16T15:53:49-07:00</committed-date>
  <authored-date>2009-05-16T15:53:49-07:00</authored-date>
  <message>Added Radio and checkbox classes.

Remaining works:
- Fix artwork issue
- nib2cib support

Closes #77.

Reviewed by me.</message>
  <tree>481b87b2d0adbc63a0be6716a790532e4de7c58f</tree>
  <committer>
    <name>Francisco Tolmasky</name>
    <email>francisco@280north.com</email>
  </committer>
</commit>
