Clean up several flaws in CPTabView:

- should not force empty space above and below, but only where the tabs are
- box should fill frame when no tabs are present
- ivars should be prefixed with underscore
- not sure about the current background color code, may revisit
This commit is contained in:
Ross Boucher
2010-12-15 15:48:42 -08:00
parent 8aeaa6681a
commit ab083a3baf
2 changed files with 120 additions and 126 deletions
+117 -123
View File
@@ -3,87 +3,64 @@
@import "CPTabViewItem.j"
@import "CPView.j"
/*
Places tabs on top with a bezeled border.
@global
@group CPTabViewType
*/
CPTopTabsBezelBorder = 0;
//CPLeftTabsBezelBorder = 1;
//CPLeftTabsBezelBorder = 1;
CPBottomTabsBezelBorder = 2;
//CPRightTabsBezelBorder = 3;
/*
Displays no tabs and has a bezeled border.
@global
@group CPTabViewType
*/
CPNoTabsBezelBorder = 4;
/*
Has no tabs and displays a line border.
@global
@group CPTabViewType
*/
CPNoTabsLineBorder = 5;
/*
Displays no tabs and no border.
@global
@group CPTabViewType
*/
CPNoTabsNoBorder = 6;
//CPRightTabsBezelBorder = 3;
CPNoTabsBezelBorder = 4; //Displays no tabs and has a bezeled border.
CPNoTabsLineBorder = 5; //Has no tabs and displays a line border.
CPNoTabsNoBorder = 6; //Displays no tabs and no border.
var CPTabViewDidSelectTabViewItemSelector = 1,
CPTabViewShouldSelectTabViewItemSelector = 2,
CPTabViewWillSelectTabViewItemSelector = 4,
CPTabViewDidChangeNumberOfTabViewItemsSelector = 8;
var HEIGHT_OF_SEGMENTED_CONTROL = 24;
@implementation CPTabView : CPView
{
CPArray items;
CPArray _items;
CPSegmentedControl tabs;
CPBox box;
CPSegmentedControl _tabs;
CPBox _box;
CPNumber selectedIndex;
CPNumber _selectedIndex;
CPTabViewType type;
CPTabViewType _type;
id delegate;
unsigned delegateSelectors;
id _delegate;
unsigned _delegateSelectors;
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if (self)
if (self = [super initWithFrame:aFrame])
{
items = [CPArray array];
selectedIndex = CPNotFound;
[self setTabViewType:CPTopTabsBezelBorder];
_items = [CPArray array];
_selectedIndex = CPNotFound;
[self _init];
[self setTabViewType:CPTopTabsBezelBorder];
}
return self;
}
- (void)_init
{
tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 0, HEIGHT_OF_SEGMENTED_CONTROL)];
[tabs setHitTests:NO];
var aFrame = [self frame];
box = [[CPBox alloc] initWithFrame:CGRectMake(0, HEIGHT_OF_SEGMENTED_CONTROL / 2, CGRectGetWidth(aFrame),
CGRectGetHeight(aFrame) - HEIGHT_OF_SEGMENTED_CONTROL)];
_tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[_tabs setHitTests:NO];
var height = [_tabs valueForThemeAttribute:@"default-height"];
[_tabs setFrameSize:CGSizeMake(0, height)];
_box = [[CPBox alloc] initWithFrame:[self bounds]];
[self setBackgroundColor:[CPColor colorWithCalibratedWhite:0.95 alpha:1.0]];
[box setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[tabs setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin];
[_box setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[_tabs setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin];
[self addSubview:box];
[self addSubview:tabs];
[self addSubview:_box];
[self addSubview:_tabs];
}
// Adding and Removing Tabs
@@ -93,7 +70,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (void)addTabViewItem:(CPTabViewItem)aTabViewItem
{
[self insertTabViewItem:aTabViewItem atIndex:[items count]];
[self insertTabViewItem:aTabViewItem atIndex:[_items count]];
}
/*!
@@ -104,13 +81,13 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(unsigned)anIndex
{
[items insertObject:aTabViewItem atIndex:anIndex];
[_items insertObject:aTabViewItem atIndex:anIndex];
[self _updateItems];
[self _repositionTabs];
if (delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
[delegate tabViewDidChangeNumberOfTabViewItems:self];
if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
[_delegate tabViewDidChangeNumberOfTabViewItems:self];
}
/*!
@@ -119,19 +96,21 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (void)removeTabViewItem:(CPTabViewItem)aTabViewItem
{
for (var i = 0; i < [items count]; i++)
var count = [_items count];
for (var i = 0; i < count; i++)
{
if ([items objectAtIndex:i] === aTabViewItem)
{
[items removeObjectAtIndex:i];
break;
}
}
[self _updateItems];
[self _repositionTabs];
if (delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
[delegate tabViewDidChangeNumberOfTabViewItems:self];
if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
[_delegate tabViewDidChangeNumberOfTabViewItems:self];
}
// Accessing Tabs
@@ -141,7 +120,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (int)indexOfTabViewItem:(CPTabViewItem)aTabViewItem
{
return [items indexOfObjectIdenticalTo:aTabViewItem];
return [_items indexOfObjectIdenticalTo:aTabViewItem];
}
/*!
@@ -150,8 +129,8 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (int)indexOfTabViewItemWithIdentifier:(CPString)anIdentifier
{
for (var index = [items count]; index >= 0; index--)
if ([[items[index] identifier] isEqual:anIdentifier])
for (var index = [_items count]; index >= 0; index--)
if ([[_items[index] identifier] isEqual:anIdentifier])
return index;
return CPNotFound;
@@ -162,7 +141,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (unsigned)numberOfTabViewItems
{
return [items count];
return [_items count];
}
/*!
@@ -170,7 +149,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (CPTabViewItem)tabViewItemAtIndex:(unsigned)anIndex
{
return [items objectAtIndex:anIndex];
return [_items objectAtIndex:anIndex];
}
/*!
@@ -178,7 +157,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (CPArray)tabViewItems
{
return [items copy]; // Copy?
return [_items copy]; // Copy?
}
// Selecting a Tab
@@ -188,7 +167,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (void)selectFirstTabViewItem:(id)aSender
{
if ([items count] === 0)
if ([_items count] === 0)
return; // throw?
[self selectTabViewItemAtIndex:0];
@@ -200,10 +179,10 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (void)selectLastTabViewItem:(id)aSender
{
if ([items count] === 0)
if ([_items count] === 0)
return; // throw?
[self selectTabViewItemAtIndex:[items count] - 1];
[self selectTabViewItemAtIndex:[_items count] - 1];
}
/*!
@@ -212,12 +191,12 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (void)selectNextTabViewItem:(id)aSender
{
if (selectedIndex === CPNotFound)
if (_selectedIndex === CPNotFound)
return;
var nextIndex = selectedIndex + 1;
var nextIndex = _selectedIndex + 1;
if (nextIndex === [items count])
if (nextIndex === [_items count])
// does nothing. According to spec at (http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/ApplicationKit/Classes/NSTabView_Class/Reference/Reference.html#//apple_ref/occ/instm/NSTabView/selectNextTabViewItem:)
return;
@@ -230,10 +209,10 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (void)selectPreviousTabViewItem:(id)aSender
{
if (selectedIndex === CPNotFound)
if (_selectedIndex === CPNotFound)
return;
var previousIndex = selectedIndex - 1;
var previousIndex = _selectedIndex - 1;
if (previousIndex < 0)
return; // does nothing. See above.
@@ -256,24 +235,24 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (void)selectTabViewItemAtIndex:(unsigned)anIndex
{
var aTabViewItem = [items objectAtIndex:anIndex];
var aTabViewItem = [_items objectAtIndex:anIndex];
if (anIndex === selectedIndex)
if (anIndex === _selectedIndex)
return;
var aTabViewItem = [self tabViewItemAtIndex:anIndex];
if ((delegateSelectors & CPTabViewShouldSelectTabViewItemSelector) && ![delegate tabView:self shouldSelectTabViewItem:aTabViewItem])
if ((_delegateSelectors & CPTabViewShouldSelectTabViewItemSelector) && ![delegate tabView:self shouldSelectTabViewItem:aTabViewItem])
return;
if (delegateSelectors & CPTabViewWillSelectTabViewItemSelector)
[delegate tabView:self willSelectTabViewItem:aTabViewItem];
if (_delegateSelectors & CPTabViewWillSelectTabViewItemSelector)
[_delegate tabView:self willSelectTabViewItem:aTabViewItem];
[tabs selectSegmentWithTag:anIndex];
[_tabs selectSegmentWithTag:anIndex];
[self _setSelectedIndex:anIndex];
if (delegateSelectors & CPTabViewDidSelectTabViewItemSelector)
[delegate tabView:self didSelectTabViewItem:aTabViewItem];
if (_delegateSelectors & CPTabViewDidSelectTabViewItemSelector)
[_delegate tabView:self didSelectTabViewItem:aTabViewItem];
}
/*!
@@ -281,7 +260,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (CPTabViewItem)selectedTabViewItem
{
return [items objectAtIndex:selectedIndex];
return [_items objectAtIndex:_selectedIndex];
}
//
@@ -291,31 +270,40 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (void)setTabViewType:(CPTabViewType)aTabViewType
{
if (type === aTabViewType)
if (_type === aTabViewType)
return;
if ((type === CPTopTabsBezelBorder || type === CPBottomTabsBezelBorder)
&& (aTabViewType !== CPTopTabsBezelBorder && aTabViewType !== CPBottomTabsBezelBorder))
[tabs removeFromSuperview];
_type = aTabViewType;
if ((type === CPNoTabsBezelBorder || type === CPNoTabsLineBorder || type === CPNoTabsNoBorder)
&& (aTabViewType !== CPNoTabsBezelBorder && aTabViewType !== CPNoTabsBezelBorder && aTabViewType !== CPNoTabsNoBorder))
[self addSubview:tabs];
if (_type !== CPTopTabsBezelBorder && _type !== CPBottomTabsBezelBorder)
{
[_box setFrame:[self bounds]];
[_tabs removeFromSuperview];
}
else
{
var aFrame = [self frame],
segmentedHeight = CGRectGetHeight([_tabs frame]),
origin = _type === CPTopTabsBezelBorder ? segmentedHeight / 2 : 0;
type = aTabViewType;
[_box setFrame:CGRectMake(0, origin, CGRectGetWidth(aFrame),
CGRectGetHeight(aFrame) - segmentedHeight / 2)];
switch (type)
[self addSubview:_tabs];
}
switch (_type)
{
case CPTopTabsBezelBorder:
case CPBottomTabsBezelBorder:
case CPNoTabsBezelBorder:
[box setBorderType:CPBezelBorder];
[_box setBorderType:CPBezelBorder];
break;
case CPNoTabsLineBorder:
[box setBorderType:CPLineBorder];
[_box setBorderType:CPLineBorder];
break;
case CPNoTabsNoBorder:
[box setBorderType:CPNoBorder];
[_box setBorderType:CPNoBorder];
break;
}
}
@@ -325,7 +313,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (CPTabViewType)tabViewType
{
return type;
return _type;
}
/*!
@@ -333,7 +321,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (id)delegate
{
return delegate;
return _delegate;
}
/*!
@@ -342,71 +330,77 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
*/
- (void)setDelegate:(id)aDelegate
{
if (delegate == aDelegate)
if (_delegate == aDelegate)
return;
delegate = aDelegate;
_delegate = aDelegate;
delegateSelectors = 0;
_delegateSelectors = 0;
if ([delegate respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)])
delegateSelectors |= CPTabViewShouldSelectTabViewItemSelector;
if ([_delegate respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)])
_delegateSelectors |= CPTabViewShouldSelectTabViewItemSelector;
if ([delegate respondsToSelector:@selector(tabView:willSelectTabViewItem:)])
delegateSelectors |= CPTabViewWillSelectTabViewItemSelector;
if ([_delegate respondsToSelector:@selector(tabView:willSelectTabViewItem:)])
_delegateSelectors |= CPTabViewWillSelectTabViewItemSelector;
if ([delegate respondsToSelector:@selector(tabView:didSelectTabViewItem:)])
delegateSelectors |= CPTabViewDidSelectTabViewItemSelector;
if ([_delegate respondsToSelector:@selector(tabView:didSelectTabViewItem:)])
_delegateSelectors |= CPTabViewDidSelectTabViewItemSelector;
if ([delegate respondsToSelector:@selector(tabViewDidChangeNumberOfTabViewItems:)])
delegateSelectors |= CPTabViewDidChangeNumberOfTabViewItemsSelector;
if ([_delegate respondsToSelector:@selector(tabViewDidChangeNumberOfTabViewItems:)])
_delegateSelectors |= CPTabViewDidChangeNumberOfTabViewItemsSelector;
}
- (void)setBackgroundColor:(CPColor)aColor
{
[box setBackgroundColor:aColor];
[_box setBackgroundColor:aColor];
}
- (CPColor)backgroundColor
{
return [_box backgroundColor];
}
- (void)mouseDown:(CPEvent)anEvent
{
var segmentIndex = [tabs testSegment:[tabs convertPoint:[anEvent locationInWindow] fromView:nil]];
var segmentIndex = [_tabs testSegment:[_tabs convertPoint:[anEvent locationInWindow] fromView:nil]];
if (segmentIndex != CPNotFound)
{
[self selectTabViewItemAtIndex:segmentIndex];
[tabs trackSegment:anEvent];
[_tabs trackSegment:anEvent];
}
}
- (void)_repositionTabs
{
var horizontalCenterOfSelf = CGRectGetWidth([self bounds]) / 2,
verticalCenterOfTabs = CGRectGetHeight([tabs bounds]) / 2;
verticalCenterOfTabs = CGRectGetHeight([_tabs bounds]) / 2;
if (type === CPBottomTabsBezelBorder)
[tabs setCenter:CGPointMake(horizontalCenterOfSelf, CGRectGetHeight([self bounds]) - verticalCenterOfTabs)];
if (_type === CPBottomTabsBezelBorder)
[_tabs setCenter:CGPointMake(horizontalCenterOfSelf, CGRectGetHeight([self bounds]) - verticalCenterOfTabs)];
else
[tabs setCenter:CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)];
[_tabs setCenter:CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)];
}
- (void)_setSelectedIndex:(CPNumber)index
{
selectedIndex = index;
_selectedIndex = index;
[box setContentView:[[items objectAtIndex:selectedIndex] view]];
[_box setContentView:[[_items objectAtIndex:_selectedIndex] view]];
}
- (void)_updateItems
{
[tabs setSegmentCount:[items count]];
var count = [_items count];
[_tabs setSegmentCount:count];
for (var i = 0; i < [items count]; i++)
for (var i = 0; i < count; i++)
{
[tabs setLabel:[[items objectAtIndex:i] label] forSegment:i];
[tabs setTag:i forSegment:i];
[_tabs setLabel:[[_items objectAtIndex:i] label] forSegment:i];
[_tabs setTag:i forSegment:i];
}
if (selectedIndex === CPNotFound)
if (_selectedIndex === CPNotFound)
{
[self selectFirstTabViewItem:self];
}
@@ -427,7 +421,7 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
{
[self _init];
items = [aCoder decodeObjectForKey:CPTabViewItemsKey];
_items = [aCoder decodeObjectForKey:CPTabViewItemsKey];
[self _updateItems];
[self _repositionTabs];
@@ -448,12 +442,12 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:items forKey:CPTabViewItemsKey];
[aCoder encodeObject:_items forKey:CPTabViewItemsKey];
[aCoder encodeObject:[self selectedTabViewItem] forKey:CPTabViewSelectedItemKey];
[aCoder encodeInt:type forKey:CPTabViewTypeKey];
[aCoder encodeInt:_type forKey:CPTabViewTypeKey];
[aCoder encodeConditionalObject:delegate forKey:CPTabViewDelegateKey];
[aCoder encodeConditionalObject:_delegate forKey:CPTabViewDelegateKey];
}
@end
+3 -3
View File
@@ -7,12 +7,12 @@
- (CPSegmentedControl)tabs
{
return tabs;
return _tabs;
}
- (CPBox)box
{
return box;
return _box;
}
@end
@@ -73,7 +73,7 @@
tabs = [_tabView tabs];
[_tabView setFrame:CPRectMake(0, 0, 800, 800)];
[self assert:[box frameSize].height equals:800 - ([box frameOrigin].y) - [tabs frameSize].height / 2];
[self assert:[box frameSize].height equals:800 - [tabs frameSize].height / 2];
}