24 @
typedef CPTabViewType
46 - (void)tabViewDidChangeNumberOfTabViewItems:(
CPTabView)tabView;
71 id <CPTabViewDelegate> _delegate;
72 unsigned _delegateSelectors;
75 - (id)initWithFrame:(CGRect)aFrame
77 if (
self = [super initWithFrame:aFrame])
80 _selectedTabViewItem = nil;
90 [_tabs setHitTests:NO];
91 [_tabs setSegments:[CPArray array]];
93 var height = [_tabs valueForThemeAttribute:@"min-size"].height;
94 [_tabs setFrameSize:CGSizeMake(0, height)];
96 _box = [[_CPTabViewBox alloc] initWithFrame:[
self bounds]];
97 [_box setTabView:self];
103 _placeHolderView = nil;
108 return [_tabs segments];
126 - (void)insertTabViewItem:(
CPTabViewItem)aTabViewItem atIndex:(CPUInteger)anIndex
135 [_tabs insertSegments:tabViewItems atIndexes:indexes];
136 [
tabViewItems makeObjectsPerformSelector:@selector(_setTabView:) withObject:self];
139 [
self _reverseSetContent];
141 [
self _sendDelegateTabViewDidChangeNumberOfTabViewItems];
145 [
self _selectTabViewItemAtIndex:0];
154 var idx = [[
self items] indexOfObjectIdenticalTo:aTabViewItem];
160 [aTabViewItem _setTabView:nil];
163 [
self _didRemoveTabViewItem:aTabViewItem atIndex:idx];
164 [
self _reverseSetContent];
166 [
self _sendDelegateTabViewDidChangeNumberOfTabViewItems];
169 - (void)_didRemoveTabViewItem:(
CPTabViewItem)aTabViewItem atIndex:(CPInteger)idx
172 if ([
self _isSelectionBinded])
175 if (_selectedTabViewItem == aTabViewItem)
185 _selectedTabViewItem == nil;
197 return [[
self items] indexOfObjectIdenticalTo:aTabViewItem];
205 - (int)indexOfTabViewItemWithIdentifier:(
CPString)anIdentifier
207 return [[
self items] indexOfObjectPassingTest:function(item, idx, stop)
209 return [[item identifier] isEqual:anIdentifier];
219 return [[
self items] count];
228 return [[
self items] objectAtIndex:anIndex];
237 return [[
self items] copy];
245 - (void)selectFirstTabViewItem:(
id)aSender
257 - (void)selectLastTabViewItem:(
id)aSender
269 - (void)selectNextTabViewItem:(
id)aSender
271 if (_selectedTabViewItem === nil)
287 - (void)selectPreviousTabViewItem:(
id)aSender
289 if (_selectedTabViewItem === nil)
294 if (previousIndex < 0)
313 - (BOOL)selectTabViewItemAtIndex:(CPUInteger)anIndex
315 if (![
self _selectTabViewItemAtIndex:anIndex])
318 [
self _reverseSetSelectedIndex];
324 - (BOOL)_selectTabViewItemAtIndex:(CPUInteger)anIndex
328 if (aTabViewItem == _selectedTabViewItem)
331 if (![
self _sendDelegateShouldSelectTabViewItem:aTabViewItem])
334 [
self _sendDelegateWillSelectTabViewItem:aTabViewItem];
336 [_tabs setSelectedSegment:anIndex];
337 _selectedTabViewItem = aTabViewItem;
338 [
self _loadTabViewItem:aTabViewItem];
340 [
self _sendDelegateDidSelectTabViewItem:aTabViewItem];
349 if (controller !== nil && ![controller isViewLoaded])
351 [controller loadViewWithCompletionHandler:function(view, error)
355 CPLog.warn("Could not load the view for item " + aTabViewItem + ". " + error);
357 else if (view !== nil)
362 [
self _displayItemView:view];
368 [
self _displayItemView:[aTabViewItem
view]];
378 return _selectedTabViewItem;
401 [_tabs setFont:_font];
409 - (void)setTabViewType:(CPTabViewType)aTabViewType
411 if (_type === aTabViewType)
414 _type = aTabViewType;
417 [_tabs removeFromSuperview];
426 [_box setBorderType:CPBezelBorder];
429 [_box setBorderType:CPLineBorder];
432 [_box setBorderType:CPNoBorder];
442 [_tabs tileWithChangedSegment:segment];
453 [_box setFrame:[
self bounds]];
457 var aFrame = [
self frame],
458 segmentedHeight = CGRectGetHeight([_tabs
frame]),
461 [_box setFrame:CGRectMake(0, origin, CGRectGetWidth(aFrame),
462 CGRectGetHeight(aFrame) - segmentedHeight / 2)];
464 [
self _repositionTabs];
490 - (void)setDelegate:(
id <CPTabViewDelegate>)aDelegate
492 if (_delegate == aDelegate)
495 _delegate = aDelegate;
497 _delegateSelectors = 0;
499 if ([_delegate respondsToSelector:
@selector(tabView:shouldSelectTabViewItem:)])
502 if ([_delegate respondsToSelector:
@selector(tabView:willSelectTabViewItem:)])
505 if ([_delegate respondsToSelector:
@selector(tabView:didSelectTabViewItem:)])
508 if ([_delegate respondsToSelector:
@selector(tabViewDidChangeNumberOfTabViewItems:)])
514 [_box setBackgroundColor:aColor];
519 return [_box backgroundColor];
524 var segmentIndex = [_tabs testSegment:[_tabs convertPoint:[anEvent
locationInWindow] fromView:nil]];
526 if (segmentIndex !=
CPNotFound && [
self selectTabViewItemAtIndex:segmentIndex])
527 [_tabs trackSegment:anEvent];
530 - (void)_repositionTabs
532 var horizontalCenterOfSelf = CGRectGetWidth([
self bounds]) / 2,
533 verticalCenterOfTabs = CGRectGetHeight([_tabs
bounds]) / 2;
536 [_tabs setCenter:CGPointMake(horizontalCenterOfSelf, CGRectGetHeight([
self bounds]) - verticalCenterOfTabs)];
538 [_tabs setCenter:CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)];
541 - (void)_displayItemView:(
CPView)aView
543 [_box setContentView:aView];
548 - (BOOL)_sendDelegateShouldSelectTabViewItem:(
CPTabViewItem)aTabViewItem
551 return [_delegate tabView:self shouldSelectTabViewItem:aTabViewItem];
556 - (void)_sendDelegateWillSelectTabViewItem:(
CPTabViewItem)aTabViewItem
559 [_delegate tabView:self willSelectTabViewItem:aTabViewItem];
562 - (void)_sendDelegateDidSelectTabViewItem:(
CPTabViewItem)aTabViewItem
565 [_delegate tabView:self didSelectTabViewItem:aTabViewItem];
568 - (void)_sendDelegateTabViewDidChangeNumberOfTabViewItems
571 [_delegate tabViewDidChangeNumberOfTabViewItems:self];
578 + (Class)_binderClassForBinding:(
CPString)aBinding
581 return [_CPTabViewContentBinder class];
583 return [_CPTabViewSelectionBinder class];
585 return [
super _binderClassForBinding:aBinding];
593 - (void)_reverseSetContent
596 [theBinder reverseSetValueFor:@"items"];
599 - (void)_reverseSetSelectedIndex
603 if (theBinder !== nil)
604 [theBinder reverseSetValueFor:@"selectionIndexes"];
608 [theBinder reverseSetValueFor:@"selectedIndex"];
614 var cls = [[
self class] _binderClassForBinding:aBinding]
615 return [cls getBinding:aBinding forObject:self];
618 - (BOOL)_isSelectionBinded
623 - (void)setItems:(CPArray)tabViewItems
628 [[
self items] makeObjectsPerformSelector:@selector(_setTabView:) withObject:nil];
629 [_tabs setSegments:tabViewItems];
630 [
tabViewItems makeObjectsPerformSelector:@selector(_setTabView:) withObject:self];
643 [_tabs setSelectedSegment:-1];
644 _selectedTabViewItem = nil;
647 - (void)_displayPlaceholder:(
CPString)aPlaceholder
649 if (_placeHolderView == nil)
651 _placeHolderView = [[
CPView alloc] initWithFrame:CGRectMakeZero()];
652 var textField = [[
CPTextField alloc] initWithFrame:CGRectMakeZero()];
653 [textField setTag:1000];
656 [_placeHolderView addSubview:textField];
659 var textField = [_placeHolderView viewWithTag:1000];
660 [textField setStringValue:aPlaceholder];
661 [textField sizeToFit];
663 var boxBounds = [_box bounds],
664 textFieldBounds = [textField bounds],
665 origin = CGPointMake(CGRectGetWidth(boxBounds)/2 - CGRectGetWidth(textFieldBounds)/2, CGRectGetHeight(boxBounds)/2 - CGRectGetHeight(textFieldBounds));
667 [textField setFrameOrigin:origin];
669 [
self _displayItemView:_placeHolderView];
673 #pragma mark Override 685 var _CPTabViewContentBinderNull =
@"NO CONTENT";
686 @implementation _CPTabViewContentBinder :
CPBinder 691 - (void)_updatePlaceholdersWithOptions:(
CPDictionary)options
693 [
super _updatePlaceholdersWithOptions:options];
694 [
self _setPlaceholder:_CPTabViewContentBinderNull forMarker:CPNullMarker isDefault:YES];
697 - (void)setPlaceholderValue:(
id)aValue withMarker:(
CPString)aMarker forBinding:(
CPString)aBinding
699 [_source setItems:@[]];
700 [_source _setPlaceholderView:aValue];
703 - (void)setValue:(
id)aValue forBinding:(
CPString)aBinding
705 [_source setItems:aValue];
708 - (id)valueForBinding:(
CPString)aBinding
710 return [_source items];
715 var _CPTabViewSelectionBinderMultipleValues =
@"Multiple Selection",
716 _CPTabViewSelectionBinderNoSelection =
@"No Selection";
717 @implementation _CPTabViewSelectionBinder :
CPBinder 722 - (void)_updatePlaceholdersWithOptions:(
CPDictionary)options
724 [
super _updatePlaceholdersWithOptions:options];
726 [
self _setPlaceholder:_CPTabViewSelectionBinderMultipleValues forMarker:CPMultipleValuesMarker isDefault:YES];
727 [
self _setPlaceholder:_CPTabViewSelectionBinderNoSelection forMarker:CPNoSelectionMarker isDefault:YES];
730 - (void)setPlaceholderValue:(
id)aValue withMarker:(
CPString)aMarker forBinding:(
CPString)aBinding
733 [_source _deselectAll];
735 [_source _displayPlaceholder:aValue];
738 - (void)setValue:(
id)aValue forBinding:(
CPString)aBinding
742 if (aValue == nil || [aValue count] == 0)
744 [_source _deselectAll];
745 [_source _displayPlaceholder:_CPTabViewSelectionBinderNoSelection];
747 else if ([aValue count] > 1)
748 [_source _displayPlaceholder:_CPTabViewSelectionBinderMultipleValues];
750 [_source _selectTabViewItemAtIndex:[aValue firstIndex]];
756 [_source _deselectAll];
757 [_source _displayPlaceholder:_CPTabViewSelectionBinderNoSelection];
760 [_source _selectTabViewItemAtIndex:aValue];
764 - (id)valueForBinding:(
CPString)aBinding
769 idx = [_source indexOfTabViewItem:[_source selectedTabViewItem]];
772 [result addIndex:idx];
777 return [_source indexOfTabViewItem:[_source selectedTabViewItem]];
792 if (
self = [super initWithCoder:aCoder])
796 _font = [aCoder decodeObjectForKey:CPTabViewFontKey];
797 [_tabs setFont:_font];
799 var
items = [aCoder decodeObjectForKey:CPTabViewItemsKey] || [CPArray array];
802 [
self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]];
804 _selectedTabViewItem = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
806 _type = [aCoder decodeIntForKey:CPTabViewTypeKey];
814 [
super awakeFromCib];
819 if (_selectedTabViewItem)
827 _selectedTabViewItem = nil;
846 [_box removeFromSuperview];
850 [aCoder encodeObject:_items forKey:CPTabViewItemsKey];
852 [aCoder encodeConditionalObject:_selectedTabViewItem forKey:CPTabViewSelectedItemKey];
854 [aCoder encodeInt:_type forKey:CPTabViewTypeKey];
855 [aCoder encodeObject:_font forKey:CPTabViewFontKey];
857 [aCoder encodeConditionalObject:_delegate forKey:CPTabViewDelegateKey];
862 @implementation _CPTabViewBox :
CPBox 869 #pragma mark Override 871 - (
CPView)hitTest:(CGPoint)aPoint
875 var segmentIndex = [_tabView._tabs testSegment:[_tabView._tabs convertPoint:aPoint fromView:[
self superview]]];
void setView:(CPView aView)
var CPTabViewWillSelectTabViewItemSelector
void addSubview:(CPView aSubview)
A CALayer is similar to a CPView
int indexOfTabViewItem:(CPTabViewItem aTabViewItem)
void setBackgroundColor:(CPColor aColor)
CPViewController viewController()
CPFont boldFontWithName:size:italic:(CPString aName, [size] float aSize, [italic] BOOL italic)
CGPoint locationInWindow()
A collection of unique integers.
CPView hitTest:(CGPoint aPoint)
A mutable key-value pair collection.
CPTabViewType CPTopTabsBezelBorder
An immutable string (collection of characters).
CPColor colorWithCalibratedWhite:alpha:(float white, [alpha] float alpha)
CPTabViewItem selectedTabViewItem()
void encodeWithCoder:(CPCoder aCoder)
var CPTabViewDidChangeNumberOfTabViewItemsSelector
void setSubviews:(CPArray newSubviews)
void setTabViewType:(CPTabViewType aTabViewType)
Defines methods for use when archiving & restoring (enc/decoding).
var CPTabViewSelectedItemKey
BOOL selectTabViewItemAtIndex:(CPUInteger anIndex)
CPTabViewType tabViewType()
void tileWithChangedItem:(CPTabViewItem aTabViewItem)
var CPTabViewDidSelectTabViewItemSelector
CPBinder binderForBinding:(CPString aBinding)
void setDelegate:(id< CPTabViewDelegate > aDelegate)
CPColor backgroundColor()
id indexSetWithIndexesInRange:(CPRange aRange)
CPTabViewItem tabViewItemAtIndex:(CPUInteger anIndex)
id indexSetWithIndex:(int anIndex)
void insertTabViewItem:atIndex:(CPTabViewItem aTabViewItem, [atIndex] CPUInteger anIndex)
CPSelectionIndexesBinding
var CPTabViewShouldSelectTabViewItemSelector
unsigned numberOfTabViewItems()