API  0.9.9
CPTabView.j
Go to the documentation of this file.
1 /*
2  * CPTabView.j
3  * AppKit
4  *
5  * Created by Derek Hammer.
6  * Copyright 2010, Derek Hammer.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 @typedef CPTabViewType
26 //CPLeftTabsBezelBorder = 1;
28 //CPRightTabsBezelBorder = 3;
29 CPNoTabsBezelBorder = 4; //Displays no tabs and has a bezeled border.
30 CPNoTabsLineBorder = 5; //Has no tabs and displays a line border.
31 CPNoTabsNoBorder = 6; //Displays no tabs and no border.
32 
33 
38 
39 
41 
42 @optional
43 - (BOOL)tabView:(CPTabView)tabView shouldSelectTabViewItem:(CPTabViewItem)tabViewItem;
44 - (void)tabView:(CPTabView)tabView didSelectTabViewItem:(CPTabViewItem)tabViewItem;
45 - (void)tabView:(CPTabView)tabView willSelectTabViewItem:(CPTabViewItem)tabViewItem;
46 - (void)tabViewDidChangeNumberOfTabViewItems:(CPTabView)tabView;
47 
48 @end
49 
50 
58 @implementation CPTabView : CPView
59 {
60  CPArray _items;
61 
62  CPSegmentedControl _tabs;
63  _CPTabViewBox _box;
64  CPView _placeHolderView;
65 
66  CPTabViewItem _selectedTabViewItem;
67 
68  CPTabViewType _type;
69  CPFont _font;
70 
71  id <CPTabViewDelegate> _delegate;
72  unsigned _delegateSelectors;
73 }
74 
75 - (id)initWithFrame:(CGRect)aFrame
76 {
77  if (self = [super initWithFrame:aFrame])
78  {
79  [self _init];
80  _selectedTabViewItem = nil;
81  [self setTabViewType:CPTopTabsBezelBorder];
82  }
83 
84  return self;
85 }
86 
87 - (void)_init
88 {
89  _tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMakeZero()];
90  [_tabs setHitTests:NO];
91  [_tabs setSegments:[CPArray array]];
92 
93  var height = [_tabs valueForThemeAttribute:@"min-size"].height;
94  [_tabs setFrameSize:CGSizeMake(0, height)];
95 
96  _box = [[_CPTabViewBox alloc] initWithFrame:[self bounds]];
97  [_box setTabView:self];
99 
100  [self addSubview:_box];
101  [self addSubview:_tabs];
102 
103  _placeHolderView = nil;
104 }
105 
106 - (CPArray)items
107 {
108  return [_tabs segments];
109 }
110 
111 // Adding and Removing Tabs
116 - (void)addTabViewItem:(CPTabViewItem)aTabViewItem
117 {
118  [self insertTabViewItem:aTabViewItem atIndex:[self numberOfTabViewItems]];
119 }
120 
126 - (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(CPUInteger)anIndex
127 {
128  [self _insertTabViewItems:[aTabViewItem] atIndexes:[CPIndexSet indexSetWithIndex:anIndex]];
129 }
130 
131 - (void)_insertTabViewItems:(CPArray)tabViewItems atIndexes:(CPIndexSet)indexes
132 {
133  [_tabs insertSegments:tabViewItems atIndexes:indexes];
134  [tabViewItems makeObjectsPerformSelector:@selector(_setTabView:) withObject:self];
135 
136  [self tileWithChangedItem:[tabViewItems firstObject]];
137  [self _reverseSetContent];
138 
139  [self _sendDelegateTabViewDidChangeNumberOfTabViewItems];
140 }
141 
146 - (void)removeTabViewItem:(CPTabViewItem)aTabViewItem
147 {
148  var idx = [[self items] indexOfObjectIdenticalTo:aTabViewItem];
149 
150  if (idx == CPNotFound)
151  return;
152 
153  [_tabs removeSegmentsAtIndexes:[CPIndexSet indexSetWithIndex:idx]];
154  [aTabViewItem _setTabView:nil];
155 
156  [self tileWithChangedItem:nil];
157  [self _didRemoveTabViewItem:aTabViewItem atIndex:idx];
158  [self _reverseSetContent];
159 
160  [self _sendDelegateTabViewDidChangeNumberOfTabViewItems];
161 }
162 
163 - (void)_didRemoveTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(CPInteger)idx
164 {
165  // If the selection is managed by bindings, let the binder do that.
166  if ([self binderForBinding:CPSelectionIndexesBinding] || [self binderForBinding:CPSelectedIndexBinding])
167  return;
168 
169  if (_selectedTabViewItem == aTabViewItem)
170  {
171  var didSelect = NO;
172 
173  if (idx > 0)
174  didSelect = [self selectTabViewItemAtIndex:idx - 1];
175  else if ([self numberOfTabViewItems] > 0)
176  didSelect = [self selectTabViewItemAtIndex:0];
177 
178  if (didSelect == NO)
179  _selectedTabViewItem == nil;
180  }
181 }
182 
183 // Accessing Tabs
189 - (int)indexOfTabViewItem:(CPTabViewItem)aTabViewItem
190 {
191  return [[self items] indexOfObjectIdenticalTo:aTabViewItem];
192 }
193 
199 - (int)indexOfTabViewItemWithIdentifier:(CPString)anIdentifier
200 {
201  return [[self items] indexOfObjectPassingTest:function(item, idx, stop)
202  {
203  return [[item identifier] isEqual:anIdentifier];
204  }];
205 }
206 
212 {
213  return [[self items] count];
214 }
215 
220 - (CPTabViewItem)tabViewItemAtIndex:(CPUInteger)anIndex
221 {
222  return [[self items] objectAtIndex:anIndex];
223 }
224 
229 - (CPArray)tabViewItems
230 {
231  return [[self items] copy]; // Copy?
232 }
233 
234 // Selecting a Tab
239 - (void)selectFirstTabViewItem:(id)aSender
240 {
241  if ([self numberOfTabViewItems] === 0)
242  return; // throw?
243 
244  [self selectTabViewItemAtIndex:0];
245 }
246 
251 - (void)selectLastTabViewItem:(id)aSender
252 {
253  if ([self numberOfTabViewItems] === 0)
254  return; // throw?
255 
257 }
258 
263 - (void)selectNextTabViewItem:(id)aSender
264 {
265  if (_selectedTabViewItem === nil)
266  return;
267 
268  var nextIndex = [self indexOfTabViewItem:_selectedTabViewItem] + 1;
269 
270  if (nextIndex === [self numberOfTabViewItems])
271  // 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:)
272  return;
273 
274  [self selectTabViewItemAtIndex:nextIndex];
275 }
276 
281 - (void)selectPreviousTabViewItem:(id)aSender
282 {
283  if (_selectedTabViewItem === nil)
284  return;
285 
286  var previousIndex = [self indexOfTabViewItem:_selectedTabViewItem] - 1;
287 
288  if (previousIndex < 0)
289  return; // does nothing. See above.
290 
291  [self selectTabViewItemAtIndex:previousIndex];
292 }
293 
298 - (void)selectTabViewItem:(CPTabViewItem)aTabViewItem
299 {
300  [self selectTabViewItemAtIndex:[self indexOfTabViewItem:aTabViewItem]];
301 }
302 
307 - (BOOL)selectTabViewItemAtIndex:(CPUInteger)anIndex
308 {
309  if (![self _selectTabViewItemAtIndex:anIndex])
310  return NO;
311 
312  [self _reverseSetSelectedIndex];
313 
314  return YES;
315 }
316 
317 // Like selectTabViewItemAtIndex: but without bindings interaction
318 - (BOOL)_selectTabViewItemAtIndex:(CPUInteger)anIndex
319 {
320  var aTabViewItem = [self tabViewItemAtIndex:anIndex];
321 
322  if (aTabViewItem == _selectedTabViewItem)
323  return NO;
324 
325  if (![self _sendDelegateShouldSelectTabViewItem:aTabViewItem])
326  return NO;
327 
328  [self _sendDelegateWillSelectTabViewItem:aTabViewItem];
329 
330  [_tabs setSelectedSegment:anIndex];
331  _selectedTabViewItem = aTabViewItem;
332  [self _displayItemView:[aTabViewItem view]];
333 
334  [self _sendDelegateDidSelectTabViewItem:aTabViewItem];
335 
336  return YES;
337 }
338 
344 {
345  return _selectedTabViewItem;
346 }
347 
348 // Modifying the font
354 {
355  return _font;
356 }
357 
362 - (void)setFont:(CPFont)font
363 {
364  if ([_font isEqual:font])
365  return;
366 
367  _font = font;
368  [_tabs setFont:_font];
369 }
370 
371 //
376 - (void)setTabViewType:(CPTabViewType)aTabViewType
377 {
378  if (_type === aTabViewType)
379  return;
380 
381  _type = aTabViewType;
382 
383  if (_type !== CPTopTabsBezelBorder && _type !== CPBottomTabsBezelBorder)
384  [_tabs removeFromSuperview];
385  else
386  [self addSubview:_tabs];
387 
388  switch (_type)
389  {
392  case CPNoTabsBezelBorder:
393  [_box setBorderType:CPBezelBorder];
394  break;
395  case CPNoTabsLineBorder:
396  [_box setBorderType:CPLineBorder];
397  break;
398  case CPNoTabsNoBorder:
399  [_box setBorderType:CPNoBorder];
400  break;
401  }
402 
403  [self setNeedsLayout];
404 }
405 
406 - (void)tileWithChangedItem:(CPTabViewItem)aTabViewItem
407 {
408  var segment = aTabViewItem ? [self indexOfTabViewItem:aTabViewItem] : 0;
409  [_tabs tileWithChangedSegment:segment];
410 
411  [self setNeedsLayout];
412 }
413 
415 {
416  // Even if CPTabView's autoresizesSubviews is NO, _tabs and _box has to be laid out.
417  // This means we can't rely on autoresize masks.
418  if (_type !== CPTopTabsBezelBorder && _type !== CPBottomTabsBezelBorder)
419  {
420  [_box setFrame:[self bounds]];
421  }
422  else
423  {
424  var aFrame = [self frame],
425  segmentedHeight = CGRectGetHeight([_tabs frame]),
426  origin = _type === CPTopTabsBezelBorder ? segmentedHeight / 2 : 0;
427 
428  [_box setFrame:CGRectMake(0, origin, CGRectGetWidth(aFrame),
429  CGRectGetHeight(aFrame) - segmentedHeight / 2)];
430 
431  [self _repositionTabs];
432  }
433 }
434 
439 - (CPTabViewType)tabViewType
440 {
441  return _type;
442 }
443 
448 - (id)delegate
449 {
450  return _delegate;
451 }
452 
457 - (void)setDelegate:(id <CPTabViewDelegate>)aDelegate
458 {
459  if (_delegate == aDelegate)
460  return;
461 
462  _delegate = aDelegate;
463 
464  _delegateSelectors = 0;
465 
466  if ([_delegate respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)])
467  _delegateSelectors |= CPTabViewShouldSelectTabViewItemSelector;
468 
469  if ([_delegate respondsToSelector:@selector(tabView:willSelectTabViewItem:)])
470  _delegateSelectors |= CPTabViewWillSelectTabViewItemSelector;
471 
472  if ([_delegate respondsToSelector:@selector(tabView:didSelectTabViewItem:)])
473  _delegateSelectors |= CPTabViewDidSelectTabViewItemSelector;
474 
475  if ([_delegate respondsToSelector:@selector(tabViewDidChangeNumberOfTabViewItems:)])
477 }
478 
479 - (void)setBackgroundColor:(CPColor)aColor
480 {
481  [_box setBackgroundColor:aColor];
482 }
483 
485 {
486  return [_box backgroundColor];
487 }
488 
489 - (void)mouseDown:(CPEvent)anEvent
490 {
491  var segmentIndex = [_tabs testSegment:[_tabs convertPoint:[anEvent locationInWindow] fromView:nil]];
492 
493  if (segmentIndex != CPNotFound && [self selectTabViewItemAtIndex:segmentIndex])
494  [_tabs trackSegment:anEvent];
495 }
496 
497 - (void)_repositionTabs
498 {
499  var horizontalCenterOfSelf = CGRectGetWidth([self bounds]) / 2,
500  verticalCenterOfTabs = CGRectGetHeight([_tabs bounds]) / 2;
501 
502  if (_type === CPBottomTabsBezelBorder)
503  [_tabs setCenter:CGPointMake(horizontalCenterOfSelf, CGRectGetHeight([self bounds]) - verticalCenterOfTabs)];
504  else
505  [_tabs setCenter:CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)];
506 }
507 
508 - (void)_displayItemView:(CPView)aView
509 {
510  [_box setContentView:aView];
511 }
512 
513 // DELEGATE METHODS
514 
515 - (BOOL)_sendDelegateShouldSelectTabViewItem:(CPTabViewItem)aTabViewItem
516 {
517  if (_delegateSelectors & CPTabViewShouldSelectTabViewItemSelector)
518  return [_delegate tabView:self shouldSelectTabViewItem:aTabViewItem];
519 
520  return YES;
521 }
522 
523 - (void)_sendDelegateWillSelectTabViewItem:(CPTabViewItem)aTabViewItem
524 {
525  if (_delegateSelectors & CPTabViewWillSelectTabViewItemSelector)
526  [_delegate tabView:self willSelectTabViewItem:aTabViewItem];
527 }
528 
529 - (void)_sendDelegateDidSelectTabViewItem:(CPTabViewItem)aTabViewItem
530 {
531  if (_delegateSelectors & CPTabViewDidSelectTabViewItemSelector)
532  [_delegate tabView:self didSelectTabViewItem:aTabViewItem];
533 }
534 
535 - (void)_sendDelegateTabViewDidChangeNumberOfTabViewItems
536 {
537  if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
538  [_delegate tabViewDidChangeNumberOfTabViewItems:self];
539 }
540 
541 @end
542 
544 
545 + (Class)_binderClassForBinding:(CPString)aBinding
546 {
547  if (aBinding == CPContentBinding)
548  return [_CPTabViewContentBinder class];
549  else if (aBinding == CPSelectionIndexesBinding || aBinding == CPSelectedIndexBinding)
550  return [_CPTabViewSelectionBinder class];
551 
552  return [super _binderClassForBinding:aBinding];
553 }
554 
555 + (BOOL)isBindingExclusive:(CPString)aBinding
556 {
557  return (aBinding == CPSelectionIndexesBinding || aBinding == CPSelectedIndexBinding);
558 }
559 
560 - (void)_reverseSetContent
561 {
562  var theBinder = [self binderForBinding:CPContentBinding];
563  [theBinder reverseSetValueFor:@"items"];
564 }
565 
566 - (void)_reverseSetSelectedIndex
567 {
568  var theBinder = [self binderForBinding:CPSelectionIndexesBinding];
569 
570  if (theBinder !== nil)
571  [theBinder reverseSetValueFor:@"selectionIndexes"];
572  else
573  {
574  theBinder = [self binderForBinding:CPSelectedIndexBinding];
575  [theBinder reverseSetValueFor:@"selectedIndex"];
576  }
577 }
578 
579 - (CPBinder)binderForBinding:(CPString)aBinding
580 {
581  var cls = [[self class] _binderClassForBinding:aBinding]
582  return [cls getBinding:aBinding forObject:self];
583 }
584 
585 - (void)setItems:(CPArray)tabViewItems
586 {
587  if ([tabViewItems isEqualToArray:[_tabs segments]])
588  return;
589 
590  [[self items] makeObjectsPerformSelector:@selector(_setTabView:) withObject:nil];
591  [_tabs setSegments:tabViewItems];
592  [tabViewItems makeObjectsPerformSelector:@selector(_setTabView:) withObject:self];
593 
594  [self tileWithChangedItem:nil];
595 
596  // Update the selection because setSegments: did remove all previous segments AND the selection.
597  [_tabs setSelectedSegment:[self indexOfTabViewItem:_selectedTabViewItem]];
598 
599  // should we send delegate methods in bindings mode ?
600  //[self _delegateTabViewDidChangeNumberOfTabViewItems:self];
601 }
602 
603 - (void)_deselectAll
604 {
605  [_tabs setSelectedSegment:-1];
606  _selectedTabViewItem = nil;
607 }
608 
609 - (void)_displayPlaceholder:(CPString)aPlaceholder
610 {
611  if (_placeHolderView == nil)
612  {
613  _placeHolderView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
614  var textField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
615  [textField setTag:1000];
616  [textField setTextColor:[CPColor whiteColor]];
617  [textField setFont:[CPFont boldFontWithName:@"Geneva" size:18 italic:YES]];
618  [_placeHolderView addSubview:textField];
619  }
620 
621  var textField = [_placeHolderView viewWithTag:1000];
622  [textField setStringValue:aPlaceholder];
623  [textField sizeToFit];
624 
625  var boxBounds = [_box bounds],
626  textFieldBounds = [textField bounds],
627  origin = CGPointMake(CGRectGetWidth(boxBounds)/2 - CGRectGetWidth(textFieldBounds)/2, CGRectGetHeight(boxBounds)/2 - CGRectGetHeight(textFieldBounds));
628 
629  [textField setFrameOrigin:origin];
630 
631  [self _displayItemView:_placeHolderView];
632 }
633 
634 #pragma mark -
635 #pragma mark Override
636 
640 - (BOOL)acceptsFirstMouse:(CPEvent)anEvent
641 {
642  return YES;
643 }
644 
645 @end
646 
647 var _CPTabViewContentBinderNull = @"NO CONTENT";
648 @implementation _CPTabViewContentBinder : CPBinder
649 {
650  id __doxygen__;
651 }
652 
653 - (void)_updatePlaceholdersWithOptions:(CPDictionary)options
654 {
655  [super _updatePlaceholdersWithOptions:options];
656  [self _setPlaceholder:_CPTabViewContentBinderNull forMarker:CPNullMarker isDefault:YES];
657 }
658 
659 - (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
660 {
661  [_source setItems:@[]];
662  [_source _setPlaceholderView:aValue];
663 }
664 
665 - (void)setValue:(id)aValue forBinding:(CPString)aBinding
666 {
667  [_source setItems:aValue];
668 }
669 
670 - (id)valueForBinding:(CPString)aBinding
671 {
672  return [_source items];
673 }
674 
675 @end
676 
677 var _CPTabViewSelectionBinderMultipleValues = @"Multiple Selection",
678  _CPTabViewSelectionBinderNoSelection = @"No Selection";
679 @implementation _CPTabViewSelectionBinder : CPBinder
680 {
681  id __doxygen__;
682 }
683 
684 - (void)_updatePlaceholdersWithOptions:(CPDictionary)options
685 {
686  [super _updatePlaceholdersWithOptions:options];
687 
688  [self _setPlaceholder:_CPTabViewSelectionBinderMultipleValues forMarker:CPMultipleValuesMarker isDefault:YES];
689  [self _setPlaceholder:_CPTabViewSelectionBinderNoSelection forMarker:CPNoSelectionMarker isDefault:YES];
690 }
691 
692 - (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
693 {
694  if (aMarker == CPNoSelectionMarker || aMarker == CPNullMarker)
695  [_source _deselectAll];
696 
697  [_source _displayPlaceholder:aValue];
698 }
699 
700 - (void)setValue:(id)aValue forBinding:(CPString)aBinding
701 {
702  if (aBinding == CPSelectionIndexesBinding)
703  {
704  if (aValue == nil || [aValue count] == 0)
705  {
706  [_source _deselectAll];
707  [_source _displayPlaceholder:_CPTabViewSelectionBinderNoSelection];
708  }
709  else if ([aValue count] > 1)
710  [_source _displayPlaceholder:_CPTabViewSelectionBinderMultipleValues];
711  else if ([aValue firstIndex] < [_source numberOfTabViewItems])
712  [_source _selectTabViewItemAtIndex:[aValue firstIndex]];
713  }
714  else if (aBinding == CPSelectedIndexBinding)
715  {
716  if (aValue == CPNotFound)
717  {
718  [_source _deselectAll];
719  [_source _displayPlaceholder:_CPTabViewSelectionBinderNoSelection];
720  }
721  else if (aValue < [_source numberOfTabViewItems])
722  [_source _selectTabViewItemAtIndex:aValue];
723  }
724 }
725 
726 - (id)valueForBinding:(CPString)aBinding
727 {
728  if (aBinding == CPSelectionIndexesBinding)
729  {
730  var result = [CPIndexSet indexSet],
731  idx = [_source indexOfTabViewItem:[_source selectedTabViewItem]];
732 
733  if (idx !== CPNotFound)
734  [result addIndex:idx];
735 
736  return result;
737  }
738  else if (aBinding == CPSelectedIndexBinding)
739  return [_source indexOfTabViewItem:[_source selectedTabViewItem]];
740 }
741 
742 @end
743 
744 var CPTabViewItemsKey = "CPTabViewItemsKey",
745  CPTabViewSelectedItemKey = "CPTabViewSelectedItemKey",
746  CPTabViewTypeKey = "CPTabViewTypeKey",
747  CPTabViewFontKey = "CPTabViewFontKey",
748  CPTabViewDelegateKey = "CPTabViewDelegateKey";
749 
750 @implementation CPTabView (CPCoding)
751 
752 - (id)initWithCoder:(CPCoder)aCoder
753 {
754  if (self = [super initWithCoder:aCoder])
755  {
756  [self _init];
757 
758  _font = [aCoder decodeObjectForKey:CPTabViewFontKey];
759  [_tabs setFont:_font];
760 
761  var items = [aCoder decodeObjectForKey:CPTabViewItemsKey] || [CPArray array];
762  [self _insertTabViewItems:items atIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [items count])]];
763 
764  [self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]];
765 
766  _selectedTabViewItem = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
767 
768  _type = [aCoder decodeIntForKey:CPTabViewTypeKey];
769  }
770 
771  return self;
772 }
773 
775 {
776  [super awakeFromCib];
777 
778  // This cannot be run in initWithCoder because it might call selectTabViewItem:, which is
779  // not safe to call before the views of the tab views items are fully decoded.
780 
781  if (_selectedTabViewItem)
782  {
783  var idx = [self indexOfTabViewItem:_selectedTabViewItem];
784 
785  if (idx !== CPNotFound)
786  {
787  // Temporarily set the selected item to not selected.
788  // It allows the initial selection to be made correctly.
789  _selectedTabViewItem = nil;
790 
791  [self selectTabViewItemAtIndex:idx];
792  }
793  }
794 
795  var type = _type;
796  _type = nil;
797  [self setTabViewType:type];
798 
799  [self setNeedsLayout];
800 }
801 
802 - (void)encodeWithCoder:(CPCoder)aCoder
803 {
804  // Don't bother to encode the CPBox. We will recreate it on decode and its content view is already
805  // stored by the tab view item. Not encoding _box makes the resulting archive smaller and reduces
806  // the surface for decoding bugs (of which we've had many in tab view).
807  var subviews = [self subviews];
808  [_box removeFromSuperview];
809  [super encodeWithCoder:aCoder];
810  [self setSubviews:subviews];
811 
812  [aCoder encodeObject:_items forKey:CPTabViewItemsKey];
813 
814  [aCoder encodeConditionalObject:_selectedTabViewItem forKey:CPTabViewSelectedItemKey];
815 
816  [aCoder encodeInt:_type forKey:CPTabViewTypeKey];
817  [aCoder encodeObject:_font forKey:CPTabViewFontKey];
818 
819  [aCoder encodeConditionalObject:_delegate forKey:CPTabViewDelegateKey];
820 }
821 
822 @end
823 
824 @implementation _CPTabViewBox : CPBox
825 {
826  CPTabView _tabView;
827 }
828 
829 
830 #pragma mark -
831 #pragma mark Override
832 
833 - (CPView)hitTest:(CGPoint)aPoint
834 {
835  // Here we check if we have clicked on the segmentedControl of the tabView or not
836  // If YES, the CPBox should not handle the click
837  var segmentIndex = [_tabView._tabs testSegment:[_tabView._tabs convertPoint:aPoint fromView:[self superview]]];
838 
839  if (segmentIndex != CPNotFound)
840  return nil;
841 
842  return [super hitTest:aPoint];
843 }
844 
845 @end
Definition: CPFont.h:2
var CPTabViewWillSelectTabViewItemSelector
Definition: CPTabView.j:36
void addSubview:(CPView aSubview)
Definition: CPView.j:495
A CALayer is similar to a CPView
Definition: CALayer.j:46
int indexOfTabViewItem:(CPTabViewItem aTabViewItem)
Definition: CPTabView.j:189
var CPTabViewItemsKey
Definition: CPTabView.j:744
CPFont font()
Definition: CPTabView.j:353
var isEqual
void setBackgroundColor:(CPColor aColor)
Definition: CPTabView.j:479
CPFont boldFontWithName:size:italic:(CPString aName, [size] float aSize, [italic] BOOL italic)
Definition: CPFont.j:262
CGPoint locationInWindow()
Definition: CPEvent.j:287
CPColor whiteColor()
Definition: CPColor.j:358
void layoutSubviews()
Definition: CPTabView.j:414
CGRect bounds()
Definition: CPView.j:1287
A collection of unique integers.
Definition: CPIndexSet.h:2
CPView hitTest:(CGPoint aPoint)
Definition: CPView.j:1769
CPNoTabsNoBorder
Definition: CPTabView.j:31
CPContentBinding
A mutable key-value pair collection.
Definition: CPDictionary.h:2
id delegate()
Definition: CPTabView.j:448
CPTabViewType CPTopTabsBezelBorder
Definition: CPTabView.j:25
CPBottomTabsBezelBorder
Definition: CPTabView.j:27
An immutable string (collection of characters).
Definition: CPString.h:2
CPArray items()
Definition: CPTabView.j:106
CPColor colorWithCalibratedWhite:alpha:(float white, [alpha] float alpha)
Definition: CPColor.j:170
var CPTabViewDelegateKey
Definition: CPTabView.j:748
CPTabViewItem selectedTabViewItem()
Definition: CPTabView.j:343
void encodeWithCoder:(CPCoder aCoder)
Definition: CPView.j:3704
var CPTabViewDidChangeNumberOfTabViewItemsSelector
Definition: CPTabView.j:37
CPNoTabsBezelBorder
Definition: CPTabView.j:29
void setSubviews:(CPArray newSubviews)
Definition: CPView.j:697
void setTabViewType:(CPTabViewType aTabViewType)
Definition: CPTabView.j:376
CPSelectedIndexBinding
CPArray subviews()
Definition: CPView.j:478
void setNeedsLayout()
Definition: CPView.j:2641
Defines methods for use when archiving & restoring (enc/decoding).
Definition: CPCoder.h:2
var CPTabViewSelectedItemKey
Definition: CPTabView.j:745
BOOL selectTabViewItemAtIndex:(CPUInteger anIndex)
Definition: CPTabView.j:307
CPTabViewType tabViewType()
Definition: CPTabView.j:439
CPNotFound
Definition: CPObjJRuntime.j:62
void tileWithChangedItem:(CPTabViewItem aTabViewItem)
Definition: CPTabView.j:406
var CPTabViewDidSelectTabViewItemSelector
Definition: CPTabView.j:34
CPBinder binderForBinding:(CPString aBinding)
Definition: CPTabView.j:579
void setDelegate:(id< CPTabViewDelegate > aDelegate)
Definition: CPTabView.j:457
CPColor backgroundColor()
Definition: CPTabView.j:484
var CPTabViewFontKey
Definition: CPTabView.j:747
CPNoSelectionMarker
CPArray tabViewItems()
Definition: CPTabView.j:229
id indexSetWithIndexesInRange:(CPRange aRange)
Definition: CPIndexSet.j:60
Definition: CPBox.h:2
CPTabViewItem tabViewItemAtIndex:(CPUInteger anIndex)
Definition: CPTabView.j:220
Definition: CPEvent.h:2
CPView superview()
Definition: CPView.j:469
CGRect frame()
Definition: CPView.j:1011
CPNoTabsLineBorder
Definition: CPTabView.j:30
id indexSetWithIndex:(int anIndex)
Definition: CPIndexSet.j:51
void insertTabViewItem:atIndex:(CPTabViewItem aTabViewItem, [atIndex] CPUInteger anIndex)
Definition: CPTabView.j:126
CPSelectionIndexesBinding
id indexSet()
Definition: CPIndexSet.j:43
var CPTabViewShouldSelectTabViewItemSelector
Definition: CPTabView.j:35
unsigned numberOfTabViewItems()
Definition: CPTabView.j:211
CPNullMarker
Definition: CPView.j:131
var CPTabViewTypeKey
Definition: CPTabView.j:746