Skip to content

Commit

Permalink
Add segmented controls to Aristo
Browse files Browse the repository at this point in the history
  • Loading branch information
Ross Boucher committed May 7, 2009
1 parent ae8fd0c commit 3d2cf3f
Show file tree
Hide file tree
Showing 20 changed files with 215 additions and 1 deletion.
140 changes: 139 additions & 1 deletion AppKit/CPSegmentedControl.j
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

@import "CPControl.j"

#include "CoreGraphics/CGGeometry.h"

/*
@global
@group CPSegmentSwitchTracking
Expand All @@ -47,6 +49,8 @@ CPSegmentSwitchTrackingMomentary = 2;
@implementation CPSegmentedControl : CPControl
{
CPArray _segments;
CPArray _controlStates;

int _selectedSegment;
int _segmentStyle;
CPSegmentSwitchTracking _trackingMode;
Expand All @@ -55,9 +59,16 @@ CPSegmentSwitchTrackingMomentary = 2;
BOOL _trackingHighlighted;
}

+ (id)themedAttributes
{
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"]];
}

- (id)initWithFrame:(CGRect)aRect
{
_segments = [];
_controlStates = [];

self = [super initWithFrame:aRect];

Expand Down Expand Up @@ -99,6 +110,8 @@ CPSegmentSwitchTrackingMomentary = 2;
{
_segments[index] = [[_CPSegmentItem alloc] init];
_segments[index].frame.size.height = height;

_controlStates[index] = CPControlStateNormal;
}
}
else if (aCount < _segments.length)
Expand Down Expand Up @@ -371,6 +384,8 @@ CPSegmentSwitchTrackingMomentary = 2;

segment.selected = isSelected;

_controlStates[aSegment] = isSelected ? CPControlStateSelected : CPControlStateNormal;

// We need to do some cleanup if we only allow one selection.
if (isSelected)
{
Expand All @@ -381,13 +396,16 @@ CPSegmentSwitchTrackingMomentary = 2;
if (_trackingMode == CPSegmentSwitchTrackingSelectOne && oldSelectedSegment != aSegment && oldSelectedSegment != -1)
{
_segments[oldSelectedSegment].selected = NO;
_controlStates[oldSelectedSegment] = CPControlStateNormal;

[self drawSegmentBezel:oldSelectedSegment highlight:NO];
}
}

if (_trackingMode != CPSegmentSwitchTrackingMomentary)
[self drawSegmentBezel:aSegment highlight:NO];

[self setNeedsLayout];
}

/*!
Expand Down Expand Up @@ -448,8 +466,124 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (void)drawSegmentBezel:(int)aSegment highlight:(BOOL)shouldHighlight
{
if (shouldHighlight)
_controlStates[aSegment] |= CPControlStateHighlighted;
else
_controlStates[aSegment] &= ~CPControlStateHighlighted;

[self setNeedsLayout];
}

- (float)_leftOffsetForSegment:(unsigned)segment
{
var bezelInset = [self currentValueForThemedAttributeName:@"bezel-inset"];

if (segment == 0)
return bezelInset.left;

var thickness = [self currentValueForThemedAttributeName:@"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"],
bounds = [self bounds];

if (aName === "left-segment-bezel")
{
return CGRectMake(bezelInset.left, bezelInset.top, contentInset.left, height);
}
else if (aName === "right-segment-bezel")
{
return CGRectMake(CGRectGetMaxX(bounds) - contentInset.right, bezelInset.top, contentInset.right, height);
}
else if (aName.substring(0, "segment-bezel".length) == "segment-bezel")
{
var segment = parseInt(aName.substring("segment-bezel-".length), 10),
width = [self widthForSegment:segment],
left = [self _leftOffsetForSegment:segment];

if (_segments.length == 1)
return CGRectMake(left + contentInset.left, bezelInset.top, width - contentInset.left - contentInset.right, height);
else if (segment == 0)
return CGRectMake(left + contentInset.left, bezelInset.top, width - contentInset.left, height);
else if (segment == _segments.length - 1)
return CGRectMake(left, bezelInset.top, width - contentInset.right, height);
else
return CGRectMake(left, bezelInset.top, width, height);
}
else if (aName.substring(0, "divider-bezel".length) == "divider-bezel")
{
var segment = parseInt(aName.substring("divider-bezel-".length), 10),
width = [self widthForSegment:segment],
left = [self _leftOffsetForSegment:segment],
thickness = [self currentValueForThemedAttributeName:@"divider-thickness"];

return CGRectMake(left + width, bezelInset.top, thickness, height);
}

return [super rectForEphemeralSubviewNamed:aName];
}

- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
return [[CPView alloc] initWithFrame:_CGRectMakeZero()];
}

- (void)layoutSubviews
{
var leftCapColor = [self valueForThemedAttributeName:@"left-segment-bezel-color"
inControlState:_controlStates[0]];

var leftBezelView = [self layoutEphemeralSubviewNamed:@"left-segment-bezel"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];

[leftBezelView setBackgroundColor:leftCapColor];

var rightCapColor = [self valueForThemedAttributeName:@"right-segment-bezel-color"
inControlState:_controlStates[_controlStates.length - 1]];

var rightBezelView = [self layoutEphemeralSubviewNamed:@"right-segment-bezel"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];

[rightBezelView setBackgroundColor:rightCapColor];

for (var i=0, count = _controlStates.length; i<count; i++)
{
var bezelColor = [self valueForThemedAttributeName:@"center-segment-bezel-color"
inControlState:_controlStates[i]];

var bezelView = [self layoutEphemeralSubviewNamed:"segment-bezel-"+i
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];

[bezelView setBackgroundColor:bezelColor];

if (i == count - 1)
continue;

var borderState = _controlStates[i] | _controlStates[i+1];

borderState = (borderState & CPControlStateSelected & ~CPControlStateHighlighted) ? CPControlStateSelected : CPControlStateNormal;

var borderColor = [self valueForThemedAttributeName:@"divider-bezel-color"
inControlState:borderState];

var borderView = [self layoutEphemeralSubviewNamed:"divider-bezel-"+i
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];

[borderView setBackgroundColor:borderColor];
}
}


/*!
Draws the specified segment
@param aSegment the segment to draw
Expand Down Expand Up @@ -627,8 +761,8 @@ CPSegmentSwitchTrackingMomentary = 2;
{
_trackingHighlighted = YES;
_trackingSegment = [self testSegment:location];
CPLog.error("_trackingSegment="+_trackingSegment);


[self drawSegmentBezel:_trackingSegment highlight:YES];
}

Expand Down Expand Up @@ -680,6 +814,10 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
_segments = [aCoder decodeObjectForKey:CPSegmentedControlSegmentsKey];
_segmentStyle = [aCoder decodeIntForKey:CPSegmentedControlSegmentStyleKey];

_controlStates = [];
for (var i = 0; i < _segments.length; i++)
_controlStates[i] = 0;

if ([aCoder containsValueForKey:CPSegmentedControlSelectedKey])
_selectedSegment = [aCoder decodeIntForKey:CPSegmentedControlSelectedKey];
else
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
76 changes: 76 additions & 0 deletions AppKit/Themes/Aristo/ThemeDescriptors.j
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,82 @@
return button;
}

+ (CPPopUpButton)themedSegmentedControl
{
var segmentedControl = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 24.0)];

[segmentedControl setTrackingMode:CPSegmentSwitchTrackingSelectAny];
[segmentedControl setSegmentCount:3];

[segmentedControl setWidth:40.0 forSegment:0];
[segmentedControl setLabel:@"foo" forSegment:0];
[segmentedControl setTag:1 forSegment:0];

[segmentedControl setWidth:60.0 forSegment:1];
[segmentedControl setLabel:@"bar" forSegment:1];
[segmentedControl setTag:2 forSegment:1];

[segmentedControl setWidth:25.0 forSegment:2];
[segmentedControl setLabel:@"1" forSegment:2];
[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)]];

[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: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: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: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:CGInsetMake(0.0, 4.0, 0.0, 4.0) forThemedAttributeName:@"content-inset" inControlState:CPControlStateNormal];

[segmentedControl setValue:CGInsetMake(0.0, 0.0, 0.0, 0.0) forThemedAttributeName:@"bezel-inset" inControlState:CPControlStateNormal];

[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: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],
Expand Down

0 comments on commit 3d2cf3f

Please sign in to comment.