![]() |
API 0.9.5
|
00001 00002 CPTopTabsBezelBorder = 0; 00003 //CPLeftTabsBezelBorder = 1; 00004 CPBottomTabsBezelBorder = 2; 00005 //CPRightTabsBezelBorder = 3; 00006 CPNoTabsBezelBorder = 4; //Displays no tabs and has a bezeled border. 00007 CPNoTabsLineBorder = 5; //Has no tabs and displays a line border. 00008 CPNoTabsNoBorder = 6; //Displays no tabs and no border. 00009 00010 var CPTabViewDidSelectTabViewItemSelector = 1, 00011 CPTabViewShouldSelectTabViewItemSelector = 2, 00012 CPTabViewWillSelectTabViewItemSelector = 4, 00013 CPTabViewDidChangeNumberOfTabViewItemsSelector = 8; 00014 00023 @implementation CPTabView : CPView 00024 { 00025 CPArray _items; 00026 00027 CPSegmentedControl _tabs; 00028 CPBox _box; 00029 00030 CPNumber _selectedIndex; 00031 00032 CPTabViewType _type; 00033 CPFont _font; 00034 00035 id _delegate; 00036 unsigned _delegateSelectors; 00037 } 00038 00039 - (id)initWithFrame:(CGRect)aFrame 00040 { 00041 if (self = [super initWithFrame:aFrame]) 00042 { 00043 _items = [CPArray array]; 00044 _selectedIndex = CPNotFound; 00045 00046 [self _init]; 00047 [self setTabViewType:CPTopTabsBezelBorder]; 00048 } 00049 00050 return self; 00051 } 00052 00053 - (void)_init 00054 { 00055 _tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; 00056 [_tabs setHitTests:NO]; 00057 00058 var height = [_tabs valueForThemeAttribute:@"default-height"]; 00059 [_tabs setFrameSize:CGSizeMake(0, height)]; 00060 00061 _box = [[CPBox alloc] initWithFrame:[self bounds]]; 00062 [self setBackgroundColor:[CPColor colorWithCalibratedWhite:0.95 alpha:1.0]]; 00063 00064 [_box setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; 00065 [_tabs setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin]; 00066 00067 [self addSubview:_box]; 00068 [self addSubview:_tabs]; 00069 } 00070 00071 // Adding and Removing Tabs 00076 - (void)addTabViewItem:(CPTabViewItem)aTabViewItem 00077 { 00078 [self insertTabViewItem:aTabViewItem atIndex:[_items count]]; 00079 } 00080 00086 - (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(unsigned)anIndex 00087 { 00088 [_items insertObject:aTabViewItem atIndex:anIndex]; 00089 00090 [self _updateItems]; 00091 [self _repositionTabs]; 00092 00093 [aTabViewItem _setTabView:self]; 00094 00095 if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector) 00096 [_delegate tabViewDidChangeNumberOfTabViewItems:self]; 00097 } 00098 00103 - (void)removeTabViewItem:(CPTabViewItem)aTabViewItem 00104 { 00105 var count = [_items count]; 00106 for (var i = 0; i < count; i++) 00107 { 00108 if ([_items objectAtIndex:i] === aTabViewItem) 00109 { 00110 [_items removeObjectAtIndex:i]; 00111 break; 00112 } 00113 } 00114 00115 [self _updateItems]; 00116 [self _repositionTabs]; 00117 00118 [aTabViewItem _setTabView:nil]; 00119 00120 if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector) 00121 [_delegate tabViewDidChangeNumberOfTabViewItems:self]; 00122 } 00123 00124 // Accessing Tabs 00130 - (int)indexOfTabViewItem:(CPTabViewItem)aTabViewItem 00131 { 00132 return [_items indexOfObjectIdenticalTo:aTabViewItem]; 00133 } 00134 00140 - (int)indexOfTabViewItemWithIdentifier:(CPString)anIdentifier 00141 { 00142 for (var index = [_items count]; index >= 0; index--) 00143 if ([[_items[index] identifier] isEqual:anIdentifier]) 00144 return index; 00145 00146 return CPNotFound; 00147 } 00148 00153 - (unsigned)numberOfTabViewItems 00154 { 00155 return [_items count]; 00156 } 00157 00162 - (CPTabViewItem)tabViewItemAtIndex:(unsigned)anIndex 00163 { 00164 return [_items objectAtIndex:anIndex]; 00165 } 00166 00171 - (CPArray)tabViewItems 00172 { 00173 return [_items copy]; // Copy? 00174 } 00175 00176 // Selecting a Tab 00181 - (void)selectFirstTabViewItem:(id)aSender 00182 { 00183 if ([_items count] === 0) 00184 return; // throw? 00185 00186 [self selectTabViewItemAtIndex:0]; 00187 } 00188 00193 - (void)selectLastTabViewItem:(id)aSender 00194 { 00195 if ([_items count] === 0) 00196 return; // throw? 00197 00198 [self selectTabViewItemAtIndex:[_items count] - 1]; 00199 } 00200 00205 - (void)selectNextTabViewItem:(id)aSender 00206 { 00207 if (_selectedIndex === CPNotFound) 00208 return; 00209 00210 var nextIndex = _selectedIndex + 1; 00211 00212 if (nextIndex === [_items count]) 00213 // 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:) 00214 return; 00215 00216 [self selectTabViewItemAtIndex:nextIndex]; 00217 } 00218 00223 - (void)selectPreviousTabViewItem:(id)aSender 00224 { 00225 if (_selectedIndex === CPNotFound) 00226 return; 00227 00228 var previousIndex = _selectedIndex - 1; 00229 00230 if (previousIndex < 0) 00231 return; // does nothing. See above. 00232 00233 [self selectTabViewItemAtIndex:previousIndex]; 00234 } 00235 00240 - (void)selectTabViewItem:(CPTabViewItem)aTabViewItem 00241 { 00242 [self selectTabViewItemAtIndex:[self indexOfTabViewItem:aTabViewItem]]; 00243 } 00244 00249 - (void)selectTabViewItemAtIndex:(unsigned)anIndex 00250 { 00251 var aTabViewItem = [_items objectAtIndex:anIndex]; 00252 00253 if (anIndex === _selectedIndex) 00254 return; 00255 00256 var aTabViewItem = [self tabViewItemAtIndex:anIndex]; 00257 00258 if ((_delegateSelectors & CPTabViewShouldSelectTabViewItemSelector) && ![_delegate tabView:self shouldSelectTabViewItem:aTabViewItem]) 00259 return; 00260 00261 if (_delegateSelectors & CPTabViewWillSelectTabViewItemSelector) 00262 [_delegate tabView:self willSelectTabViewItem:aTabViewItem]; 00263 00264 [_tabs selectSegmentWithTag:anIndex]; 00265 [self _setSelectedIndex:anIndex]; 00266 00267 if (_delegateSelectors & CPTabViewDidSelectTabViewItemSelector) 00268 [_delegate tabView:self didSelectTabViewItem:aTabViewItem]; 00269 } 00270 00275 - (CPTabViewItem)selectedTabViewItem 00276 { 00277 return [_items objectAtIndex:_selectedIndex]; 00278 } 00279 00280 // Modifying the font 00285 - (CPFont)font 00286 { 00287 return _font; 00288 } 00289 00294 - (void)setFont:(CPFont)font 00295 { 00296 if ([_font isEqual:font]) 00297 return; 00298 00299 _font = font; 00300 [_tabs setFont:_font]; 00301 } 00302 00303 // 00308 - (void)setTabViewType:(CPTabViewType)aTabViewType 00309 { 00310 if (_type === aTabViewType) 00311 return; 00312 00313 _type = aTabViewType; 00314 00315 if (_type !== CPTopTabsBezelBorder && _type !== CPBottomTabsBezelBorder) 00316 { 00317 [_box setFrame:[self bounds]]; 00318 [_tabs removeFromSuperview]; 00319 } 00320 else 00321 { 00322 var aFrame = [self frame], 00323 segmentedHeight = CGRectGetHeight([_tabs frame]), 00324 origin = _type === CPTopTabsBezelBorder ? segmentedHeight / 2 : 0; 00325 00326 [_box setFrame:CGRectMake(0, origin, CGRectGetWidth(aFrame), 00327 CGRectGetHeight(aFrame) - segmentedHeight / 2)]; 00328 00329 [self addSubview:_tabs]; 00330 } 00331 00332 switch (_type) 00333 { 00334 case CPTopTabsBezelBorder: 00335 case CPBottomTabsBezelBorder: 00336 case CPNoTabsBezelBorder: 00337 [_box setBorderType:CPBezelBorder]; 00338 break; 00339 case CPNoTabsLineBorder: 00340 [_box setBorderType:CPLineBorder]; 00341 break; 00342 case CPNoTabsNoBorder: 00343 [_box setBorderType:CPNoBorder]; 00344 break; 00345 } 00346 } 00347 00352 - (CPTabViewType)tabViewType 00353 { 00354 return _type; 00355 } 00356 00361 - (id)delegate 00362 { 00363 return _delegate; 00364 } 00365 00370 - (void)setDelegate:(id)aDelegate 00371 { 00372 if (_delegate == aDelegate) 00373 return; 00374 00375 _delegate = aDelegate; 00376 00377 _delegateSelectors = 0; 00378 00379 if ([_delegate respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)]) 00380 _delegateSelectors |= CPTabViewShouldSelectTabViewItemSelector; 00381 00382 if ([_delegate respondsToSelector:@selector(tabView:willSelectTabViewItem:)]) 00383 _delegateSelectors |= CPTabViewWillSelectTabViewItemSelector; 00384 00385 if ([_delegate respondsToSelector:@selector(tabView:didSelectTabViewItem:)]) 00386 _delegateSelectors |= CPTabViewDidSelectTabViewItemSelector; 00387 00388 if ([_delegate respondsToSelector:@selector(tabViewDidChangeNumberOfTabViewItems:)]) 00389 _delegateSelectors |= CPTabViewDidChangeNumberOfTabViewItemsSelector; 00390 } 00391 00392 - (void)setBackgroundColor:(CPColor)aColor 00393 { 00394 [_box setBackgroundColor:aColor]; 00395 } 00396 00397 - (CPColor)backgroundColor 00398 { 00399 return [_box backgroundColor]; 00400 } 00401 00402 - (void)mouseDown:(CPEvent)anEvent 00403 { 00404 var segmentIndex = [_tabs testSegment:[_tabs convertPoint:[anEvent locationInWindow] fromView:nil]]; 00405 00406 if (segmentIndex != CPNotFound) 00407 { 00408 [self selectTabViewItemAtIndex:segmentIndex]; 00409 [_tabs trackSegment:anEvent]; 00410 } 00411 } 00412 00413 - (void)_repositionTabs 00414 { 00415 var horizontalCenterOfSelf = CGRectGetWidth([self bounds]) / 2, 00416 verticalCenterOfTabs = CGRectGetHeight([_tabs bounds]) / 2; 00417 00418 if (_type === CPBottomTabsBezelBorder) 00419 [_tabs setCenter:CGPointMake(horizontalCenterOfSelf, CGRectGetHeight([self bounds]) - verticalCenterOfTabs)]; 00420 else 00421 [_tabs setCenter:CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)]; 00422 } 00423 00424 - (void)_setSelectedIndex:(CPNumber)index 00425 { 00426 _selectedIndex = index; 00427 00428 [_box setContentView:[[_items objectAtIndex:_selectedIndex] view]]; 00429 } 00430 00431 - (void)_updateItems 00432 { 00433 var count = [_items count]; 00434 [_tabs setSegmentCount:count]; 00435 00436 for (var i = 0; i < count; i++) 00437 { 00438 [_tabs setLabel:[[_items objectAtIndex:i] label] forSegment:i]; 00439 [_tabs setTag:i forSegment:i]; 00440 } 00441 00442 if (_selectedIndex === CPNotFound) 00443 { 00444 [self selectFirstTabViewItem:self]; 00445 } 00446 } 00447 00448 @end 00449 00450 var CPTabViewItemsKey = "CPTabViewItemsKey", 00451 CPTabViewSelectedItemKey = "CPTabViewSelectedItemKey", 00452 CPTabViewTypeKey = "CPTabViewTypeKey", 00453 CPTabViewFontKey = "CPTabViewFontKey", 00454 CPTabViewDelegateKey = "CPTabViewDelegateKey"; 00455 00456 @implementation CPTabView (CPCoding) 00457 00458 - (id)initWithCoder:(CPCoder)aCoder 00459 { 00460 if (self = [super initWithCoder:aCoder]) 00461 { 00462 [self _init]; 00463 00464 _font = [aCoder decodeObjectForKey:CPTabViewFontKey]; 00465 [_tabs setFont:_font]; 00466 00467 _items = [aCoder decodeObjectForKey:CPTabViewItemsKey]; 00468 00469 [self _updateItems]; 00470 [self _repositionTabs]; 00471 00472 var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey]; 00473 00474 if (selected) 00475 [self selectTabViewItem:selected]; 00476 00477 [self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]]; 00478 00479 [self setTabViewType:[aCoder decodeIntForKey:CPTabViewTypeKey]]; 00480 } 00481 00482 return self; 00483 } 00484 00485 - (void)encodeWithCoder:(CPCoder)aCoder 00486 { 00487 [super encodeWithCoder:aCoder]; 00488 00489 [aCoder encodeObject:_items forKey:CPTabViewItemsKey]; 00490 [aCoder encodeObject:[self selectedTabViewItem] forKey:CPTabViewSelectedItemKey]; 00491 00492 [aCoder encodeInt:_type forKey:CPTabViewTypeKey]; 00493 [aCoder encodeObject:_font forKey:CPTabViewFontKey]; 00494 00495 [aCoder encodeConditionalObject:_delegate forKey:CPTabViewDelegateKey]; 00496 } 00497 00498 @end