summaryrefslogtreecommitdiff
path: root/cocoa/PSMTabBarControl/PSMTabBarController.m
diff options
context:
space:
mode:
Diffstat (limited to 'cocoa/PSMTabBarControl/PSMTabBarController.m')
-rw-r--r--cocoa/PSMTabBarControl/PSMTabBarController.m662
1 files changed, 321 insertions, 341 deletions
diff --git a/cocoa/PSMTabBarControl/PSMTabBarController.m b/cocoa/PSMTabBarControl/PSMTabBarController.m
index 69542c865..7d9820e61 100644
--- a/cocoa/PSMTabBarControl/PSMTabBarController.m
+++ b/cocoa/PSMTabBarControl/PSMTabBarController.m
@@ -12,7 +12,7 @@
#import "PSMTabStyle.h"
#import "NSString_AITruncation.h"
-#define MAX_OVERFLOW_MENUITEM_TITLE_LENGTH 60
+#define MAX_OVERFLOW_MENUITEM_TITLE_LENGTH 60
@interface PSMTabBarController (Private)
- (NSArray *)_generateWidthsFromCells:(NSArray *)cells;
@@ -28,26 +28,24 @@
PSMTabBarControl.
@param A PSMTabBarControl.
@returns A newly created PSMTabBarController instance.
-*/
-
-- (id)initWithTabBarControl:(PSMTabBarControl *)control
-{
- if ( (self = [super init]) ) {
- _control = control;
- _cellTrackingRects = [[NSMutableArray alloc] init];
- _closeButtonTrackingRects = [[NSMutableArray alloc] init];
- _cellFrames = [[NSMutableArray alloc] init];
+ */
+
+- (id)initWithTabBarControl:(PSMTabBarControl *)control {
+ if((self = [super init])) {
+ _control = control;
+ _cellTrackingRects = [[NSMutableArray alloc] init];
+ _closeButtonTrackingRects = [[NSMutableArray alloc] init];
+ _cellFrames = [[NSMutableArray alloc] init];
_addButtonRect = NSZeroRect;
- }
- return self;
+ }
+ return self;
}
-- (void)dealloc
-{
- [_cellTrackingRects release];
- [_closeButtonTrackingRects release];
- [_cellFrames release];
- [super dealloc];
+- (void)dealloc {
+ [_cellTrackingRects release];
+ [_closeButtonTrackingRects release];
+ [_cellFrames release];
+ [super dealloc];
}
/*!
@@ -55,11 +53,10 @@
@abstract Returns the position for the add tab button.
@discussion Returns the position for the add tab button.
@returns The rect for the add button rect.
-*/
+ */
-- (NSRect)addButtonRect
-{
- return _addButtonRect;
+- (NSRect)addButtonRect {
+ return _addButtonRect;
}
/*!
@@ -67,11 +64,10 @@
@abstract Returns current overflow menu or nil if there is none.
@discussion Returns current overflow menu or nil if there is none.
@returns The current overflow menu.
-*/
+ */
-- (NSMenu *)overflowMenu
-{
- return _overflowMenu;
+- (NSMenu *)overflowMenu {
+ return _overflowMenu;
}
/*!
@@ -80,18 +76,17 @@
@discussion Returns the rect for the tracking rect at the requested index.
@param Index of a cell.
@returns The tracking rect of the cell at the requested index.
-*/
-
-- (NSRect)cellTrackingRectAtIndex:(NSInteger)index
-{
- NSRect rect;
- if (index > -1 && index < [_cellTrackingRects count]) {
- rect = [[_cellTrackingRects objectAtIndex:index] rectValue];
- } else {
- NSLog(@"cellTrackingRectAtIndex: Invalid index (%ld)", (long)index);
- rect = NSZeroRect;
- }
- return rect;
+ */
+
+- (NSRect)cellTrackingRectAtIndex:(NSInteger)index {
+ NSRect rect;
+ if(index > -1 && index < [_cellTrackingRects count]) {
+ rect = [[_cellTrackingRects objectAtIndex:index] rectValue];
+ } else {
+ NSLog(@"cellTrackingRectAtIndex: Invalid index (%ld)", (long)index);
+ rect = NSZeroRect;
+ }
+ return rect;
}
/*!
@@ -100,18 +95,17 @@
@discussion Returns the tracking rect for the close button at the requested index.
@param Index of a cell.
@returns The close button tracking rect of the cell at the requested index.
-*/
-
-- (NSRect)closeButtonTrackingRectAtIndex:(NSInteger)index
-{
- NSRect rect;
- if (index > -1 && index < [_closeButtonTrackingRects count]) {
- rect = [[_closeButtonTrackingRects objectAtIndex:index] rectValue];
- } else {
- NSLog(@"closeButtonTrackingRectAtIndex: Invalid index (%ld)", (long)index);
- rect = NSZeroRect;
- }
- return rect;
+ */
+
+- (NSRect)closeButtonTrackingRectAtIndex:(NSInteger)index {
+ NSRect rect;
+ if(index > -1 && index < [_closeButtonTrackingRects count]) {
+ rect = [[_closeButtonTrackingRects objectAtIndex:index] rectValue];
+ } else {
+ NSLog(@"closeButtonTrackingRectAtIndex: Invalid index (%ld)", (long)index);
+ rect = NSZeroRect;
+ }
+ return rect;
}
/*!
@@ -120,19 +114,18 @@
@discussion Returns the frame for the cell at the requested index.
@param Index of a cell.
@returns The frame of the cell at the requested index.
-*/
-
-- (NSRect)cellFrameAtIndex:(NSInteger)index
-{
- NSRect rect;
-
- if (index > -1 && index < [_cellFrames count]) {
- rect = [[_cellFrames objectAtIndex:index] rectValue];
- } else {
- NSLog(@"cellFrameAtIndex: Invalid index (%ld)", (long)index);
- rect = NSZeroRect;
- }
- return rect;
+ */
+
+- (NSRect)cellFrameAtIndex:(NSInteger)index {
+ NSRect rect;
+
+ if(index > -1 && index < [_cellFrames count]) {
+ rect = [[_cellFrames objectAtIndex:index] rectValue];
+ } else {
+ NSLog(@"cellFrameAtIndex: Invalid index (%ld)", (long)index);
+ rect = NSZeroRect;
+ }
+ return rect;
}
/*!
@@ -140,46 +133,45 @@
@abstract Changes the cell states so the given cell is the currently selected cell.
@discussion Makes the given cell the active cell and properly recalculates the tab states for surrounding cells.
@param An instance of PSMTabBarCell to make active.
-*/
-
-- (void)setSelectedCell:(PSMTabBarCell *)cell
-{
- NSArray *cells = [_control cells];
- NSEnumerator *enumerator = [cells objectEnumerator];
- PSMTabBarCell *lastCell = nil, *nextCell;
-
- //deselect the previously selected tab
- while ( (nextCell = [enumerator nextObject]) && ([nextCell state] == NSOffState) ) {
- lastCell = nextCell;
- }
-
- [nextCell setState:NSOffState];
- [nextCell setTabState:PSMTab_PositionMiddleMask];
-
- if (lastCell && lastCell != [_control lastVisibleTab]) {
- [lastCell setTabState:~[lastCell tabState] & PSMTab_RightIsSelectedMask];
- }
-
- if ( (nextCell = [enumerator nextObject]) ) {
- [nextCell setTabState:~[lastCell tabState] & PSMTab_LeftIsSelectedMask];
- }
-
- [cell setState:NSOnState];
- [cell setTabState:PSMTab_SelectedMask];
-
- if (![cell isInOverflowMenu]) {
- NSInteger cellIndex = [cells indexOfObject:cell];
-
- if (cellIndex > 0) {
- nextCell = [cells objectAtIndex:cellIndex - 1];
- [nextCell setTabState:[nextCell tabState] | PSMTab_RightIsSelectedMask];
- }
-
- if (cellIndex < [cells count] - 1) {
- nextCell = [cells objectAtIndex:cellIndex + 1];
- [nextCell setTabState:[nextCell tabState] | PSMTab_LeftIsSelectedMask];
- }
- }
+ */
+
+- (void)setSelectedCell:(PSMTabBarCell *)cell {
+ NSArray *cells = [_control cells];
+ NSEnumerator *enumerator = [cells objectEnumerator];
+ PSMTabBarCell *lastCell = nil, *nextCell;
+
+ //deselect the previously selected tab
+ while((nextCell = [enumerator nextObject]) && ([nextCell state] == NSOffState)) {
+ lastCell = nextCell;
+ }
+
+ [nextCell setState:NSOffState];
+ [nextCell setTabState:PSMTab_PositionMiddleMask];
+
+ if(lastCell && lastCell != [_control lastVisibleTab]) {
+ [lastCell setTabState:~[lastCell tabState] & PSMTab_RightIsSelectedMask];
+ }
+
+ if((nextCell = [enumerator nextObject])) {
+ [nextCell setTabState:~[lastCell tabState] & PSMTab_LeftIsSelectedMask];
+ }
+
+ [cell setState:NSOnState];
+ [cell setTabState:PSMTab_SelectedMask];
+
+ if(![cell isInOverflowMenu]) {
+ NSInteger cellIndex = [cells indexOfObject:cell];
+
+ if(cellIndex > 0) {
+ nextCell = [cells objectAtIndex:cellIndex - 1];
+ [nextCell setTabState:[nextCell tabState] | PSMTab_RightIsSelectedMask];
+ }
+
+ if(cellIndex < [cells count] - 1) {
+ nextCell = [cells objectAtIndex:cellIndex + 1];
+ [nextCell setTabState:[nextCell tabState] | PSMTab_LeftIsSelectedMask];
+ }
+ }
}
/*!
@@ -187,47 +179,45 @@
@abstract Recalculates cell positions and states.
@discussion This method calculates the proper frame, tabState and overflow menu status for all cells in the
tab bar control.
-*/
-
-- (void)layoutCells
-{
- NSArray *cells = [_control cells];
- NSInteger cellCount = [cells count];
-
- // make sure all of our tabs are accounted for before updating
- if ([[_control tabView] numberOfTabViewItems] != cellCount) {
- return;
- }
-
- [_cellTrackingRects removeAllObjects];
- [_closeButtonTrackingRects removeAllObjects];
- [_cellFrames removeAllObjects];
-
- NSArray *cellWidths = [self _generateWidthsFromCells:cells];
- [self _setupCells:cells withWidths:cellWidths];
-
- //set up the rect from the add tab button
- _addButtonRect = [_control genericCellRect];
- _addButtonRect.size = [[_control addTabButton] frame].size;
- if ([_control orientation] == PSMTabBarHorizontalOrientation) {
- _addButtonRect.origin.y = MARGIN_Y;
- _addButtonRect.origin.x += [[cellWidths valueForKeyPath:@"@sum.floatValue"] doubleValue] + 2;
- } else {
- _addButtonRect.origin.x = 0;
- _addButtonRect.origin.y = [[cellWidths lastObject] doubleValue];
- }
+ */
+
+- (void)layoutCells {
+ NSArray *cells = [_control cells];
+ NSInteger cellCount = [cells count];
+
+ // make sure all of our tabs are accounted for before updating
+ if([[_control tabView] numberOfTabViewItems] != cellCount) {
+ return;
+ }
+
+ [_cellTrackingRects removeAllObjects];
+ [_closeButtonTrackingRects removeAllObjects];
+ [_cellFrames removeAllObjects];
+
+ NSArray *cellWidths = [self _generateWidthsFromCells:cells];
+ [self _setupCells:cells withWidths:cellWidths];
+
+ //set up the rect from the add tab button
+ _addButtonRect = [_control genericCellRect];
+ _addButtonRect.size = [[_control addTabButton] frame].size;
+ if([_control orientation] == PSMTabBarHorizontalOrientation) {
+ _addButtonRect.origin.y = MARGIN_Y;
+ _addButtonRect.origin.x += [[cellWidths valueForKeyPath:@"@sum.floatValue"] doubleValue] + 2;
+ } else {
+ _addButtonRect.origin.x = 0;
+ _addButtonRect.origin.y = [[cellWidths lastObject] doubleValue];
+ }
}
/*!
* @method _shrinkWidths:towardMinimum:withAvailableWidth:
- * @abstract Decreases widths in an array toward a minimum until they fit within availableWidth, if possible
+ * @abstract Decreases widths in an array toward a minimum until they fit within availableWidth, if possible
* @param An array of NSNumbers
* @param The target minimum
* @param The maximum available width
* @returns The amount by which the total array width was shrunk
*/
-- (NSInteger)_shrinkWidths:(NSMutableArray *)newWidths towardMinimum:(NSInteger)minimum withAvailableWidth:(CGFloat)availableWidth
-{
+- (NSInteger)_shrinkWidths:(NSMutableArray *)newWidths towardMinimum:(NSInteger)minimum withAvailableWidth:(CGFloat)availableWidth {
BOOL changed = NO;
NSInteger count = [newWidths count];
NSInteger totalWidths = [[newWidths valueForKeyPath:@"@sum.intValue"] integerValue];
@@ -235,45 +225,43 @@
do {
changed = NO;
-
- for (NSInteger q = (count - 1); q >= 0; q--) {
+
+ for(NSInteger q = (count - 1); q >= 0; q--) {
CGFloat cellWidth = [[newWidths objectAtIndex:q] doubleValue];
- if (cellWidth - 1 >= minimum) {
+ if(cellWidth - 1 >= minimum) {
cellWidth--;
totalWidths--;
- [newWidths replaceObjectAtIndex:q
- withObject:[NSNumber numberWithDouble:cellWidth]];
+ [newWidths replaceObjectAtIndex:q
+ withObject:[NSNumber numberWithDouble:cellWidth]];
changed = YES;
- }
+ }
}
+ } while(changed && (totalWidths > availableWidth));
- } while (changed && (totalWidths > availableWidth));
-
- return (originalTotalWidths - totalWidths);
+ return(originalTotalWidths - totalWidths);
}
/*!
* @function potentialMinimumForArray()
* @abstract Calculate the minimum total for a given array of widths
* @discussion The array is summed using, for each item, the minimum between the current value and the passed minimum value.
- * This is useful for getting a sum if the array has size-to-fit widths which will be allowed to be less than the
+ * This is useful for getting a sum if the array has size-to-fit widths which will be allowed to be less than the
* specified minimum.
* @param An array of widths
* @param The minimum
* @returns The smallest possible sum for the array
*/
-static NSInteger potentialMinimumForArray(NSArray *array, NSInteger minimum)
-{
+static NSInteger potentialMinimumForArray(NSArray *array, NSInteger minimum){
NSInteger runningTotal = 0;
NSInteger count = [array count];
- for (NSInteger i = 0; i < count; i++) {
+ for(NSInteger i = 0; i < count; i++) {
NSInteger currentValue = [[array objectAtIndex:i] integerValue];
runningTotal += MIN(currentValue, minimum);
}
-
+
return runningTotal;
}
@@ -284,60 +272,59 @@ static NSInteger potentialMinimumForArray(NSArray *array, NSInteger minimum)
visible. Uses large blocks of code that were previously in PSMTabBarControl's update method.
@param An array of PSMTabBarCells.
@returns An array of numbers representing the widths of cells that would be visible.
-*/
-
-- (NSArray *)_generateWidthsFromCells:(NSArray *)cells
-{
- NSInteger cellCount = [cells count], i, numberOfVisibleCells = ([_control orientation] == PSMTabBarHorizontalOrientation) ? 1 : 0;
- NSMutableArray *newWidths = [NSMutableArray arrayWithCapacity:cellCount];
- id <PSMTabStyle> style = [_control style];
- CGFloat availableWidth = [_control availableCellWidth], currentOrigin = 0, totalOccupiedWidth = 0.0, width;
- NSRect cellRect = [_control genericCellRect], controlRect = [_control frame];
- PSMTabBarCell *currentCell;
-
- if ([_control orientation] == PSMTabBarVerticalOrientation) {
- currentOrigin = [style topMarginForTabBarControl];
- }
+ */
+
+- (NSArray *)_generateWidthsFromCells:(NSArray *)cells {
+ NSInteger cellCount = [cells count], i, numberOfVisibleCells = ([_control orientation] == PSMTabBarHorizontalOrientation) ? 1 : 0;
+ NSMutableArray *newWidths = [NSMutableArray arrayWithCapacity:cellCount];
+ id <PSMTabStyle> style = [_control style];
+ CGFloat availableWidth = [_control availableCellWidth], currentOrigin = 0, totalOccupiedWidth = 0.0, width;
+ NSRect cellRect = [_control genericCellRect], controlRect = [_control frame];
+ PSMTabBarCell *currentCell;
+
+ if([_control orientation] == PSMTabBarVerticalOrientation) {
+ currentOrigin = [style topMarginForTabBarControl];
+ }
//Don't let cells overlap the add tab button if it is visible
- if ([_control showAddTabButton]) {
+ if([_control showAddTabButton]) {
availableWidth -= [self addButtonRect].size.width;
}
- for (i = 0; i < cellCount; i++) {
- currentCell = [cells objectAtIndex:i];
-
+ for(i = 0; i < cellCount; i++) {
+ currentCell = [cells objectAtIndex:i];
+
// supress close button?
- [currentCell setCloseButtonSuppressed:((cellCount == 1 && [_control canCloseOnlyTab] == NO) ||
+ [currentCell setCloseButtonSuppressed:((cellCount == 1 && [_control canCloseOnlyTab] == NO) ||
[_control disableTabClose] ||
- ([[_control delegate] respondsToSelector:@selector(tabView:disableTabCloseForTabViewItem:)] &&
- [[_control delegate] tabView:[_control tabView] disableTabCloseForTabViewItem:[currentCell representedObject]]))];
-
- if ([_control orientation] == PSMTabBarHorizontalOrientation) {
- // Determine cell width
- if ([_control sizeCellsToFit]) {
+ ([[_control delegate] respondsToSelector:@selector(tabView:disableTabCloseForTabViewItem:)] &&
+ [[_control delegate] tabView:[_control tabView] disableTabCloseForTabViewItem:[currentCell representedObject]]))];
+
+ if([_control orientation] == PSMTabBarHorizontalOrientation) {
+ // Determine cell width
+ if([_control sizeCellsToFit]) {
width = [currentCell desiredWidthOfCell];
- if (width > [_control cellMaxWidth]) {
+ if(width > [_control cellMaxWidth]) {
width = [_control cellMaxWidth];
}
} else {
width = [_control cellOptimumWidth];
}
-
+
width = ceil(width);
-
+
//check to see if there is not enough space to place all tabs as preferred
- if (totalOccupiedWidth + width >= availableWidth) {
+ if(totalOccupiedWidth + width >= availableWidth) {
//There's not enough space to add currentCell at its preferred width!
-
+
//If we're not going to use the overflow menu, cram all the tab cells into the bar regardless of minimum width
- if (![_control useOverflowMenu]) {
+ if(![_control useOverflowMenu]) {
NSInteger j, averageWidth = (availableWidth / cellCount);
-
+
numberOfVisibleCells = cellCount;
[newWidths removeAllObjects];
-
- for (j = 0; j < cellCount; j++) {
+
+ for(j = 0; j < cellCount; j++) {
CGFloat desiredWidth = [[cells objectAtIndex:j] desiredWidthOfCell];
[newWidths addObject:[NSNumber numberWithDouble:(desiredWidth < averageWidth && [_control sizeCellsToFit]) ? desiredWidth : averageWidth]];
}
@@ -345,23 +332,23 @@ static NSInteger potentialMinimumForArray(NSArray *array, NSInteger minimum)
totalOccupiedWidth = [[newWidths valueForKeyPath:@"@sum.intValue"] integerValue];
break;
}
-
+
//We'll be using the overflow menu if needed.
numberOfVisibleCells = i;
- if ([_control sizeCellsToFit]) {
+ if([_control sizeCellsToFit]) {
BOOL remainingCellsMustGoToOverflow = NO;
totalOccupiedWidth = [[newWidths valueForKeyPath:@"@sum.intValue"] integerValue];
-
+
/* Can I squeeze it in without violating min cell width? This is the width we would take up
* if every cell so far were at the control minimum size (or their current size if that is less than the control minimum).
- */
- if ((potentialMinimumForArray(newWidths, [_control cellMinWidth]) + MIN(width, [_control cellMinWidth])) <= availableWidth) {
+ */
+ if((potentialMinimumForArray(newWidths, [_control cellMinWidth]) + MIN(width, [_control cellMinWidth])) <= availableWidth) {
/* It's definitely possible for cells so far to be visible.
* Shrink other cells to allow this one to fit
*/
NSInteger cellMinWidth = [_control cellMinWidth];
-
+
/* Start off adding it to the array; we know that it will eventually fit because
* (the potential minimum <= availableWidth)
*
@@ -371,45 +358,45 @@ static NSInteger potentialMinimumForArray(NSArray *array, NSInteger minimum)
numberOfVisibleCells++;
totalOccupiedWidth += width;
-
+
//First, try to shrink tabs toward the average. Tabs smaller than average won't change
totalOccupiedWidth -= [self _shrinkWidths:newWidths
- towardMinimum:[[newWidths valueForKeyPath:@"@avg.intValue"] integerValue]
+ towardMinimum:[[newWidths valueForKeyPath:@"@avg.intValue"] integerValue]
withAvailableWidth:availableWidth];
-
- if (totalOccupiedWidth > availableWidth) {
+
+ if(totalOccupiedWidth > availableWidth) {
//Next, shrink tabs toward the smallest of the existing tabs. The smallest tab won't change.
NSInteger smallestTabWidth = [[newWidths valueForKeyPath:@"@min.intValue"] integerValue];
- if (smallestTabWidth > cellMinWidth) {
+ if(smallestTabWidth > cellMinWidth) {
totalOccupiedWidth -= [self _shrinkWidths:newWidths
- towardMinimum:smallestTabWidth
+ towardMinimum:smallestTabWidth
withAvailableWidth:availableWidth];
}
}
-
- if (totalOccupiedWidth > availableWidth) {
+
+ if(totalOccupiedWidth > availableWidth) {
//Finally, shrink tabs toward the imposed minimum size. All tabs larger than the minimum wll change.
totalOccupiedWidth -= [self _shrinkWidths:newWidths
- towardMinimum:cellMinWidth
+ towardMinimum:cellMinWidth
withAvailableWidth:availableWidth];
}
- if (totalOccupiedWidth > availableWidth) {
+ if(totalOccupiedWidth > availableWidth) {
NSLog(@"**** -[PSMTabBarController generateWidthsFromCells:] This is a failure (available %f, total %f, width is %f)",
availableWidth, totalOccupiedWidth, width);
remainingCellsMustGoToOverflow = YES;
}
-
- if (totalOccupiedWidth < availableWidth) {
+
+ if(totalOccupiedWidth < availableWidth) {
/* We're not using all available space not but exceeded available width before;
* stretch all cells to fully fit the bar
*/
NSInteger leftoverWidth = availableWidth - totalOccupiedWidth;
- if (leftoverWidth > 0) {
+ if(leftoverWidth > 0) {
NSInteger q;
- for (q = numberOfVisibleCells - 1; q >= 0; q--) {
+ for(q = numberOfVisibleCells - 1; q >= 0; q--) {
NSInteger desiredAddition = (NSInteger)leftoverWidth / (q + 1);
NSInteger newCellWidth = (NSInteger)[[newWidths objectAtIndex:q] doubleValue] + desiredAddition;
[newWidths replaceObjectAtIndex:q withObject:[NSNumber numberWithDouble:newCellWidth]];
@@ -418,34 +405,32 @@ static NSInteger potentialMinimumForArray(NSArray *array, NSInteger minimum)
}
}
}
-
} else {
// stretch - distribute leftover room among cells, since we can't add this cell
NSInteger leftoverWidth = availableWidth - totalOccupiedWidth;
NSInteger q;
- for (q = i - 1; q >= 0; q--) {
+ for(q = i - 1; q >= 0; q--) {
NSInteger desiredAddition = (NSInteger)leftoverWidth / (q + 1);
NSInteger newCellWidth = (NSInteger)[[newWidths objectAtIndex:q] doubleValue] + desiredAddition;
[newWidths replaceObjectAtIndex:q withObject:[NSNumber numberWithDouble:newCellWidth]];
leftoverWidth -= desiredAddition;
}
-
+
remainingCellsMustGoToOverflow = YES;
}
// done assigning widths; remaining cells go in overflow menu
- if (remainingCellsMustGoToOverflow) {
+ if(remainingCellsMustGoToOverflow) {
break;
}
-
} else {
//We're not using size-to-fit
NSInteger revisedWidth = availableWidth / (i + 1);
- if (revisedWidth >= [_control cellMinWidth]) {
+ if(revisedWidth >= [_control cellMinWidth]) {
NSUInteger q;
totalOccupiedWidth = 0;
- for (q = 0; q < [newWidths count]; q++) {
+ for(q = 0; q < [newWidths count]; q++) {
[newWidths replaceObjectAtIndex:q withObject:[NSNumber numberWithDouble:revisedWidth]];
totalOccupiedWidth += revisedWidth;
}
@@ -464,42 +449,41 @@ static NSInteger potentialMinimumForArray(NSArray *array, NSInteger minimum)
[newWidths addObject:[NSNumber numberWithDouble:width]];
totalOccupiedWidth += width;
}
-
- } else {
- //lay out vertical tabs
- if (currentOrigin + cellRect.size.height <= controlRect.size.height) {
+ } else {
+ //lay out vertical tabs
+ if(currentOrigin + cellRect.size.height <= controlRect.size.height) {
[newWidths addObject:[NSNumber numberWithDouble:currentOrigin]];
numberOfVisibleCells++;
currentOrigin += cellRect.size.height;
} else {
//out of room, the remaining tabs go into overflow
- if ([newWidths count] > 0 && controlRect.size.height - currentOrigin < 17) {
+ if([newWidths count] > 0 && controlRect.size.height - currentOrigin < 17) {
[newWidths removeLastObject];
numberOfVisibleCells--;
}
break;
}
- }
- }
+ }
+ }
//make sure there are at least two items in the horizontal tab bar
- if ([_control orientation] == PSMTabBarHorizontalOrientation) {
- if (numberOfVisibleCells < 2 && [cells count] > 1) {
+ if([_control orientation] == PSMTabBarHorizontalOrientation) {
+ if(numberOfVisibleCells < 2 && [cells count] > 1) {
PSMTabBarCell *cell1 = [cells objectAtIndex:0], *cell2 = [cells objectAtIndex:1];
NSNumber *cellWidth;
-
+
[newWidths removeAllObjects];
totalOccupiedWidth = 0;
-
- cellWidth = [NSNumber numberWithDouble:[cell1 desiredWidthOfCell] < availableWidth * 0.5f ? [cell1 desiredWidthOfCell] : availableWidth * 0.5f];
+
+ cellWidth = [NSNumber numberWithDouble:[cell1 desiredWidthOfCell] < availableWidth * 0.5f ?[cell1 desiredWidthOfCell] : availableWidth * 0.5f];
[newWidths addObject:cellWidth];
totalOccupiedWidth += [cellWidth doubleValue];
-
- cellWidth = [NSNumber numberWithDouble:[cell2 desiredWidthOfCell] < (availableWidth - totalOccupiedWidth) ? [cell2 desiredWidthOfCell] : (availableWidth - totalOccupiedWidth)];
+
+ cellWidth = [NSNumber numberWithDouble:[cell2 desiredWidthOfCell] < (availableWidth - totalOccupiedWidth) ?[cell2 desiredWidthOfCell] : (availableWidth - totalOccupiedWidth)];
[newWidths addObject:cellWidth];
totalOccupiedWidth += [cellWidth doubleValue];
-
- if (totalOccupiedWidth < availableWidth) {
+
+ if(totalOccupiedWidth < availableWidth) {
[newWidths replaceObjectAtIndex:0 withObject:[NSNumber numberWithDouble:availableWidth - [cellWidth doubleValue]]];
}
@@ -507,136 +491,132 @@ static NSInteger potentialMinimumForArray(NSArray *array, NSInteger minimum)
}
}
- return newWidths;
+ return newWidths;
}
/*!
@method _setupCells:withWidths
@abstract Creates tracking rect arrays and sets the frames of the visible cells.
@discussion Creates tracking rect arrays and sets the cells given in the widths array.
-*/
-
-- (void)_setupCells:(NSArray *)cells withWidths:(NSArray *)widths
-{
- NSInteger i, tabState, cellCount = [cells count];
- NSRect cellRect = [_control genericCellRect];
- PSMTabBarCell *cell;
- NSTabViewItem *selectedTabViewItem = [[_control tabView] selectedTabViewItem];
- NSMenuItem *menuItem;
-
- [_overflowMenu release], _overflowMenu = nil;
-
- for (i = 0; i < cellCount; i++) {
- cell = [cells objectAtIndex:i];
-
- if (i < [widths count]) {
- tabState = 0;
-
- // set cell frame
- if ([_control orientation] == PSMTabBarHorizontalOrientation) {
- cellRect.size.width = [[widths objectAtIndex:i] doubleValue];
- } else {
- cellRect.size.width = [_control frame].size.width;
- cellRect.origin.y = [[widths objectAtIndex:i] doubleValue];
- cellRect.origin.x = 0;
- }
-
- [_cellFrames addObject:[NSValue valueWithRect:cellRect]];
-
- //add tracking rects to arrays
- [_closeButtonTrackingRects addObject:[NSValue valueWithRect:[cell closeButtonRectForFrame:cellRect]]];
- [_cellTrackingRects addObject:[NSValue valueWithRect:cellRect]];
-
- if ([[cell representedObject] isEqualTo:selectedTabViewItem]) {
- [cell setState:NSOnState];
- tabState |= PSMTab_SelectedMask;
- // previous cell
- if (i > 0) {
- [[cells objectAtIndex:i - 1] setTabState:([(PSMTabBarCell *)[cells objectAtIndex:i - 1] tabState] | PSMTab_RightIsSelectedMask)];
- }
- // next cell - see below
- } else {
- [cell setState:NSOffState];
- // see if prev cell was selected
- if ( (i > 0) && ([[cells objectAtIndex:i - 1] state] == NSOnState) ) {
- tabState |= PSMTab_LeftIsSelectedMask;
- }
- }
-
- // more tab states
- if ([widths count] == 1) {
- tabState |= PSMTab_PositionLeftMask | PSMTab_PositionRightMask | PSMTab_PositionSingleMask;
- } else if (i == 0) {
- tabState |= PSMTab_PositionLeftMask;
- } else if (i == [widths count] - 1) {
- tabState |= PSMTab_PositionRightMask;
- }
-
- [cell setTabState:tabState];
- [cell setIsInOverflowMenu:NO];
-
- // indicator
- if (![[cell indicator] isHidden] && ![_control isTabBarHidden]) {
- if (![[_control subviews] containsObject:[cell indicator]]) {
- [_control addSubview:[cell indicator]];
- [[cell indicator] startAnimation:self];
- }
- }
-
- // next...
- cellRect.origin.x += [[widths objectAtIndex:i] doubleValue];
- } else {
- [cell setState:NSOffState];
- [cell setIsInOverflowMenu:YES];
- [[cell indicator] removeFromSuperview];
-
+ */
+
+- (void)_setupCells:(NSArray *)cells withWidths:(NSArray *)widths {
+ NSInteger i, tabState, cellCount = [cells count];
+ NSRect cellRect = [_control genericCellRect];
+ PSMTabBarCell *cell;
+ NSTabViewItem *selectedTabViewItem = [[_control tabView] selectedTabViewItem];
+ NSMenuItem *menuItem;
+
+ [_overflowMenu release], _overflowMenu = nil;
+
+ for(i = 0; i < cellCount; i++) {
+ cell = [cells objectAtIndex:i];
+
+ if(i < [widths count]) {
+ tabState = 0;
+
+ // set cell frame
+ if([_control orientation] == PSMTabBarHorizontalOrientation) {
+ cellRect.size.width = [[widths objectAtIndex:i] doubleValue];
+ } else {
+ cellRect.size.width = [_control frame].size.width;
+ cellRect.origin.y = [[widths objectAtIndex:i] doubleValue];
+ cellRect.origin.x = 0;
+ }
+
+ [_cellFrames addObject:[NSValue valueWithRect:cellRect]];
+
+ //add tracking rects to arrays
+ [_closeButtonTrackingRects addObject:[NSValue valueWithRect:[cell closeButtonRectForFrame:cellRect]]];
+ [_cellTrackingRects addObject:[NSValue valueWithRect:cellRect]];
+
+ if([[cell representedObject] isEqualTo:selectedTabViewItem]) {
+ [cell setState:NSOnState];
+ tabState |= PSMTab_SelectedMask;
+ // previous cell
+ if(i > 0) {
+ [[cells objectAtIndex:i - 1] setTabState:([(PSMTabBarCell *)[cells objectAtIndex:i - 1] tabState] | PSMTab_RightIsSelectedMask)];
+ }
+ // next cell - see below
+ } else {
+ [cell setState:NSOffState];
+ // see if prev cell was selected
+ if((i > 0) && ([[cells objectAtIndex:i - 1] state] == NSOnState)) {
+ tabState |= PSMTab_LeftIsSelectedMask;
+ }
+ }
+
+ // more tab states
+ if([widths count] == 1) {
+ tabState |= PSMTab_PositionLeftMask | PSMTab_PositionRightMask | PSMTab_PositionSingleMask;
+ } else if(i == 0) {
+ tabState |= PSMTab_PositionLeftMask;
+ } else if(i == [widths count] - 1) {
+ tabState |= PSMTab_PositionRightMask;
+ }
+
+ [cell setTabState:tabState];
+ [cell setIsInOverflowMenu:NO];
+
+ // indicator
+ if(![[cell indicator] isHidden] && ![_control isTabBarHidden]) {
+ if(![[_control subviews] containsObject:[cell indicator]]) {
+ [_control addSubview:[cell indicator]];
+ [[cell indicator] startAnimation:self];
+ }
+ }
+
+ // next...
+ cellRect.origin.x += [[widths objectAtIndex:i] doubleValue];
+ } else {
+ [cell setState:NSOffState];
+ [cell setIsInOverflowMenu:YES];
+ [[cell indicator] removeFromSuperview];
+
//position the cell well offscreen
- if ([_control orientation] == PSMTabBarHorizontalOrientation) {
+ if([_control orientation] == PSMTabBarHorizontalOrientation) {
cellRect.origin.x += [[_control style] rightMarginForTabBarControl] + 20;
} else {
cellRect.origin.y = [_control frame].size.height + 2;
}
-
- [_cellFrames addObject:[NSValue valueWithRect:cellRect]];
-
- if (_overflowMenu == nil) {
- _overflowMenu = [[NSMenu alloc] init];
- [_overflowMenu insertItemWithTitle:@"" action:nil keyEquivalent:@"" atIndex:0]; // Because the overflowPupUpButton is a pull down menu
+
+ [_cellFrames addObject:[NSValue valueWithRect:cellRect]];
+
+ if(_overflowMenu == nil) {
+ _overflowMenu = [[NSMenu alloc] init];
+ [_overflowMenu insertItemWithTitle:@"" action:nil keyEquivalent:@"" atIndex:0]; // Because the overflowPupUpButton is a pull down menu
[_overflowMenu setDelegate:self];
- }
-
+ }
+
// Each item's title is limited to 60 characters. If more than 60 characters, use an ellipsis to indicate that more exists.
- menuItem = [_overflowMenu addItemWithTitle:[[[cell attributedStringValue] string] stringWithEllipsisByTruncatingToLength:MAX_OVERFLOW_MENUITEM_TITLE_LENGTH]
- action:@selector(overflowMenuAction:)
- keyEquivalent:@""];
- [menuItem setTarget:_control];
- [menuItem setRepresentedObject:[cell representedObject]];
-
- if ([cell count] > 0) {
- [menuItem setTitle:[[menuItem title] stringByAppendingFormat:@" (%lu)", (unsigned long)[cell count]]];
+ menuItem = [_overflowMenu addItemWithTitle:[[[cell attributedStringValue] string] stringWithEllipsisByTruncatingToLength:MAX_OVERFLOW_MENUITEM_TITLE_LENGTH]
+ action:@selector(overflowMenuAction:)
+ keyEquivalent:@""];
+ [menuItem setTarget:_control];
+ [menuItem setRepresentedObject:[cell representedObject]];
+
+ if([cell count] > 0) {
+ [menuItem setTitle:[[menuItem title] stringByAppendingFormat:@" (%lu)", (unsigned long)[cell count]]];
}
- }
- }
+ }
+ }
}
-- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)menuItem atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
-{
- if (menu == _overflowMenu) {
- if ([[[menuItem representedObject] identifier] respondsToSelector:@selector(icon)]) {
+- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)menuItem atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel {
+ if(menu == _overflowMenu) {
+ if([[[menuItem representedObject] identifier] respondsToSelector:@selector(icon)]) {
[menuItem setImage:[[[menuItem representedObject] identifier] valueForKey:@"icon"]];
}
}
-
+
return TRUE;
}
-- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu
-{
- if (menu == _overflowMenu) {
+- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu {
+ if(menu == _overflowMenu) {
return [_overflowMenu numberOfItems];
-
} else {
- NSLog(@"Warning: Unexpected menu delegate call for menu %@",menu);
+ NSLog(@"Warning: Unexpected menu delegate call for menu %@", menu);
return 0;
}
}
@@ -644,20 +624,20 @@ static NSInteger potentialMinimumForArray(NSArray *array, NSInteger minimum)
@end
/*
-PSMTabBarController will store what the current tab frame state should be like based off the last layout. PSMTabBarControl
-has to handle fetching the new frame and then changing the tab cell frame.
+ PSMTabBarController will store what the current tab frame state should be like based off the last layout. PSMTabBarControl
+ has to handle fetching the new frame and then changing the tab cell frame.
Tab states will probably be changed immediately.
-Tabs that aren't going to be visible need to have their frame set offscreen. Treat them as if they were visible.
+ Tabs that aren't going to be visible need to have their frame set offscreen. Treat them as if they were visible.
-The overflow menu is rebuilt and stored by the controller.
+ The overflow menu is rebuilt and stored by the controller.
-Arrays of tracking rects will be created here, but not applied.
+ Arrays of tracking rects will be created here, but not applied.
Tracking rects are removed and added by PSMTabBarControl at the end of an animate/display cycle.
-The add tab button frame is handled by this controller. Visibility and location are set by the control.
+ The add tab button frame is handled by this controller. Visibility and location are set by the control.
-isInOverflowMenu should probably be removed in favor of a call that returns yes/no to if a cell is in overflow. (Not yet implemented)
+ isInOverflowMenu should probably be removed in favor of a call that returns yes/no to if a cell is in overflow. (Not yet implemented)
-Still need to rewrite most of the code in PSMTabDragAssistant.
-*/
+ Still need to rewrite most of the code in PSMTabDragAssistant.
+ */