diff options
author | Sven Weidauer <sven.weidauer@gmail.com> | 2011-01-26 10:52:13 +0000 |
---|---|---|
committer | Sven Weidauer <sven.weidauer@gmail.com> | 2011-01-26 10:52:13 +0000 |
commit | 7b2694e9f6c35d9f50c3fb3cf38b0fc766478162 (patch) | |
tree | c4e3d07a6bb51de884f53312a96d05849f072db1 /cocoa/PSMTabBarControl/PSMTabBarControl.m | |
parent | a663cf8f84942e1147d1d2f3db292308639c7fa5 (diff) | |
download | netsurf-7b2694e9f6c35d9f50c3fb3cf38b0fc766478162.tar.gz netsurf-7b2694e9f6c35d9f50c3fb3cf38b0fc766478162.tar.bz2 |
Updated PSMTabBarControl source code to version from https://github.com/dergraf83/PSMTabBarControl
svn path=/trunk/netsurf/; revision=11490
Diffstat (limited to 'cocoa/PSMTabBarControl/PSMTabBarControl.m')
-rw-r--r-- | cocoa/PSMTabBarControl/PSMTabBarControl.m | 2126 |
1 files changed, 1015 insertions, 1111 deletions
diff --git a/cocoa/PSMTabBarControl/PSMTabBarControl.m b/cocoa/PSMTabBarControl/PSMTabBarControl.m index 3c7271b40..865180417 100644 --- a/cocoa/PSMTabBarControl/PSMTabBarControl.m +++ b/cocoa/PSMTabBarControl/PSMTabBarControl.m @@ -15,50 +15,48 @@ #import "PSMTabDragAssistant.h" #import "PSMTabBarController.h" -#include <bitstring.h> - @interface PSMTabBarControl (Private) - // constructor/destructor +// constructor/destructor - (void)initAddedProperties; - // accessors +// accessors - (NSEvent *)lastMouseDownEvent; - (void)setLastMouseDownEvent:(NSEvent *)event; - // contents +// contents - (void)addTabViewItem:(NSTabViewItem *)item; - (void)removeTabForCell:(PSMTabBarCell *)cell; - // draw +// draw - (void)update; - (void)update:(BOOL)animate; - (void)_setupTrackingRectsForCell:(PSMTabBarCell *)cell; - (void)_positionOverflowMenu; - (void)_checkWindowFrame; - // actions +// actions - (void)overflowMenuAction:(id)sender; - (void)closeTabClick:(id)sender; - (void)tabClick:(id)sender; - (void)tabNothing:(id)sender; - // notification handlers +// notification handlers - (void)frameDidChange:(NSNotification *)notification; - (void)windowDidMove:(NSNotification *)aNotification; - (void)windowDidUpdate:(NSNotification *)notification; - // NSTabView delegate +// NSTabView delegate - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem; - (BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem; - (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem; - (void)tabViewDidChangeNumberOfTabViewItems:(NSTabView *)tabView; - // archiving +// archiving - (void)encodeWithCoder:(NSCoder *)aCoder; - (id)initWithCoder:(NSCoder *)aDecoder; - // convenience +// convenience - (void)_bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewItem *)item; - (id)cellForPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame; @@ -71,9 +69,11 @@ #pragma mark Characteristics + (NSBundle *)bundle; { - static NSBundle *bundle = nil; - if (!bundle) bundle = [NSBundle bundleForClass:[PSMTabBarControl class]]; - return bundle; + static NSBundle *bundle = nil; + if(!bundle) { + bundle = [NSBundle bundleForClass:[PSMTabBarControl class]]; + } + return bundle; } /*! @@ -81,11 +81,10 @@ @abstract The number of pixels available for cells @discussion Calculates the number of pixels available for cells based on margins and the window resize badge. @returns Returns the amount of space for cells. -*/ + */ -- (CGFloat)availableCellWidth -{ - return [self frame].size.width - [style leftMarginForTabBarControl] - [style rightMarginForTabBarControl] - _resizeAreaCompensation; +- (CGFloat)availableCellWidth { + return [self frame].size.width - [style leftMarginForTabBarControl] - [style rightMarginForTabBarControl] - _resizeAreaCompensation; } /*! @@ -93,114 +92,115 @@ @abstract The basic rect for a tab cell. @discussion Creates a generic frame for a tab cell based on the current control state. @returns Returns a basic rect for a tab cell. -*/ + */ -- (NSRect)genericCellRect -{ - NSRect aRect=[self frame]; - aRect.origin.x = [style leftMarginForTabBarControl]; - aRect.origin.y = 0.0; - aRect.size.width = [self availableCellWidth]; - aRect.size.height = [style tabCellHeight]; - return aRect; +- (NSRect)genericCellRect { + NSRect aRect = [self frame]; + aRect.origin.x = [style leftMarginForTabBarControl]; + aRect.origin.y = 0.0; + aRect.size.width = [self availableCellWidth]; + aRect.size.height = [style tabCellHeight]; + return aRect; } #pragma mark - #pragma mark Constructor/destructor -- (void)initAddedProperties -{ - _cells = [[NSMutableArray alloc] initWithCapacity:10]; +- (void)initAddedProperties { + _cells = [[NSMutableArray alloc] initWithCapacity:10]; _controller = [[PSMTabBarController alloc] initWithTabBarControl:self]; - _animationTimer = nil; - - // default config + _animationTimer = nil; + + // default config _currentStep = kPSMIsNotBeingResized; _orientation = PSMTabBarHorizontalOrientation; - _canCloseOnlyTab = NO; + _canCloseOnlyTab = NO; _disableTabClose = NO; - _showAddTabButton = NO; - _hideForSingleTab = NO; - _sizeCellsToFit = NO; - _isHidden = NO; - _awakenedFromNib = NO; + _showAddTabButton = NO; + _hideForSingleTab = NO; + _sizeCellsToFit = NO; + _isHidden = NO; + _awakenedFromNib = NO; _automaticallyAnimates = NO; - _useOverflowMenu = YES; + _useOverflowMenu = YES; _allowsBackgroundTabClosing = YES; _allowsResizing = NO; _selectsTabsOnMouseDown = NO; - _alwaysShowActiveTab = NO; + _alwaysShowActiveTab = NO; _allowsScrubbing = NO; - _cellMinWidth = 100; - _cellMaxWidth = 280; - _cellOptimumWidth = 130; + _cellMinWidth = 100; + _cellMaxWidth = 280; + _cellOptimumWidth = 130; _tearOffStyle = PSMTabBarTearOffAlphaWindow; - style = [[PSMUnifiedTabStyle alloc] init]; - - // the overflow button/menu - NSRect overflowButtonRect = NSMakeRect([self frame].size.width - [style rightMarginForTabBarControl] + 1, 0, [style rightMarginForTabBarControl] - 1, [self frame].size.height); - _overflowPopUpButton = [[PSMOverflowPopUpButton alloc] initWithFrame:overflowButtonRect pullsDown:YES]; - [_overflowPopUpButton setAutoresizingMask:NSViewNotSizable | NSViewMinXMargin]; - [_overflowPopUpButton setHidden:YES]; - [self addSubview:_overflowPopUpButton]; - [self _positionOverflowMenu]; - - // new tab button - NSRect addTabButtonRect = NSMakeRect([self frame].size.width - [style rightMarginForTabBarControl] + 1, 3.0, 16.0, 16.0); - _addTabButton = [[PSMRolloverButton alloc] initWithFrame:addTabButtonRect]; - if (_addTabButton) { - NSImage *newButtonImage = [style addTabButtonImage]; - if (newButtonImage) { - [_addTabButton setUsualImage:newButtonImage]; - } - newButtonImage = [style addTabButtonPressedImage]; - if (newButtonImage) { - [_addTabButton setAlternateImage:newButtonImage]; - } - newButtonImage = [style addTabButtonRolloverImage]; - if (newButtonImage) { - [_addTabButton setRolloverImage:newButtonImage]; - } - [_addTabButton setTitle:@""]; - [_addTabButton setImagePosition:NSImageOnly]; - [_addTabButton setButtonType:NSMomentaryChangeButton]; - [_addTabButton setBordered:NO]; - [_addTabButton setBezelStyle:NSShadowlessSquareBezelStyle]; - [self addSubview:_addTabButton]; - - if (_showAddTabButton) { - [_addTabButton setHidden:NO]; - } else { - [_addTabButton setHidden:YES]; - } - [_addTabButton setNeedsDisplay:YES]; - } -} - -- (id)initWithFrame:(NSRect)frame + style = [[[[self class] defaultStyleClass] alloc] init]; + + // the overflow button/menu + NSRect overflowButtonRect = NSMakeRect([self frame].size.width - [style rightMarginForTabBarControl] + 1, 0, [style rightMarginForTabBarControl] - 1, [self frame].size.height); + _overflowPopUpButton = [[PSMOverflowPopUpButton alloc] initWithFrame:overflowButtonRect pullsDown:YES]; + [_overflowPopUpButton setAutoresizingMask:NSViewNotSizable | NSViewMinXMargin]; + [_overflowPopUpButton setHidden:YES]; + [self addSubview:_overflowPopUpButton]; + [self _positionOverflowMenu]; + + // new tab button + NSRect addTabButtonRect = NSMakeRect([self frame].size.width - [style rightMarginForTabBarControl] + 1, 3.0, 16.0, 16.0); + _addTabButton = [[PSMRolloverButton alloc] initWithFrame:addTabButtonRect]; + if(_addTabButton) { + NSImage *newButtonImage = [style addTabButtonImage]; + if(newButtonImage) { + [_addTabButton setUsualImage:newButtonImage]; + } + newButtonImage = [style addTabButtonPressedImage]; + if(newButtonImage) { + [_addTabButton setAlternateImage:newButtonImage]; + } + newButtonImage = [style addTabButtonRolloverImage]; + if(newButtonImage) { + [_addTabButton setRolloverImage:newButtonImage]; + } + [_addTabButton setTitle:@""]; + [_addTabButton setImagePosition:NSImageOnly]; + [_addTabButton setButtonType:NSMomentaryChangeButton]; + [_addTabButton setBordered:NO]; + [_addTabButton setBezelStyle:NSShadowlessSquareBezelStyle]; + [self addSubview:_addTabButton]; + + if(_showAddTabButton) { + [_addTabButton setHidden:NO]; + } else { + [_addTabButton setHidden:YES]; + } + [_addTabButton setNeedsDisplay:YES]; + } +} + ++ (Class) defaultStyleClass; { - self = [super initWithFrame:frame]; - if (self) { - // Initialization - [self initAddedProperties]; - [self registerForDraggedTypes:[NSArray arrayWithObjects:@"PSMTabBarControlItemPBType", nil]]; - + return [PSMUnifiedTabStyle class]; +} + +- (id)initWithFrame:(NSRect)frame { + self = [super initWithFrame:frame]; + if(self) { + // Initialization + [self initAddedProperties]; + [self registerForDraggedTypes:[NSArray arrayWithObjects:@"PSMTabBarControlItemPBType", nil]]; + // resize [self setPostsFrameChangedNotifications:YES]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(frameDidChange:) name:NSViewFrameDidChangeNotification object:self]; - } - [self setTarget:self]; - return self; + } + [self setTarget:self]; + return self; } -- (void)dealloc -{ +- (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - + //stop any animations that may be running [_animationTimer invalidate]; [_animationTimer release]; _animationTimer = nil; - + [_showHideAnimationTimer invalidate]; [_showHideAnimationTimer release]; _showHideAnimationTimer = nil; @@ -210,538 +210,496 @@ //unbind all the items to prevent crashing //not sure if this is necessary or not - NSEnumerator *enumerator = [_cells objectEnumerator]; + // http://code.google.com/p/maccode/issues/detail?id=35 + NSEnumerator *enumerator = [[[_cells copy] autorelease] objectEnumerator]; PSMTabBarCell *nextCell; - while ( (nextCell = [enumerator nextObject]) ) { + while((nextCell = [enumerator nextObject])) { [self removeTabForCell:nextCell]; } - - [_overflowPopUpButton release]; - [_cells release]; + + [_overflowPopUpButton release]; + [_cells release]; [_controller release]; - [tabView release]; - [_addTabButton release]; - [partnerView release]; - [_lastMouseDownEvent release]; - [style release]; - - [self unregisterDraggedTypes]; - - [super dealloc]; + [tabView release]; + [_addTabButton release]; + [partnerView release]; + [_lastMouseDownEvent release]; + [style release]; + + [self unregisterDraggedTypes]; + + [super dealloc]; } -- (void)awakeFromNib -{ - // build cells from existing tab view items - NSArray *existingItems = [tabView tabViewItems]; - NSEnumerator *e = [existingItems objectEnumerator]; - NSTabViewItem *item; - while ( (item = [e nextObject]) ) { - if (![[self representedTabViewItems] containsObject:item]) { - [self addTabViewItem:item]; +- (void)awakeFromNib { + // build cells from existing tab view items + NSArray *existingItems = [tabView tabViewItems]; + NSEnumerator *e = [existingItems objectEnumerator]; + NSTabViewItem *item; + while((item = [e nextObject])) { + if(![[self representedTabViewItems] containsObject:item]) { + [self addTabViewItem:item]; } - } + } } - (void)viewWillMoveToWindow:(NSWindow *)aWindow { - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center removeObserver:self name:NSWindowDidBecomeKeyNotification object:nil]; [center removeObserver:self name:NSWindowDidResignKeyNotification object:nil]; [center removeObserver:self name:NSWindowDidUpdateNotification object:nil]; [center removeObserver:self name:NSWindowDidMoveNotification object:nil]; - - if (_showHideAnimationTimer) { + + if(_showHideAnimationTimer) { [_showHideAnimationTimer invalidate]; [_showHideAnimationTimer release]; _showHideAnimationTimer = nil; } - - if (aWindow) { + + if(aWindow) { [center addObserver:self selector:@selector(windowStatusDidChange:) name:NSWindowDidBecomeKeyNotification object:aWindow]; [center addObserver:self selector:@selector(windowStatusDidChange:) name:NSWindowDidResignKeyNotification object:aWindow]; [center addObserver:self selector:@selector(windowDidUpdate:) name:NSWindowDidUpdateNotification object:aWindow]; [center addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:aWindow]; - } + } } -- (void)windowStatusDidChange:(NSNotification *)notification -{ +- (void)windowStatusDidChange:(NSNotification *)notification { [self setNeedsDisplay:YES]; } #pragma mark - #pragma mark Accessors -- (NSMutableArray *)cells -{ - return _cells; +- (NSMutableArray *)cells { + return _cells; } -- (NSEvent *)lastMouseDownEvent -{ - return _lastMouseDownEvent; +- (NSEvent *)lastMouseDownEvent { + return _lastMouseDownEvent; } -- (void)setLastMouseDownEvent:(NSEvent *)event -{ - [event retain]; - [_lastMouseDownEvent release]; - _lastMouseDownEvent = event; +- (void)setLastMouseDownEvent:(NSEvent *)event { + [event retain]; + [_lastMouseDownEvent release]; + _lastMouseDownEvent = event; } -- (id)delegate -{ - return delegate; +- (id)delegate { + return delegate; } -- (void)setDelegate:(id)object -{ - delegate = object; - +- (void)setDelegate:(id)object { + delegate = object; + NSMutableArray *types = [NSMutableArray arrayWithObject:@"PSMTabBarControlItemPBType"]; - + //Update the allowed drag types - if ([self delegate] && [[self delegate] respondsToSelector:@selector(allowedDraggedTypesForTabView:)]) { + if([self delegate] && [[self delegate] respondsToSelector:@selector(allowedDraggedTypesForTabView:)]) { [types addObjectsFromArray:[[self delegate] allowedDraggedTypesForTabView:tabView]]; } [self unregisterDraggedTypes]; [self registerForDraggedTypes:types]; } -- (NSTabView *)tabView -{ - return tabView; +- (NSTabView *)tabView { + return tabView; } -- (void)setTabView:(NSTabView *)view -{ - [view retain]; - [tabView release]; - tabView = view; +- (void)setTabView:(NSTabView *)view { + [view retain]; + [tabView release]; + tabView = view; } -- (id<PSMTabStyle>)style -{ - return style; +- (id<PSMTabStyle>)style { + return style; } -- (NSString *)styleName -{ - return [style name]; +- (NSString *)styleName { + return [style name]; } -- (void)setStyle:(id <PSMTabStyle>)newStyle -{ - if (style != newStyle) { - [style autorelease]; - style = [newStyle retain]; - - // restyle add tab button - if (_addTabButton) { - NSImage *newButtonImage = [style addTabButtonImage]; - if (newButtonImage) { - [_addTabButton setUsualImage:newButtonImage]; - } - - newButtonImage = [style addTabButtonPressedImage]; - if (newButtonImage) { - [_addTabButton setAlternateImage:newButtonImage]; - } - - newButtonImage = [style addTabButtonRolloverImage]; - if (newButtonImage) { - [_addTabButton setRolloverImage:newButtonImage]; - } - } - - [self update]; - } -} - -- (void)setStyleNamed:(NSString *)name -{ - id <PSMTabStyle> newStyle = [[PSMUnifiedTabStyle alloc] init]; - [self setStyle:newStyle]; - [newStyle release]; +- (void)setStyle:(id <PSMTabStyle>)newStyle { + if(style != newStyle) { + [style autorelease]; + style = [newStyle retain]; + + // restyle add tab button + if(_addTabButton) { + NSImage *newButtonImage = [style addTabButtonImage]; + if(newButtonImage) { + [_addTabButton setUsualImage:newButtonImage]; + } + + newButtonImage = [style addTabButtonPressedImage]; + if(newButtonImage) { + [_addTabButton setAlternateImage:newButtonImage]; + } + + newButtonImage = [style addTabButtonRolloverImage]; + if(newButtonImage) { + [_addTabButton setRolloverImage:newButtonImage]; + } + } + + [self update]; + } } -- (PSMTabBarOrientation)orientation -{ +- (void)setStyleNamed:(NSString *)name { + + Class styleClass = NSClassFromString( [NSString stringWithFormat: @"PSM%@TabStyle", [name capitalizedString]] ); + if (styleClass == Nil) styleClass = [isa defaultStyleClass]; + + id <PSMTabStyle> newStyle = [[styleClass alloc] init]; + [self setStyle:newStyle]; + [newStyle release]; +} + +- (PSMTabBarOrientation)orientation { return _orientation; } -- (void)setOrientation:(PSMTabBarOrientation)value -{ +- (void)setOrientation:(PSMTabBarOrientation)value { PSMTabBarOrientation lastOrientation = _orientation; _orientation = value; - if (_tabBarWidth < 10) { + if(_tabBarWidth < 10) { _tabBarWidth = 120; } - - if (lastOrientation != _orientation) { + + if(lastOrientation != _orientation) { [[self style] setOrientation:_orientation]; - [self _positionOverflowMenu]; //move the overflow popup button to the right place + [self _positionOverflowMenu]; //move the overflow popup button to the right place [self update:NO]; } } -- (BOOL)canCloseOnlyTab -{ - return _canCloseOnlyTab; +- (BOOL)canCloseOnlyTab { + return _canCloseOnlyTab; } -- (void)setCanCloseOnlyTab:(BOOL)value -{ - _canCloseOnlyTab = value; - if ([_cells count] == 1) { - [self update]; - } +- (void)setCanCloseOnlyTab:(BOOL)value { + _canCloseOnlyTab = value; + if([_cells count] == 1) { + [self update]; + } } -- (BOOL)disableTabClose -{ +- (BOOL)disableTabClose { return _disableTabClose; } -- (void)setDisableTabClose:(BOOL)value -{ +- (void)setDisableTabClose:(BOOL)value { _disableTabClose = value; [self update]; } -- (BOOL)hideForSingleTab -{ - return _hideForSingleTab; +- (BOOL)hideForSingleTab { + return _hideForSingleTab; } -- (void)setHideForSingleTab:(BOOL)value -{ - _hideForSingleTab = value; - [self update]; +- (void)setHideForSingleTab:(BOOL)value { + _hideForSingleTab = value; + [self update]; } -- (BOOL)showAddTabButton -{ - return _showAddTabButton; +- (BOOL)showAddTabButton { + return _showAddTabButton; } -- (void)setShowAddTabButton:(BOOL)value -{ - _showAddTabButton = value; - if (!NSIsEmptyRect([_controller addButtonRect])) +- (void)setShowAddTabButton:(BOOL)value { + _showAddTabButton = value; + if(!NSIsEmptyRect([_controller addButtonRect])) { [_addTabButton setFrame:[_controller addButtonRect]]; + } - [_addTabButton setHidden:!_showAddTabButton]; + [_addTabButton setHidden:!_showAddTabButton]; [_addTabButton setNeedsDisplay:YES]; [self update]; } -- (NSInteger)cellMinWidth -{ - return _cellMinWidth; +- (NSInteger)cellMinWidth { + return _cellMinWidth; } -- (void)setCellMinWidth:(NSInteger)value -{ - _cellMinWidth = value; - [self update]; +- (void)setCellMinWidth:(NSInteger)value { + _cellMinWidth = value; + [self update]; } -- (NSInteger)cellMaxWidth -{ - return _cellMaxWidth; +- (NSInteger)cellMaxWidth { + return _cellMaxWidth; } -- (void)setCellMaxWidth:(NSInteger)value -{ - _cellMaxWidth = value; - [self update]; +- (void)setCellMaxWidth:(NSInteger)value { + _cellMaxWidth = value; + [self update]; } -- (NSInteger)cellOptimumWidth -{ - return _cellOptimumWidth; +- (NSInteger)cellOptimumWidth { + return _cellOptimumWidth; } -- (void)setCellOptimumWidth:(NSInteger)value -{ - _cellOptimumWidth = value; - [self update]; +- (void)setCellOptimumWidth:(NSInteger)value { + _cellOptimumWidth = value; + [self update]; } -- (BOOL)sizeCellsToFit -{ - return _sizeCellsToFit; +- (BOOL)sizeCellsToFit { + return _sizeCellsToFit; } -- (void)setSizeCellsToFit:(BOOL)value -{ - _sizeCellsToFit = value; - [self update]; +- (void)setSizeCellsToFit:(BOOL)value { + _sizeCellsToFit = value; + [self update]; } -- (BOOL)useOverflowMenu -{ - return _useOverflowMenu; +- (BOOL)useOverflowMenu { + return _useOverflowMenu; } -- (void)setUseOverflowMenu:(BOOL)value -{ - _useOverflowMenu = value; - [self update]; +- (void)setUseOverflowMenu:(BOOL)value { + _useOverflowMenu = value; + [self update]; } -- (PSMRolloverButton *)addTabButton -{ - return _addTabButton; +- (PSMRolloverButton *)addTabButton { + return _addTabButton; } -- (PSMOverflowPopUpButton *)overflowPopUpButton -{ - return _overflowPopUpButton; +- (PSMOverflowPopUpButton *)overflowPopUpButton { + return _overflowPopUpButton; } -- (BOOL)allowsBackgroundTabClosing -{ +- (BOOL)allowsBackgroundTabClosing { return _allowsBackgroundTabClosing; } -- (void)setAllowsBackgroundTabClosing:(BOOL)value -{ +- (void)setAllowsBackgroundTabClosing:(BOOL)value { _allowsBackgroundTabClosing = value; } -- (BOOL)allowsResizing -{ +- (BOOL)allowsResizing { return _allowsResizing; } -- (void)setAllowsResizing:(BOOL)value -{ +- (void)setAllowsResizing:(BOOL)value { _allowsResizing = value; } -- (BOOL)selectsTabsOnMouseDown -{ +- (BOOL)selectsTabsOnMouseDown { return _selectsTabsOnMouseDown; } -- (void)setSelectsTabsOnMouseDown:(BOOL)value -{ +- (void)setSelectsTabsOnMouseDown:(BOOL)value { _selectsTabsOnMouseDown = value; } -- (BOOL)automaticallyAnimates -{ +- (BOOL)automaticallyAnimates { return _automaticallyAnimates; } -- (void)setAutomaticallyAnimates:(BOOL)value -{ +- (void)setAutomaticallyAnimates:(BOOL)value { _automaticallyAnimates = value; } -- (BOOL)alwaysShowActiveTab -{ +- (BOOL)alwaysShowActiveTab { return _alwaysShowActiveTab; } -- (void)setAlwaysShowActiveTab:(BOOL)value -{ +- (void)setAlwaysShowActiveTab:(BOOL)value { _alwaysShowActiveTab = value; } -- (BOOL)allowsScrubbing -{ +- (BOOL)allowsScrubbing { return _allowsScrubbing; } -- (void)setAllowsScrubbing:(BOOL)value -{ +- (void)setAllowsScrubbing:(BOOL)value { _allowsScrubbing = value; } -- (PSMTabBarTearOffStyle)tearOffStyle -{ +- (PSMTabBarTearOffStyle)tearOffStyle { return _tearOffStyle; } -- (void)setTearOffStyle:(PSMTabBarTearOffStyle)tearOffStyle -{ +- (void)setTearOffStyle:(PSMTabBarTearOffStyle)tearOffStyle { _tearOffStyle = tearOffStyle; } #pragma mark - #pragma mark Functionality -- (void)addTabViewItem:(NSTabViewItem *)item -{ - // create cell - PSMTabBarCell *cell = [[PSMTabBarCell alloc] initWithControlView:self]; - NSRect cellRect, lastCellFrame = [[_cells lastObject] frame]; - - if ([self orientation] == PSMTabBarHorizontalOrientation) { +- (void)addTabViewItem:(NSTabViewItem *)item { + // create cell + PSMTabBarCell *cell = [[PSMTabBarCell alloc] initWithControlView:self]; + NSRect cellRect, lastCellFrame; + if([_cells lastObject] != nil) { + cellRect = lastCellFrame = [[_cells lastObject] frame]; + } else { + cellRect = lastCellFrame = NSZeroRect; + } + + if([self orientation] == PSMTabBarHorizontalOrientation) { cellRect = [self genericCellRect]; cellRect.size.width = 30; cellRect.origin.x = lastCellFrame.origin.x + lastCellFrame.size.width; } else { - cellRect = /*lastCellFrame*/[self genericCellRect]; + cellRect = /*lastCellFrame*/ [self genericCellRect]; cellRect.size.width = lastCellFrame.size.width; cellRect.size.height = 0; cellRect.origin.y = lastCellFrame.origin.y + lastCellFrame.size.height; } - - [cell setRepresentedObject:item]; + + [cell setRepresentedObject:item]; [cell setFrame:cellRect]; - - // bind it up - [self bindPropertiesForCell:cell andTabViewItem:item]; - - // add to collection - [_cells addObject:cell]; - [cell release]; - if ([_cells count] == [tabView numberOfTabViewItems]) { - [self update]; // don't update unless all are accounted for! + + // bind it up + [self bindPropertiesForCell:cell andTabViewItem:item]; + + // add to collection + [_cells addObject:cell]; + [cell release]; + if([_cells count] == [tabView numberOfTabViewItems]) { + [self update]; // don't update unless all are accounted for! } } -- (void)removeTabForCell:(PSMTabBarCell *)cell -{ +- (void)removeTabForCell:(PSMTabBarCell *)cell { NSTabViewItem *item = [cell representedObject]; - - // unbind - [[cell indicator] unbind:@"animate"]; - [[cell indicator] unbind:@"hidden"]; - [cell unbind:@"hasIcon"]; - [cell unbind:@"hasLargeImage"]; - [cell unbind:@"title"]; - [cell unbind:@"count"]; + + // unbind + [[cell indicator] unbind:@"animate"]; + [[cell indicator] unbind:@"hidden"]; + [cell unbind:@"hasIcon"]; + [cell unbind:@"hasLargeImage"]; + [cell unbind:@"title"]; + [cell unbind:@"count"]; [cell unbind:@"countColor"]; - [cell unbind:@"isEdited"]; + [cell unbind:@"isEdited"]; - if ([item identifier] != nil) { - if ([[item identifier] respondsToSelector:@selector(isProcessing)]) { + if([item identifier] != nil) { + if([[item identifier] respondsToSelector:@selector(isProcessing)]) { [[item identifier] removeObserver:cell forKeyPath:@"isProcessing"]; } } - - if ([item identifier] != nil) { - if ([[item identifier] respondsToSelector:@selector(icon)]) { + + if([item identifier] != nil) { + if([[item identifier] respondsToSelector:@selector(icon)]) { [[item identifier] removeObserver:cell forKeyPath:@"icon"]; } } - - if ([item identifier] != nil) { - if ([[item identifier] respondsToSelector:@selector(objectCount)]) { + + if([item identifier] != nil) { + if([[item identifier] respondsToSelector:@selector(objectCount)]) { [[item identifier] removeObserver:cell forKeyPath:@"objectCount"]; } } - - if ([item identifier] != nil) { - if ([[item identifier] respondsToSelector:@selector(countColor)]) { + + if([item identifier] != nil) { + if([[item identifier] respondsToSelector:@selector(countColor)]) { [[item identifier] removeObserver:cell forKeyPath:@"countColor"]; } } - if ([item identifier] != nil) { - if ([[item identifier] respondsToSelector:@selector(largeImage)]) { + if([item identifier] != nil) { + if([[item identifier] respondsToSelector:@selector(largeImage)]) { [[item identifier] removeObserver:cell forKeyPath:@"largeImage"]; } } - - if ([item identifier] != nil) { - if ([[item identifier] respondsToSelector:@selector(isEdited)]) { + + if([item identifier] != nil) { + if([[item identifier] respondsToSelector:@selector(isEdited)]) { [[item identifier] removeObserver:cell forKeyPath:@"isEdited"]; } } - - // stop watching identifier - [item removeObserver:self forKeyPath:@"identifier"]; - - // remove indicator - if ([[self subviews] containsObject:[cell indicator]]) { - [[cell indicator] removeFromSuperview]; - } - // remove tracking - [[NSNotificationCenter defaultCenter] removeObserver:cell]; - - if ([cell closeButtonTrackingTag] != 0) { - [self removeTrackingRect:[cell closeButtonTrackingTag]]; + + // stop watching identifier + [item removeObserver:self forKeyPath:@"identifier"]; + + // remove indicator + if([[self subviews] containsObject:[cell indicator]]) { + [[cell indicator] removeFromSuperview]; + } + // remove tracking + [[NSNotificationCenter defaultCenter] removeObserver:cell]; + + if([cell closeButtonTrackingTag] != 0) { + [self removeTrackingRect:[cell closeButtonTrackingTag]]; [cell setCloseButtonTrackingTag:0]; - } - if ([cell cellTrackingTag] != 0) { - [self removeTrackingRect:[cell cellTrackingTag]]; + } + if([cell cellTrackingTag] != 0) { + [self removeTrackingRect:[cell cellTrackingTag]]; [cell setCellTrackingTag:0]; - } + } - // pull from collection - [_cells removeObject:cell]; + // pull from collection + [_cells removeObject:cell]; - [self update]; + [self update]; } -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context -{ - // did the tab's identifier change? - if ([keyPath isEqualToString:@"identifier"]) { - NSEnumerator *e = [_cells objectEnumerator]; - PSMTabBarCell *cell; - while ( (cell = [e nextObject]) ) { - if ([cell representedObject] == object) { - [self _bindPropertiesForCell:cell andTabViewItem:object]; +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + // did the tab's identifier change? + if([keyPath isEqualToString:@"identifier"]) { + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while((cell = [e nextObject])) { + if([cell representedObject] == object) { + [self _bindPropertiesForCell:cell andTabViewItem:object]; } - } - } + } + } } #pragma mark - #pragma mark Hide/Show -- (void)hideTabBar:(BOOL)hide animate:(BOOL)animate -{ - if (!_awakenedFromNib || (_isHidden && hide) || (!_isHidden && !hide) || (_currentStep != kPSMIsNotBeingResized)) { - return; +- (void)hideTabBar:(BOOL)hide animate:(BOOL)animate { + if(!_awakenedFromNib || (_isHidden && hide) || (!_isHidden && !hide) || (_currentStep != kPSMIsNotBeingResized)) { + return; } - - [[self subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; - _isHidden = hide; - _currentStep = 0; - if (!animate) { - _currentStep = (NSInteger)kPSMHideAnimationSteps; + [[self subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; + + _isHidden = hide; + _currentStep = 0; + if(!animate) { + _currentStep = (NSInteger)kPSMHideAnimationSteps; } - if (hide) { + if(hide) { [_overflowPopUpButton removeFromSuperview]; [_addTabButton removeFromSuperview]; - } else if (!animate) { + } else if(!animate) { [self addSubview:_overflowPopUpButton]; [self addSubview:_addTabButton]; } - CGFloat partnerOriginalSize, partnerOriginalOrigin, myOriginalSize, myOriginalOrigin, partnerTargetSize, partnerTargetOrigin, myTargetSize, myTargetOrigin; - - // target values for partner - if ([self orientation] == PSMTabBarHorizontalOrientation) { + CGFloat partnerOriginalSize, partnerOriginalOrigin, myOriginalSize, myOriginalOrigin, partnerTargetSize, partnerTargetOrigin, myTargetSize, myTargetOrigin; + + // target values for partner + if([self orientation] == PSMTabBarHorizontalOrientation) { // current (original) values myOriginalSize = [self frame].size.height; myOriginalOrigin = [self frame].origin.y; - if (partnerView) { + if(partnerView) { partnerOriginalSize = [partnerView frame].size.height; partnerOriginalOrigin = [partnerView frame].origin.y; } else { partnerOriginalSize = [[self window] frame].size.height; partnerOriginalOrigin = [[self window] frame].origin.y; } - - if (partnerView) { + + if(partnerView) { // above or below me? - if ((myOriginalOrigin - 22) > partnerOriginalOrigin) { + if((myOriginalOrigin - 22) > partnerOriginalOrigin) { // partner is below me - if (_isHidden) { + if(_isHidden) { // I'm shrinking myTargetOrigin = myOriginalOrigin + 21; myTargetSize = myOriginalSize - 21; @@ -756,7 +714,7 @@ } } else { // partner is above me - if (_isHidden) { + if(_isHidden) { // I'm shrinking myTargetOrigin = myOriginalOrigin; myTargetSize = myOriginalSize - 21; @@ -772,7 +730,7 @@ } } else { // for window movement - if (_isHidden) { + if(_isHidden) { // I'm shrinking myTargetOrigin = myOriginalOrigin; myTargetSize = myOriginalSize - 21; @@ -786,23 +744,23 @@ partnerTargetSize = partnerOriginalSize + 21; } } - } else /* vertical */ { - // current (original) values + } else { /* vertical */ + // current (original) values myOriginalSize = [self frame].size.width; myOriginalOrigin = [self frame].origin.x; - if (partnerView) { + if(partnerView) { partnerOriginalSize = [partnerView frame].size.width; partnerOriginalOrigin = [partnerView frame].origin.x; } else { partnerOriginalSize = [[self window] frame].size.width; partnerOriginalOrigin = [[self window] frame].origin.x; } - - if (partnerView) { + + if(partnerView) { //to the left or right? - if (myOriginalOrigin < partnerOriginalOrigin + partnerOriginalSize) { + if(myOriginalOrigin < partnerOriginalOrigin + partnerOriginalSize) { // partner is to the left - if (_isHidden) { + if(_isHidden) { // I'm shrinking myTargetOrigin = myOriginalOrigin; myTargetSize = 1; @@ -818,7 +776,7 @@ } } else { // partner is to the right - if (_isHidden) { + if(_isHidden) { // I'm shrinking myTargetOrigin = myOriginalOrigin + myOriginalSize; myTargetSize = 1; @@ -835,7 +793,7 @@ } } else { // for window movement - if (_isHidden) { + if(_isHidden) { // I'm shrinking myTargetOrigin = myOriginalOrigin; myTargetSize = 1; @@ -850,211 +808,201 @@ partnerTargetSize = partnerOriginalSize + _tabBarWidth - 1; } } - - if (!_isHidden && [[self delegate] respondsToSelector:@selector(desiredWidthForVerticalTabBar:)]) + + if(!_isHidden && [[self delegate] respondsToSelector:@selector(desiredWidthForVerticalTabBar:)]) { myTargetSize = [[self delegate] desiredWidthForVerticalTabBar:self]; + } } - NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithDouble:myOriginalOrigin], @"myOriginalOrigin", [NSNumber numberWithDouble:partnerOriginalOrigin], @"partnerOriginalOrigin", [NSNumber numberWithDouble:myOriginalSize], @"myOriginalSize", [NSNumber numberWithDouble:partnerOriginalSize], @"partnerOriginalSize", [NSNumber numberWithDouble:myTargetOrigin], @"myTargetOrigin", [NSNumber numberWithDouble:partnerTargetOrigin], @"partnerTargetOrigin", [NSNumber numberWithDouble:myTargetSize], @"myTargetSize", [NSNumber numberWithDouble:partnerTargetSize], @"partnerTargetSize", nil]; - if (_showHideAnimationTimer) { + NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithDouble:myOriginalOrigin], @"myOriginalOrigin", [NSNumber numberWithDouble:partnerOriginalOrigin], @"partnerOriginalOrigin", [NSNumber numberWithDouble:myOriginalSize], @"myOriginalSize", [NSNumber numberWithDouble:partnerOriginalSize], @"partnerOriginalSize", [NSNumber numberWithDouble:myTargetOrigin], @"myTargetOrigin", [NSNumber numberWithDouble:partnerTargetOrigin], @"partnerTargetOrigin", [NSNumber numberWithDouble:myTargetSize], @"myTargetSize", [NSNumber numberWithDouble:partnerTargetSize], @"partnerTargetSize", nil]; + if(_showHideAnimationTimer) { [_showHideAnimationTimer invalidate]; [_showHideAnimationTimer release]; } - _showHideAnimationTimer = [[NSTimer scheduledTimerWithTimeInterval:(1.0 / 30.0) target:self selector:@selector(animateShowHide:) userInfo:userInfo repeats:YES] retain]; + _showHideAnimationTimer = [[NSTimer scheduledTimerWithTimeInterval:(1.0 / 30.0) target:self selector:@selector(animateShowHide:) userInfo:userInfo repeats:YES] retain]; } -- (void)animateShowHide:(NSTimer *)timer -{ - // moves the frame of the tab bar and window (or partner view) linearly to hide or show the tab bar - NSRect myFrame = [self frame]; +- (void)animateShowHide:(NSTimer *)timer { + // moves the frame of the tab bar and window (or partner view) linearly to hide or show the tab bar + NSRect myFrame = [self frame]; NSDictionary *userInfo = [timer userInfo]; - CGFloat myCurrentOrigin = ([[userInfo objectForKey:@"myOriginalOrigin"] doubleValue] + (([[userInfo objectForKey:@"myTargetOrigin"] doubleValue] - [[userInfo objectForKey:@"myOriginalOrigin"] doubleValue]) * (_currentStep/kPSMHideAnimationSteps))); - CGFloat myCurrentSize = ([[userInfo objectForKey:@"myOriginalSize"] doubleValue] + (([[userInfo objectForKey:@"myTargetSize"] doubleValue] - [[userInfo objectForKey:@"myOriginalSize"] doubleValue]) * (_currentStep/kPSMHideAnimationSteps))); - CGFloat partnerCurrentOrigin = ([[userInfo objectForKey:@"partnerOriginalOrigin"] doubleValue] + (([[userInfo objectForKey:@"partnerTargetOrigin"] doubleValue] - [[userInfo objectForKey:@"partnerOriginalOrigin"] doubleValue]) * (_currentStep/kPSMHideAnimationSteps))); - CGFloat partnerCurrentSize = ([[userInfo objectForKey:@"partnerOriginalSize"] doubleValue] + (([[userInfo objectForKey:@"partnerTargetSize"] doubleValue] - [[userInfo objectForKey:@"partnerOriginalSize"] doubleValue]) * (_currentStep/kPSMHideAnimationSteps))); - + CGFloat myCurrentOrigin = ([[userInfo objectForKey:@"myOriginalOrigin"] doubleValue] + (([[userInfo objectForKey:@"myTargetOrigin"] doubleValue] - [[userInfo objectForKey:@"myOriginalOrigin"] doubleValue]) * (_currentStep / kPSMHideAnimationSteps))); + CGFloat myCurrentSize = ([[userInfo objectForKey:@"myOriginalSize"] doubleValue] + (([[userInfo objectForKey:@"myTargetSize"] doubleValue] - [[userInfo objectForKey:@"myOriginalSize"] doubleValue]) * (_currentStep / kPSMHideAnimationSteps))); + CGFloat partnerCurrentOrigin = ([[userInfo objectForKey:@"partnerOriginalOrigin"] doubleValue] + (([[userInfo objectForKey:@"partnerTargetOrigin"] doubleValue] - [[userInfo objectForKey:@"partnerOriginalOrigin"] doubleValue]) * (_currentStep / kPSMHideAnimationSteps))); + CGFloat partnerCurrentSize = ([[userInfo objectForKey:@"partnerOriginalSize"] doubleValue] + (([[userInfo objectForKey:@"partnerTargetSize"] doubleValue] - [[userInfo objectForKey:@"partnerOriginalSize"] doubleValue]) * (_currentStep / kPSMHideAnimationSteps))); + NSRect myNewFrame; - if ([self orientation] == PSMTabBarHorizontalOrientation) { + if([self orientation] == PSMTabBarHorizontalOrientation) { myNewFrame = NSMakeRect(myFrame.origin.x, myCurrentOrigin, myFrame.size.width, myCurrentSize); } else { myNewFrame = NSMakeRect(myCurrentOrigin, myFrame.origin.y, myCurrentSize, myFrame.size.height); } - - if (partnerView) { - // resize self and view + + if(partnerView) { + // resize self and view NSRect resizeRect; - if ([self orientation] == PSMTabBarHorizontalOrientation) { + if([self orientation] == PSMTabBarHorizontalOrientation) { resizeRect = NSMakeRect([partnerView frame].origin.x, partnerCurrentOrigin, [partnerView frame].size.width, partnerCurrentSize); } else { resizeRect = NSMakeRect(partnerCurrentOrigin, [partnerView frame].origin.y, partnerCurrentSize, [partnerView frame].size.height); } [partnerView setFrame:resizeRect]; - [partnerView setNeedsDisplay:YES]; - [self setFrame:myNewFrame]; - } else { - // resize self and window + [partnerView setNeedsDisplay:YES]; + [self setFrame:myNewFrame]; + } else { + // resize self and window NSRect resizeRect; - if ([self orientation] == PSMTabBarHorizontalOrientation) { + if([self orientation] == PSMTabBarHorizontalOrientation) { resizeRect = NSMakeRect([[self window] frame].origin.x, partnerCurrentOrigin, [[self window] frame].size.width, partnerCurrentSize); } else { resizeRect = NSMakeRect(partnerCurrentOrigin, [[self window] frame].origin.y, partnerCurrentSize, [[self window] frame].size.height); } - [[self window] setFrame:resizeRect display:YES]; - [self setFrame:myNewFrame]; - } - - // next - _currentStep++; - if (_currentStep == kPSMHideAnimationSteps + 1) { + [[self window] setFrame:resizeRect display:YES]; + [self setFrame:myNewFrame]; + } + + // next + _currentStep++; + if(_currentStep == kPSMHideAnimationSteps + 1) { _currentStep = kPSMIsNotBeingResized; - [self viewDidEndLiveResize]; - [self update:NO]; - + [self viewDidEndLiveResize]; + [self update:NO]; + //send the delegate messages - if (_isHidden) { - if ([[self delegate] respondsToSelector:@selector(tabView:tabBarDidHide:)]) { + if(_isHidden) { + if([[self delegate] respondsToSelector:@selector(tabView:tabBarDidHide:)]) { [[self delegate] tabView:[self tabView] tabBarDidHide:self]; } } else { [self addSubview:_overflowPopUpButton]; [self addSubview:_addTabButton]; - if ([[self delegate] respondsToSelector:@selector(tabView:tabBarDidUnhide:)]) { + if([[self delegate] respondsToSelector:@selector(tabView:tabBarDidUnhide:)]) { [[self delegate] tabView:[self tabView] tabBarDidUnhide:self]; } } - + [_showHideAnimationTimer invalidate]; [_showHideAnimationTimer release]; _showHideAnimationTimer = nil; - } - [[self window] display]; + } + [[self window] display]; } -- (BOOL)isTabBarHidden -{ +- (BOOL)isTabBarHidden { return _isHidden; } -- (BOOL)isAnimating -{ - return _animationTimer != nil; +- (BOOL)isAnimating { + return _animationTimer != nil; } -- (id)partnerView -{ - return partnerView; +- (id)partnerView { + return partnerView; } -- (void)setPartnerView:(id)view -{ - [partnerView release]; - [view retain]; - partnerView = view; +- (void)setPartnerView:(id)view { + [partnerView release]; + [view retain]; + partnerView = view; } #pragma mark - #pragma mark Drawing -- (BOOL)isFlipped -{ - return YES; +- (BOOL)isFlipped { + return YES; } -- (void)drawRect:(NSRect)rect -{ - [style drawTabBar:self inRect:rect]; +- (void)drawRect:(NSRect)rect { + [style drawTabBar:self inRect:rect]; } -- (void)update -{ +- (void)update { [self update:_automaticallyAnimates]; } -- (void)update:(BOOL)animate -{ - // make sure all of our tabs are accounted for before updating - if ([[self tabView] numberOfTabViewItems] != [_cells count]) { - return; - } - - // hide/show? (these return if already in desired state) - if ( (_hideForSingleTab) && ([_cells count] <= 1) ) { - [self hideTabBar:YES animate:YES]; - return; - } else { - [self hideTabBar:NO animate:YES]; - } - - [self removeAllToolTips]; - [_controller layoutCells]; //eventually we should only have to call this when we know something has changed - - PSMTabBarCell *currentCell; - - NSMenu *overflowMenu = [_controller overflowMenu]; - [_overflowPopUpButton setHidden:(overflowMenu == nil)]; - [_overflowPopUpButton setMenu:overflowMenu]; - - if (_animationTimer) { +- (void)update:(BOOL)animate { + // make sure all of our tabs are accounted for before updating + if([[self tabView] numberOfTabViewItems] != [_cells count]) { + return; + } + + // hide/show? (these return if already in desired state) + if((_hideForSingleTab) && ([_cells count] <= 1)) { + [self hideTabBar:YES animate:YES]; + return; + } else { + [self hideTabBar:NO animate:YES]; + } + + [self removeAllToolTips]; + [_controller layoutCells]; //eventually we should only have to call this when we know something has changed + + PSMTabBarCell *currentCell; + + NSMenu *overflowMenu = [_controller overflowMenu]; + [_overflowPopUpButton setHidden:(overflowMenu == nil)]; + [_overflowPopUpButton setMenu:overflowMenu]; + + if(_animationTimer) { [_animationTimer invalidate]; [_animationTimer release]; _animationTimer = nil; - } - - if (animate) { - NSMutableArray *targetFrames = [NSMutableArray arrayWithCapacity:[_cells count]]; - - for (NSUInteger i = 0; i < [_cells count]; i++) { - currentCell = [_cells objectAtIndex:i]; - - //we're going from NSRect -> NSValue -> NSRect -> NSValue here - oh well - [targetFrames addObject:[NSValue valueWithRect:[_controller cellFrameAtIndex:i]]]; - } - - [_addTabButton setHidden:!_showAddTabButton]; - - NSAnimation *animation = [[NSAnimation alloc] initWithDuration:0.50 animationCurve:NSAnimationEaseInOut]; - [animation setAnimationBlockingMode:NSAnimationNonblocking]; - [animation startAnimation]; - _animationTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 - target:self - selector:@selector(_animateCells:) - userInfo:[NSArray arrayWithObjects:targetFrames, animation, nil] - repeats:YES] retain]; + } + + if(animate) { + NSMutableArray *targetFrames = [NSMutableArray arrayWithCapacity:[_cells count]]; + + for(NSInteger i = 0; i < [_cells count]; i++) { + currentCell = [_cells objectAtIndex:i]; + + //we're going from NSRect -> NSValue -> NSRect -> NSValue here - oh well + [targetFrames addObject:[NSValue valueWithRect:[_controller cellFrameAtIndex:i]]]; + } + + [_addTabButton setHidden:!_showAddTabButton]; + + NSAnimation *animation = [[NSAnimation alloc] initWithDuration:0.50 animationCurve:NSAnimationEaseInOut]; + [animation setAnimationBlockingMode:NSAnimationNonblocking]; + [animation startAnimation]; + _animationTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 + target:self + selector:@selector(_animateCells:) + userInfo:[NSArray arrayWithObjects:targetFrames, animation, nil] + repeats:YES] retain]; [animation release]; [[NSRunLoop currentRunLoop] addTimer:_animationTimer forMode:NSEventTrackingRunLoopMode]; [self _animateCells:_animationTimer]; + } else { + for(NSInteger i = 0; i < [_cells count]; i++) { + currentCell = [_cells objectAtIndex:i]; + [currentCell setFrame:[_controller cellFrameAtIndex:i]]; - } else { - for (NSUInteger i = 0; i < [_cells count]; i++) { - currentCell = [_cells objectAtIndex:i]; - [currentCell setFrame:[_controller cellFrameAtIndex:i]]; - - if (![currentCell isInOverflowMenu]) { - [self _setupTrackingRectsForCell:currentCell]; - } - } - - [_addTabButton setFrame:[_controller addButtonRect]]; - [_addTabButton setHidden:!_showAddTabButton]; - [self setNeedsDisplay:YES]; - } -} - -- (void)_animateCells:(NSTimer *)timer -{ - NSAnimation *animation = [[timer userInfo] objectAtIndex:1]; + if(![currentCell isInOverflowMenu]) { + [self _setupTrackingRectsForCell:currentCell]; + } + } + + [_addTabButton setFrame:[_controller addButtonRect]]; + [_addTabButton setHidden:!_showAddTabButton]; + [self setNeedsDisplay:YES]; + } +} + +- (void)_animateCells:(NSTimer *)timer { + NSAnimation *animation = [[timer userInfo] objectAtIndex:1]; NSArray *targetFrames = [[timer userInfo] objectAtIndex:0]; - PSMTabBarCell *currentCell; + PSMTabBarCell *currentCell; NSInteger cellCount = [_cells count]; - - if ((cellCount > 0) && [animation isAnimating]) { + + if((cellCount > 0) && [animation isAnimating]) { //compare our target position with the current position and move towards the target - for (NSUInteger i = 0; i < [targetFrames count] && i < cellCount; i++) { + for(NSInteger i = 0; i < [targetFrames count] && i < cellCount; i++) { currentCell = [_cells objectAtIndex:i]; NSRect cellFrame = [currentCell frame], targetFrame = [[targetFrames objectAtIndex:i] rectValue]; CGFloat sizeChange; CGFloat originChange; - - if ([self orientation] == PSMTabBarHorizontalOrientation) { + + if([self orientation] == PSMTabBarHorizontalOrientation) { sizeChange = (targetFrame.size.width - cellFrame.size.width) * [animation currentProgress]; originChange = (targetFrame.origin.x - cellFrame.origin.x) * [animation currentProgress]; cellFrame.size.width += sizeChange; @@ -1065,108 +1013,106 @@ cellFrame.size.height += sizeChange; cellFrame.origin.y += originChange; } - + [currentCell setFrame:cellFrame]; - + //highlight the cell if the mouse is over it NSPoint mousePoint = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:nil]; NSRect closeRect = [currentCell closeButtonRectForFrame:cellFrame]; [currentCell setHighlighted:NSMouseInRect(mousePoint, cellFrame, [self isFlipped])]; [currentCell setCloseButtonOver:NSMouseInRect(mousePoint, closeRect, [self isFlipped])]; } - - if (_showAddTabButton) { - //animate the add tab button - NSRect target = [_controller addButtonRect], frame = [_addTabButton frame]; - frame.origin.x += (target.origin.x - frame.origin.x) * [animation currentProgress]; - [_addTabButton setFrame:frame]; - } - } else { + + if(_showAddTabButton) { + //animate the add tab button + NSRect target = [_controller addButtonRect], frame = [_addTabButton frame]; + frame.origin.x += (target.origin.x - frame.origin.x) * [animation currentProgress]; + [_addTabButton setFrame:frame]; + } + } else { //put all the cells where they should be in their final position - if (cellCount > 0) { - for (NSUInteger i = 0; i < [targetFrames count] && i < cellCount; i++) { + if(cellCount > 0) { + for(NSInteger i = 0; i < [targetFrames count] && i < cellCount; i++) { PSMTabBarCell *currentCell = [_cells objectAtIndex:i]; NSRect cellFrame = [currentCell frame], targetFrame = [[targetFrames objectAtIndex:i] rectValue]; - - if ([self orientation] == PSMTabBarHorizontalOrientation) { - cellFrame.size.width = targetFrame.size.width; - cellFrame.origin.x = targetFrame.origin.x; - } else { - cellFrame.size.height = targetFrame.size.height; - cellFrame.origin.y = targetFrame.origin.y; - } - + + if([self orientation] == PSMTabBarHorizontalOrientation) { + cellFrame.size.width = targetFrame.size.width; + cellFrame.origin.x = targetFrame.origin.x; + } else { + cellFrame.size.height = targetFrame.size.height; + cellFrame.origin.y = targetFrame.origin.y; + } + [currentCell setFrame:cellFrame]; - - //highlight the cell if the mouse is over it - NSPoint mousePoint = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:nil]; - NSRect closeRect = [currentCell closeButtonRectForFrame:cellFrame]; - [currentCell setHighlighted:NSMouseInRect(mousePoint, cellFrame, [self isFlipped])]; - [currentCell setCloseButtonOver:NSMouseInRect(mousePoint, closeRect, [self isFlipped])]; + + //highlight the cell if the mouse is over it + NSPoint mousePoint = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:nil]; + NSRect closeRect = [currentCell closeButtonRectForFrame:cellFrame]; + [currentCell setHighlighted:NSMouseInRect(mousePoint, cellFrame, [self isFlipped])]; + [currentCell setCloseButtonOver:NSMouseInRect(mousePoint, closeRect, [self isFlipped])]; } } - + //set the frame for the add tab button - if (_showAddTabButton) { - NSRect frame = [_addTabButton frame]; - frame.origin.x = [_controller addButtonRect].origin.x; - [_addTabButton setFrame:frame]; - } + if(_showAddTabButton) { + NSRect frame = [_addTabButton frame]; + frame.origin.x = [_controller addButtonRect].origin.x; + [_addTabButton setFrame:frame]; + } [_animationTimer invalidate]; [_animationTimer release]; _animationTimer = nil; - - for (NSInteger i = 0; i < cellCount; i++) { - currentCell = [_cells objectAtIndex:i]; - - //we've hit the cells that are in overflow, stop setting up tracking rects - if ([currentCell isInOverflowMenu]) { - break; - } - - [self _setupTrackingRectsForCell:currentCell]; - } - } - - [self setNeedsDisplay:YES]; -} - -- (void)_setupTrackingRectsForCell:(PSMTabBarCell *)cell -{ - NSInteger tag, index = [_cells indexOfObject:cell]; - NSRect cellTrackingRect = [_controller cellTrackingRectAtIndex:index]; - NSPoint mousePoint = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:nil]; - BOOL mouseInCell = NSMouseInRect(mousePoint, cellTrackingRect, [self isFlipped]); - - //set the cell tracking rect - [self removeTrackingRect:[cell cellTrackingTag]]; - tag = [self addTrackingRect:cellTrackingRect owner:cell userData:nil assumeInside:mouseInCell]; - [cell setCellTrackingTag:tag]; - [cell setHighlighted:mouseInCell]; - - if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - NSRect closeRect = [_controller closeButtonTrackingRectAtIndex:index]; - BOOL mouseInCloseRect = NSMouseInRect(mousePoint, closeRect, [self isFlipped]); - - //set the close button tracking rect - [self removeTrackingRect:[cell closeButtonTrackingTag]]; - tag = [self addTrackingRect:closeRect owner:cell userData:nil assumeInside:mouseInCloseRect]; - [cell setCloseButtonTrackingTag:tag]; - - [cell setCloseButtonOver:mouseInCloseRect]; - } - - //set the tooltip tracking rect - [self addToolTipRect:[cell frame] owner:self userData:nil]; -} - -- (void)_positionOverflowMenu -{ - NSRect cellRect, frame = [self frame]; - cellRect.size.height = [style tabCellHeight]; - cellRect.size.width = [style rightMarginForTabBarControl]; - - if ([self orientation] == PSMTabBarHorizontalOrientation) { + + for(NSInteger i = 0; i < cellCount; i++) { + currentCell = [_cells objectAtIndex:i]; + + //we've hit the cells that are in overflow, stop setting up tracking rects + if([currentCell isInOverflowMenu]) { + break; + } + + [self _setupTrackingRectsForCell:currentCell]; + } + } + + [self setNeedsDisplay:YES]; +} + +- (void)_setupTrackingRectsForCell:(PSMTabBarCell *)cell { + NSInteger tag, index = [_cells indexOfObject:cell]; + NSRect cellTrackingRect = [_controller cellTrackingRectAtIndex:index]; + NSPoint mousePoint = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:nil]; + BOOL mouseInCell = NSMouseInRect(mousePoint, cellTrackingRect, [self isFlipped]); + + //set the cell tracking rect + [self removeTrackingRect:[cell cellTrackingTag]]; + tag = [self addTrackingRect:cellTrackingRect owner:cell userData:nil assumeInside:mouseInCell]; + [cell setCellTrackingTag:tag]; + [cell setHighlighted:mouseInCell]; + + if([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { + NSRect closeRect = [_controller closeButtonTrackingRectAtIndex:index]; + BOOL mouseInCloseRect = NSMouseInRect(mousePoint, closeRect, [self isFlipped]); + + //set the close button tracking rect + [self removeTrackingRect:[cell closeButtonTrackingTag]]; + tag = [self addTrackingRect:closeRect owner:cell userData:nil assumeInside:mouseInCloseRect]; + [cell setCloseButtonTrackingTag:tag]; + + [cell setCloseButtonOver:mouseInCloseRect]; + } + + //set the tooltip tracking rect + [self addToolTipRect:[cell frame] owner:self userData:nil]; +} + +- (void)_positionOverflowMenu { + NSRect cellRect, frame = [self frame]; + cellRect.size.height = [style tabCellHeight]; + cellRect.size.width = [style rightMarginForTabBarControl]; + + if([self orientation] == PSMTabBarHorizontalOrientation) { cellRect.origin.y = 0; cellRect.origin.x = frame.size.width - [style rightMarginForTabBarControl] + (_resizeAreaCompensation ? -(_resizeAreaCompensation - 1) : 1); [_overflowPopUpButton setAutoresizingMask:NSViewNotSizable | NSViewMinXMargin]; @@ -1176,28 +1122,27 @@ cellRect.size.width = frame.size.width; [_overflowPopUpButton setAutoresizingMask:NSViewNotSizable | NSViewMinXMargin | NSViewMinYMargin]; } - - [_overflowPopUpButton setFrame:cellRect]; + + [_overflowPopUpButton setFrame:cellRect]; } -- (void)_checkWindowFrame -{ +- (void)_checkWindowFrame { //figure out if the new frame puts the control in the way of the resize widget NSWindow *window = [self window]; - - if (window) { + + if(window) { NSRect resizeWidgetFrame = [[window contentView] frame]; resizeWidgetFrame.origin.x += resizeWidgetFrame.size.width - 22; resizeWidgetFrame.size.width = 22; resizeWidgetFrame.size.height = 22; - - if ([window showsResizeIndicator] && NSIntersectsRect([self frame], resizeWidgetFrame)) { + + if([window showsResizeIndicator] && NSIntersectsRect([self frame], resizeWidgetFrame)) { //the resize widgets are larger on metal windows _resizeAreaCompensation = [window styleMask] & NSTexturedBackgroundWindowMask ? 20 : 8; } else { _resizeAreaCompensation = 0; } - + [self _positionOverflowMenu]; } } @@ -1205,112 +1150,107 @@ #pragma mark - #pragma mark Mouse Tracking -- (BOOL)mouseDownCanMoveWindow -{ - return NO; +- (BOOL)mouseDownCanMoveWindow { + return NO; } -- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent -{ - return YES; +- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { + return YES; } -- (void)mouseDown:(NSEvent *)theEvent -{ +- (void)mouseDown:(NSEvent *)theEvent { _didDrag = NO; - - // keep for dragging - [self setLastMouseDownEvent:theEvent]; - // what cell? - NSPoint mousePt = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + + // keep for dragging + [self setLastMouseDownEvent:theEvent]; + // what cell? + NSPoint mousePt = [self convertPoint:[theEvent locationInWindow] fromView:nil]; NSRect frame = [self frame]; - - if ([self orientation] == PSMTabBarVerticalOrientation && [self allowsResizing] && partnerView && (mousePt.x > frame.size.width - 3)) { + + if([self orientation] == PSMTabBarVerticalOrientation && [self allowsResizing] && partnerView && (mousePt.x > frame.size.width - 3)) { _resizing = YES; } - - NSRect cellFrame; - PSMTabBarCell *cell = [self cellForPoint:mousePt cellFrame:&cellFrame]; - if (cell) { + + NSRect cellFrame; + PSMTabBarCell *cell = [self cellForPoint:mousePt cellFrame:&cellFrame]; + if(cell) { BOOL overClose = NSMouseInRect(mousePt, [cell closeButtonRectForFrame:cellFrame], [self isFlipped]); - if (overClose && - ![self disableTabClose] && - ![cell isCloseButtonSuppressed] && - ([self allowsBackgroundTabClosing] || [[cell representedObject] isEqualTo:[tabView selectedTabViewItem]] || [theEvent modifierFlags] & NSCommandKeyMask)) { - [cell setCloseButtonOver:NO]; - [cell setCloseButtonPressed:YES]; + if(overClose && + ![self disableTabClose] && + ![cell isCloseButtonSuppressed] && + ([self allowsBackgroundTabClosing] || [[cell representedObject] isEqualTo:[tabView selectedTabViewItem]] || [theEvent modifierFlags] & NSCommandKeyMask)) { + [cell setCloseButtonOver:NO]; + [cell setCloseButtonPressed:YES]; _closeClicked = YES; - } else { - [cell setCloseButtonPressed:NO]; - if (_selectsTabsOnMouseDown) { + } else { + [cell setCloseButtonPressed:NO]; + if(_selectsTabsOnMouseDown) { [self performSelector:@selector(tabClick:) withObject:cell]; } - } - [self setNeedsDisplay:YES]; - } + } + [self setNeedsDisplay:YES]; + } } -- (void)mouseDragged:(NSEvent *)theEvent -{ - if ([self lastMouseDownEvent] == nil) { - return; - } - +- (void)mouseDragged:(NSEvent *)theEvent { + if([self lastMouseDownEvent] == nil) { + return; + } + NSPoint currentPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - - if (_resizing) { + + if(_resizing) { NSRect frame = [self frame]; CGFloat resizeAmount = [theEvent deltaX]; - if ((currentPoint.x > frame.size.width && resizeAmount > 0) || (currentPoint.x < frame.size.width && resizeAmount < 0)) { + if((currentPoint.x > frame.size.width && resizeAmount > 0) || (currentPoint.x < frame.size.width && resizeAmount < 0)) { [[NSCursor resizeLeftRightCursor] push]; - + NSRect partnerFrame = [partnerView frame]; - + //do some bounds checking - if ((frame.size.width + resizeAmount > [self cellMinWidth]) && (frame.size.width + resizeAmount < [self cellMaxWidth])) { + if((frame.size.width + resizeAmount > [self cellMinWidth]) && (frame.size.width + resizeAmount < [self cellMaxWidth])) { frame.size.width += resizeAmount; partnerFrame.size.width -= resizeAmount; partnerFrame.origin.x += resizeAmount; - + [self setFrame:frame]; [partnerView setFrame:partnerFrame]; [[self superview] setNeedsDisplay:YES]; - } + } } return; } - - NSRect cellFrame; - NSPoint trackingStartPoint = [self convertPoint:[[self lastMouseDownEvent] locationInWindow] fromView:nil]; - PSMTabBarCell *cell = [self cellForPoint:trackingStartPoint cellFrame:&cellFrame]; - if (cell) { + + NSRect cellFrame; + NSPoint trackingStartPoint = [self convertPoint:[[self lastMouseDownEvent] locationInWindow] fromView:nil]; + PSMTabBarCell *cell = [self cellForPoint:trackingStartPoint cellFrame:&cellFrame]; + if(cell) { //check to see if the close button was the target in the clicked cell //highlight/unhighlight the close button as necessary NSRect iconRect = [cell closeButtonRectForFrame:cellFrame]; - - if (_closeClicked && NSMouseInRect(trackingStartPoint, iconRect, [self isFlipped]) && - ([self allowsBackgroundTabClosing] || [[cell representedObject] isEqualTo:[tabView selectedTabViewItem]])) { + + if(_closeClicked && NSMouseInRect(trackingStartPoint, iconRect, [self isFlipped]) && + ([self allowsBackgroundTabClosing] || [[cell representedObject] isEqualTo:[tabView selectedTabViewItem]])) { [cell setCloseButtonPressed:NSMouseInRect(currentPoint, iconRect, [self isFlipped])]; [self setNeedsDisplay:YES]; return; } - + CGFloat dx = fabs(currentPoint.x - trackingStartPoint.x); CGFloat dy = fabs(currentPoint.y - trackingStartPoint.y); CGFloat distance = sqrt(dx * dx + dy * dy); - - if (distance >= 10 && !_didDrag && ![[PSMTabDragAssistant sharedDragAssistant] isDragging] && - [self delegate] && [[self delegate] respondsToSelector:@selector(tabView:shouldDragTabViewItem:fromTabBar:)] && - [[self delegate] tabView:tabView shouldDragTabViewItem:[cell representedObject] fromTabBar:self]) { + + if(distance >= 10 && !_didDrag && ![[PSMTabDragAssistant sharedDragAssistant] isDragging] && + [self delegate] && [[self delegate] respondsToSelector:@selector(tabView:shouldDragTabViewItem:fromTabBar:)] && + [[self delegate] tabView:tabView shouldDragTabViewItem:[cell representedObject] fromTabBar:self]) { _didDrag = YES; [[PSMTabDragAssistant sharedDragAssistant] startDraggingCell:cell fromTabBar:self withMouseDownEvent:[self lastMouseDownEvent]]; } } } -- (void)mouseUp:(NSEvent *)theEvent -{ - if (_resizing) { +- (void)mouseUp:(NSEvent *)theEvent { + if(_resizing) { _resizing = NO; [[NSCursor arrowCursor] set]; } else { @@ -1319,53 +1259,50 @@ NSRect cellFrame, mouseDownCellFrame; PSMTabBarCell *cell = [self cellForPoint:mousePt cellFrame:&cellFrame]; PSMTabBarCell *mouseDownCell = [self cellForPoint:[self convertPoint:[[self lastMouseDownEvent] locationInWindow] fromView:nil] cellFrame:&mouseDownCellFrame]; - if (cell) { + if(cell) { NSPoint trackingStartPoint = [self convertPoint:[[self lastMouseDownEvent] locationInWindow] fromView:nil]; NSRect iconRect = [mouseDownCell closeButtonRectForFrame:mouseDownCellFrame]; - - if ((NSMouseInRect(mousePt, iconRect,[self isFlipped])) && ![self disableTabClose] && ![cell isCloseButtonSuppressed] && [mouseDownCell closeButtonPressed]) { - if (([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask) != 0) { + + if((NSMouseInRect(mousePt, iconRect, [self isFlipped])) && ![self disableTabClose] && ![cell isCloseButtonSuppressed] && [mouseDownCell closeButtonPressed]) { + if(([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask) != 0) { //If the user is holding Option, close all other tabs - NSEnumerator *enumerator = [[[[self cells] copy] autorelease] objectEnumerator]; - PSMTabBarCell *otherCell; - - while ((otherCell = [enumerator nextObject])) { - if (otherCell != cell) + NSEnumerator *enumerator = [[[[self cells] copy] autorelease] objectEnumerator]; + PSMTabBarCell *otherCell; + + while((otherCell = [enumerator nextObject])) { + if(otherCell != cell) { [self performSelector:@selector(closeTabClick:) withObject:otherCell]; + } } - + //Fix the close button for the clicked tab not to be pressed [cell setCloseButtonPressed:NO]; - } else { //Otherwise, close this tab [self performSelector:@selector(closeTabClick:) withObject:cell]; } - - } else if (NSMouseInRect(mousePt, mouseDownCellFrame, [self isFlipped]) && - (!NSMouseInRect(trackingStartPoint, [cell closeButtonRectForFrame:cellFrame], [self isFlipped]) || ![self allowsBackgroundTabClosing] || [self disableTabClose])) { + } else if(NSMouseInRect(mousePt, mouseDownCellFrame, [self isFlipped]) && + (!NSMouseInRect(trackingStartPoint, [cell closeButtonRectForFrame:cellFrame], [self isFlipped]) || ![self allowsBackgroundTabClosing] || [self disableTabClose])) { [mouseDownCell setCloseButtonPressed:NO]; // If -[self selectsTabsOnMouseDown] is TRUE, we already performed tabClick: on mouseDown. - if (![self selectsTabsOnMouseDown]) { + if(![self selectsTabsOnMouseDown]) { [self performSelector:@selector(tabClick:) withObject:cell]; } - } else { [mouseDownCell setCloseButtonPressed:NO]; [self performSelector:@selector(tabNothing:) withObject:cell]; } } - + _closeClicked = NO; } } -- (NSMenu *)menuForEvent:(NSEvent *)event -{ +- (NSMenu *)menuForEvent:(NSEvent *)event { NSMenu *menu = nil; NSTabViewItem *item = [[self cellForPoint:[self convertPoint:[event locationInWindow] fromView:nil] cellFrame:nil] representedObject]; - - if (item && [[self delegate] respondsToSelector:@selector(tabView:menuForTabViewItem:)]) { + + if(item && [[self delegate] respondsToSelector:@selector(tabView:menuForTabViewItem:)]) { menu = [[self delegate] tabView:tabView menuForTabViewItem:item]; } return menu; @@ -1374,146 +1311,129 @@ #pragma mark - #pragma mark Drag and Drop -- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent -{ - return YES; +- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent { + return YES; } // NSDraggingSource -- (NSUInteger)draggingSourceOperationMaskForLocal:(BOOL)isLocal -{ - return (isLocal ? NSDragOperationMove : NSDragOperationNone); +- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { + return(isLocal ? NSDragOperationMove : NSDragOperationNone); } -- (BOOL)ignoreModifierKeysWhileDragging -{ - return YES; +- (BOOL)ignoreModifierKeysWhileDragging { + return YES; } -- (void)draggedImage:(NSImage *)anImage beganAt:(NSPoint)screenPoint -{ +- (void)draggedImage:(NSImage *)anImage beganAt:(NSPoint)screenPoint { [[PSMTabDragAssistant sharedDragAssistant] draggingBeganAt:screenPoint]; } -- (void)draggedImage:(NSImage *)image movedTo:(NSPoint)screenPoint -{ +- (void)draggedImage:(NSImage *)image movedTo:(NSPoint)screenPoint { [[PSMTabDragAssistant sharedDragAssistant] draggingMovedTo:screenPoint]; } // NSDraggingDestination -- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender -{ - if([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { - - if ([self delegate] && [[self delegate] respondsToSelector:@selector(tabView:shouldDropTabViewItem:inTabBar:)] && - ![[self delegate] tabView:[[sender draggingSource] tabView] shouldDropTabViewItem:[[[PSMTabDragAssistant sharedDragAssistant] draggedCell] representedObject] inTabBar:self]) { +- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender { + if([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { + if([self delegate] && [[self delegate] respondsToSelector:@selector(tabView:shouldDropTabViewItem:inTabBar:)] && + ![[self delegate] tabView:[[sender draggingSource] tabView] shouldDropTabViewItem:[[[PSMTabDragAssistant sharedDragAssistant] draggedCell] representedObject] inTabBar:self]) { return NSDragOperationNone; } - - [[PSMTabDragAssistant sharedDragAssistant] draggingEnteredTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]]; - return NSDragOperationMove; - } - - return NSDragOperationNone; + + [[PSMTabDragAssistant sharedDragAssistant] draggingEnteredTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]]; + return NSDragOperationMove; + } + + return NSDragOperationNone; } -- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender -{ +- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender { PSMTabBarCell *cell = [self cellForPoint:[self convertPoint:[sender draggingLocation] fromView:nil] cellFrame:nil]; - - if ([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { - - if ([self delegate] && [[self delegate] respondsToSelector:@selector(tabView:shouldDropTabViewItem:inTabBar:)] && - ![[self delegate] tabView:[[sender draggingSource] tabView] shouldDropTabViewItem:[[[PSMTabDragAssistant sharedDragAssistant] draggedCell] representedObject] inTabBar:self]) { + + if([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { + if([self delegate] && [[self delegate] respondsToSelector:@selector(tabView:shouldDropTabViewItem:inTabBar:)] && + ![[self delegate] tabView:[[sender draggingSource] tabView] shouldDropTabViewItem:[[[PSMTabDragAssistant sharedDragAssistant] draggedCell] representedObject] inTabBar:self]) { return NSDragOperationNone; } - - [[PSMTabDragAssistant sharedDragAssistant] draggingUpdatedInTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]]; - return NSDragOperationMove; - } else if (cell) { + + [[PSMTabDragAssistant sharedDragAssistant] draggingUpdatedInTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]]; + return NSDragOperationMove; + } else if(cell) { //something that was accepted by the delegate was dragged on //Test for the space bar (the skip-the-delay key). - enum { virtualKeycodeForSpace = 49 }; //Source: IM:Tx (Fig. C-2) - union { - KeyMap keymap; - char bits[16]; - } keymap; - GetKeys(keymap.keymap); - if ((GetCurrentEventKeyModifiers() == 0) && bit_test(keymap.bits, virtualKeycodeForSpace)) { - //The user pressed the space bar. This skips the delay; the user wants to pop the spring on this tab *now*. - - //For some reason, it crashes if I call -fire here. I don't know why. It doesn't crash if I simply set the fire date to now. - [_springTimer setFireDate:[NSDate date]]; - } else { - //Wind the spring for a spring-loaded drop. - //The delay time comes from Finder's defaults, which specifies it in milliseconds. - //If the delegate can't handle our spring-loaded drop, we'll abort it when the timer fires. See fireSpring:. This is simpler than constantly (checking for spring-loaded awareness and tearing down/rebuilding the timer) at every delegate change. - - //If the user has dragged to a different tab, reset the timer. - if (_tabViewItemWithSpring != [cell representedObject]) { - [_springTimer invalidate]; - [_springTimer release]; _springTimer = nil; - _tabViewItemWithSpring = [cell representedObject]; - } - if (!_springTimer) { - //Finder's default delay time, as of Tiger, is 668 ms. If the user has never changed it, there's no setting in its defaults, so we default to that amount. - NSNumber *delayNumber = [(NSNumber *)CFPreferencesCopyAppValue((CFStringRef)@"SpringingDelayMilliseconds", (CFStringRef)@"com.apple.finder") autorelease]; - NSTimeInterval delaySeconds = delayNumber ? [delayNumber doubleValue] / 1000.0 : 0.668; - _springTimer = [[NSTimer scheduledTimerWithTimeInterval:delaySeconds - target:self - selector:@selector(fireSpring:) - userInfo:sender - repeats:NO] retain]; - } + /*enum { virtualKeycodeForSpace = 49 }; //Source: IM:Tx (Fig. C-2) + union { + KeyMap keymap; + char bits[16]; + } keymap; + GetKeys(keymap.keymap); + if ((GetCurrentEventKeyModifiers() == 0) && bit_test(keymap.bits, virtualKeycodeForSpace)) { + //The user pressed the space bar. This skips the delay; the user wants to pop the spring on this tab *now*. + + //For some reason, it crashes if I call -fire here. I don't know why. It doesn't crash if I simply set the fire date to now. + [_springTimer setFireDate:[NSDate date]]; + } else {*/ + //Wind the spring for a spring-loaded drop. + //The delay time comes from Finder's defaults, which specifies it in milliseconds. + //If the delegate can't handle our spring-loaded drop, we'll abort it when the timer fires. See fireSpring:. This is simpler than constantly (checking for spring-loaded awareness and tearing down/rebuilding the timer) at every delegate change. + + //If the user has dragged to a different tab, reset the timer. + if(_tabViewItemWithSpring != [cell representedObject]) { + [_springTimer invalidate]; + [_springTimer release]; _springTimer = nil; + _tabViewItemWithSpring = [cell representedObject]; + } + if(!_springTimer) { + //Finder's default delay time, as of Tiger, is 668 ms. If the user has never changed it, there's no setting in its defaults, so we default to that amount. + NSNumber *delayNumber = [(NSNumber *)CFPreferencesCopyAppValue((CFStringRef)@"SpringingDelayMilliseconds", (CFStringRef)@"com.apple.finder") autorelease]; + NSTimeInterval delaySeconds = delayNumber ?[delayNumber doubleValue] / 1000.0 : 0.668; + _springTimer = [[NSTimer scheduledTimerWithTimeInterval:delaySeconds + target:self + selector:@selector(fireSpring:) + userInfo:sender + repeats:NO] retain]; } return NSDragOperationCopy; } - - return NSDragOperationNone; + + return NSDragOperationNone; } -- (void)draggingExited:(id <NSDraggingInfo>)sender -{ +- (void)draggingExited:(id <NSDraggingInfo>)sender { [_springTimer invalidate]; [_springTimer release]; _springTimer = nil; - [[PSMTabDragAssistant sharedDragAssistant] draggingExitedTabBar:self]; + [[PSMTabDragAssistant sharedDragAssistant] draggingExitedTabBar:self]; } -- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender -{ +- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender { //validate the drag operation only if there's a valid tab bar to drop into return [[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] == NSNotFound || - [[PSMTabDragAssistant sharedDragAssistant] destinationTabBar] != nil; + [[PSMTabDragAssistant sharedDragAssistant] destinationTabBar] != nil; } -- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender -{ - if ([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { +- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender { + if([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { [[PSMTabDragAssistant sharedDragAssistant] performDragOperation]; - } else if ([self delegate] && [[self delegate] respondsToSelector:@selector(tabView:acceptedDraggingInfo:onTabViewItem:)]) { + } else if([self delegate] && [[self delegate] respondsToSelector:@selector(tabView:acceptedDraggingInfo:onTabViewItem:)]) { //forward the drop to the delegate [[self delegate] tabView:tabView acceptedDraggingInfo:sender onTabViewItem:[[self cellForPoint:[self convertPoint:[sender draggingLocation] fromView:nil] cellFrame:nil] representedObject]]; } - return YES; + return YES; } -- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation -{ +- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation { [[PSMTabDragAssistant sharedDragAssistant] draggedImageEndedAt:aPoint operation:operation]; } -- (void)concludeDragOperation:(id <NSDraggingInfo>)sender -{ - +- (void)concludeDragOperation:(id <NSDraggingInfo>)sender { } #pragma mark - #pragma mark Spring-loading -- (void)fireSpring:(NSTimer *)timer -{ +- (void)fireSpring:(NSTimer *)timer { NSAssert1(timer == _springTimer, @"Spring fired by unrecognized timer %@", timer); id <NSDraggingInfo> sender = [timer userInfo]; @@ -1528,116 +1448,106 @@ #pragma mark - #pragma mark Actions -- (void)overflowMenuAction:(id)sender -{ +- (void)overflowMenuAction:(id)sender { NSTabViewItem *tabViewItem = (NSTabViewItem *)[sender representedObject]; [tabView selectTabViewItem:tabViewItem]; } -- (void)closeTabClick:(id)sender -{ +- (void)closeTabClick:(id)sender { NSTabViewItem *item = [sender representedObject]; - [sender retain]; - if(([_cells count] == 1) && (![self canCloseOnlyTab])) - return; - - if ([[self delegate] respondsToSelector:@selector(tabView:shouldCloseTabViewItem:)]) { - if (![[self delegate] tabView:tabView shouldCloseTabViewItem:item]) { - // fix mouse downed close button - [sender setCloseButtonPressed:NO]; - return; - } - } - - [item retain]; - + [sender retain]; + if(([_cells count] == 1) && (![self canCloseOnlyTab])) { + return; + } + + if([[self delegate] respondsToSelector:@selector(tabView:shouldCloseTabViewItem:)]) { + if(![[self delegate] tabView:tabView shouldCloseTabViewItem:item]) { + // fix mouse downed close button + [sender setCloseButtonPressed:NO]; + return; + } + } + + [item retain]; + [tabView removeTabViewItem:item]; - [item release]; - [sender release]; + [item release]; + [sender release]; } -- (void)tabClick:(id)sender -{ - [tabView selectTabViewItem:[sender representedObject]]; +- (void)tabClick:(id)sender { + [tabView selectTabViewItem:[sender representedObject]]; } -- (void)tabNothing:(id)sender -{ - //[self update]; // takes care of highlighting based on state +- (void)tabNothing:(id)sender { + //[self update]; // takes care of highlighting based on state } -- (void)frameDidChange:(NSNotification *)notification -{ +- (void)frameDidChange:(NSNotification *)notification { [self _checkWindowFrame]; // trying to address the drawing artifacts for the progress indicators - hackery follows // this one fixes the "blanking" effect when the control hides and shows itself NSEnumerator *e = [_cells objectEnumerator]; PSMTabBarCell *cell; - while ( (cell = [e nextObject]) ) { + while((cell = [e nextObject])) { [[cell indicator] stopAnimation:self]; [[cell indicator] performSelector:@selector(startAnimation:) - withObject:nil - afterDelay:0]; + withObject:nil + afterDelay:0]; } [self update:NO]; } -- (void)viewDidMoveToWindow -{ +- (void)viewDidMoveToWindow { [self _checkWindowFrame]; } -- (void)viewWillStartLiveResize -{ - NSEnumerator *e = [_cells objectEnumerator]; - PSMTabBarCell *cell; - while ( (cell = [e nextObject]) ) { - [[cell indicator] stopAnimation:self]; - } - [self setNeedsDisplay:YES]; +- (void)viewWillStartLiveResize { + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while((cell = [e nextObject])) { + [[cell indicator] stopAnimation:self]; + } + [self setNeedsDisplay:YES]; } --(void)viewDidEndLiveResize -{ - NSEnumerator *e = [_cells objectEnumerator]; - PSMTabBarCell *cell; - while ( (cell = [e nextObject]) ) { - [[cell indicator] startAnimation:self]; - } - +-(void)viewDidEndLiveResize { + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while((cell = [e nextObject])) { + [[cell indicator] startAnimation:self]; + } + [self _checkWindowFrame]; - [self update:NO]; + [self update:NO]; } -- (void)resetCursorRects -{ +- (void)resetCursorRects { [super resetCursorRects]; - if ([self orientation] == PSMTabBarVerticalOrientation) { + if([self orientation] == PSMTabBarVerticalOrientation) { NSRect frame = [self frame]; [self addCursorRect:NSMakeRect(frame.size.width - 2, 0, 2, frame.size.height) cursor:[NSCursor resizeLeftRightCursor]]; } } -- (void)windowDidMove:(NSNotification *)aNotification -{ - [self setNeedsDisplay:YES]; +- (void)windowDidMove:(NSNotification *)aNotification { + [self setNeedsDisplay:YES]; } -- (void)windowDidUpdate:(NSNotification *)notification -{ - // hide? must readjust things if I'm not supposed to be showing - // this block of code only runs when the app launches - if ([self hideForSingleTab] && ([_cells count] <= 1) && !_awakenedFromNib) { - // must adjust frames now before display - NSRect myFrame = [self frame]; - if ([self orientation] == PSMTabBarHorizontalOrientation) { - if (partnerView) { +- (void)windowDidUpdate:(NSNotification *)notification { + // hide? must readjust things if I'm not supposed to be showing + // this block of code only runs when the app launches + if([self hideForSingleTab] && ([_cells count] <= 1) && !_awakenedFromNib) { + // must adjust frames now before display + NSRect myFrame = [self frame]; + if([self orientation] == PSMTabBarHorizontalOrientation) { + if(partnerView) { NSRect partnerFrame = [partnerView frame]; // above or below me? - if (myFrame.origin.y - 22 > [partnerView frame].origin.y) { + if(myFrame.origin.y - 22 > [partnerView frame].origin.y) { // partner is below me [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y + 21, myFrame.size.width, myFrame.size.height - 21)]; [partnerView setFrame:NSMakeRect(partnerFrame.origin.x, partnerFrame.origin.y, partnerFrame.size.width, partnerFrame.size.height + 21)]; @@ -1655,10 +1565,10 @@ [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y, myFrame.size.width, myFrame.size.height - 21)]; } } else { - if (partnerView) { + if(partnerView) { NSRect partnerFrame = [partnerView frame]; //to the left or right? - if (myFrame.origin.x < [partnerView frame].origin.x) { + if(myFrame.origin.x < [partnerView frame].origin.x) { // partner is to the left [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y, 1, myFrame.size.height)]; [partnerView setFrame:NSMakeRect(partnerFrame.origin.x - myFrame.size.width + 1, partnerFrame.origin.y, partnerFrame.size.width + myFrame.size.width - 1, partnerFrame.size.height)]; @@ -1677,17 +1587,17 @@ [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y, 1, myFrame.size.height)]; } } - - _isHidden = YES; - - if ([[self delegate] respondsToSelector:@selector(tabView:tabBarDidHide:)]) { + + _isHidden = YES; + + if([[self delegate] respondsToSelector:@selector(tabView:tabBarDidHide:)]) { [[self delegate] tabView:[self tabView] tabBarDidHide:self]; } - } - + } + _awakenedFromNib = YES; [self setNeedsDisplay:YES]; - + //we only need to do this once [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidUpdateNotification object:nil]; } @@ -1695,31 +1605,28 @@ #pragma mark - #pragma mark Menu Validation -- (BOOL)validateMenuItem:(NSMenuItem *)sender -{ +- (BOOL)validateMenuItem:(NSMenuItem *)sender { [sender setState:([[sender representedObject] isEqualTo:[tabView selectedTabViewItem]]) ? NSOnState : NSOffState]; - + return [[self delegate] respondsToSelector:@selector(tabView:validateOverflowMenuItem:forTabViewItem:)] ? - [[self delegate] tabView:[self tabView] validateOverflowMenuItem:sender forTabViewItem:[sender representedObject]] : YES; + [[self delegate] tabView:[self tabView] validateOverflowMenuItem:sender forTabViewItem:[sender representedObject]] : YES; } #pragma mark - #pragma mark NSTabView Delegate -- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem -{ - // here's a weird one - this message is sent before the "tabViewDidChangeNumberOfTabViewItems" - // message, thus I can end up updating when there are no cells, if no tabs were (yet) present +- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem { + // here's a weird one - this message is sent before the "tabViewDidChangeNumberOfTabViewItems" + // message, thus I can end up updating when there are no cells, if no tabs were (yet) present NSInteger tabIndex = [aTabView indexOfTabViewItem:tabViewItem]; - - if ([_cells count] > 0 && tabIndex < [_cells count]) { + + if([_cells count] > 0 && tabIndex < [_cells count]) { PSMTabBarCell *thisCell = [_cells objectAtIndex:tabIndex]; - if (_alwaysShowActiveTab && [thisCell isInOverflowMenu]) { - + if(_alwaysShowActiveTab && [thisCell isInOverflowMenu]) { //temporarily disable the delegate in order to move the tab to a different index id tempDelegate = [aTabView delegate]; [aTabView setDelegate:nil]; - + // move it all around first [tabViewItem retain]; [thisCell retain]; @@ -1727,85 +1634,83 @@ [aTabView insertTabViewItem:tabViewItem atIndex:0]; [_cells removeObjectAtIndex:tabIndex]; [_cells insertObject:thisCell atIndex:0]; - [thisCell setIsInOverflowMenu:NO]; //very important else we get a fun recursive loop going - [[_cells objectAtIndex:[_cells count] - 1] setIsInOverflowMenu:YES]; //these 2 lines are pretty uncool and this logic needs to be updated + [thisCell setIsInOverflowMenu:NO]; //very important else we get a fun recursive loop going + [[_cells objectAtIndex:[_cells count] - 1] setIsInOverflowMenu:YES]; //these 2 lines are pretty uncool and this logic needs to be updated [thisCell release]; [tabViewItem release]; - + [aTabView setDelegate:tempDelegate]; - - //reset the selection since removing it changed the selection + + //reset the selection since removing it changed the selection [aTabView selectTabViewItem:tabViewItem]; - + [self update]; } else { - [_controller setSelectedCell:thisCell]; - [self setNeedsDisplay:YES]; + [_controller setSelectedCell:thisCell]; + [self setNeedsDisplay:YES]; } - } - - if ([[self delegate] respondsToSelector:@selector(tabView:didSelectTabViewItem:)]) { + } + + if([[self delegate] respondsToSelector:@selector(tabView:didSelectTabViewItem:)]) { [[self delegate] performSelector:@selector(tabView:didSelectTabViewItem:) withObject:aTabView withObject:tabViewItem]; } } -- (BOOL)tabView:(NSTabView *)aTabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem -{ - if ([[self delegate] respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)]) { +- (BOOL)tabView:(NSTabView *)aTabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem { + if([[self delegate] respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)]) { return [[self delegate] tabView:aTabView shouldSelectTabViewItem:tabViewItem]; } else { return YES; } } -- (void)tabView:(NSTabView *)aTabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem -{ - if ([[self delegate] respondsToSelector:@selector(tabView:willSelectTabViewItem:)]) { +- (void)tabView:(NSTabView *)aTabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem { + if([[self delegate] respondsToSelector:@selector(tabView:willSelectTabViewItem:)]) { [[self delegate] performSelector:@selector(tabView:willSelectTabViewItem:) withObject:aTabView withObject:tabViewItem]; } } -- (void)tabViewDidChangeNumberOfTabViewItems:(NSTabView *)aTabView -{ - NSArray *tabItems = [tabView tabViewItems]; - // go through cells, remove any whose representedObjects are not in [tabView tabViewItems] - NSEnumerator *e = [[[_cells copy] autorelease] objectEnumerator]; - PSMTabBarCell *cell; - while ( (cell = [e nextObject]) ) { +- (void)tabViewDidChangeNumberOfTabViewItems:(NSTabView *)aTabView { + NSArray *tabItems = [tabView tabViewItems]; + // go through cells, remove any whose representedObjects are not in [tabView tabViewItems] + NSEnumerator *e = [[[_cells copy] autorelease] objectEnumerator]; + PSMTabBarCell *cell; + while((cell = [e nextObject])) { //remove the observer binding - if ([cell representedObject] && ![tabItems containsObject:[cell representedObject]]) { - if ([[self delegate] respondsToSelector:@selector(tabView:didCloseTabViewItem:)]) { + if([cell representedObject] && ![tabItems containsObject:[cell representedObject]]) { + if([[self delegate] respondsToSelector:@selector(tabView:didCloseTabViewItem:)]) { [[self delegate] tabView:aTabView didCloseTabViewItem:[cell representedObject]]; } - - [self removeTabForCell:cell]; - } - } - - // go through tab view items, add cell for any not present - NSMutableArray *cellItems = [self representedTabViewItems]; - NSEnumerator *ex = [tabItems objectEnumerator]; - NSTabViewItem *item; - while ( (item = [ex nextObject]) ) { - if (![cellItems containsObject:item]) { - [self addTabViewItem:item]; - } - } - - // pass along for other delegate responses - if ([[self delegate] respondsToSelector:@selector(tabViewDidChangeNumberOfTabViewItems:)]) { - [[self delegate] performSelector:@selector(tabViewDidChangeNumberOfTabViewItems:) withObject:aTabView]; - } - + + [self removeTabForCell:cell]; + } + } + + // go through tab view items, add cell for any not present + NSMutableArray *cellItems = [self representedTabViewItems]; + NSEnumerator *ex = [tabItems objectEnumerator]; + NSTabViewItem *item; + while((item = [ex nextObject])) { + if(![cellItems containsObject:item]) { + [self addTabViewItem:item]; + } + } + + // pass along for other delegate responses + if([[self delegate] respondsToSelector:@selector(tabViewDidChangeNumberOfTabViewItems:)]) { + [[self delegate] performSelector:@selector(tabViewDidChangeNumberOfTabViewItems:) withObject:aTabView]; + } + // reset cursor tracking for the add tab button if one exists - if ([self addTabButton]) [[self addTabButton] resetCursorRects]; + if([self addTabButton]) { + [[self addTabButton] resetCursorRects]; + } } #pragma mark - #pragma mark Tooltips -- (NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoint)point userData:(void *)userData -{ - if ([[self delegate] respondsToSelector:@selector(tabView:toolTipForTabViewItem:)]) { +- (NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoint)point userData:(void *)userData { + if([[self delegate] respondsToSelector:@selector(tabView:toolTipForTabViewItem:)]) { return [[self delegate] tabView:[self tabView] toolTipForTabViewItem:[[self cellForPoint:point cellFrame:nil] representedObject]]; } return nil; @@ -1816,232 +1721,231 @@ - (void)encodeWithCoder:(NSCoder *)aCoder { - [super encodeWithCoder:aCoder]; - if ([aCoder allowsKeyedCoding]) { - [aCoder encodeObject:_cells forKey:@"PSMcells"]; - [aCoder encodeObject:tabView forKey:@"PSMtabView"]; - [aCoder encodeObject:_overflowPopUpButton forKey:@"PSMoverflowPopUpButton"]; - [aCoder encodeObject:_addTabButton forKey:@"PSMaddTabButton"]; - [aCoder encodeObject:style forKey:@"PSMstyle"]; + [super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject:_cells forKey:@"PSMcells"]; + [aCoder encodeObject:tabView forKey:@"PSMtabView"]; + [aCoder encodeObject:_overflowPopUpButton forKey:@"PSMoverflowPopUpButton"]; + [aCoder encodeObject:_addTabButton forKey:@"PSMaddTabButton"]; + [aCoder encodeObject:style forKey:@"PSMstyle"]; [aCoder encodeInteger:_orientation forKey:@"PSMorientation"]; - [aCoder encodeBool:_canCloseOnlyTab forKey:@"PSMcanCloseOnlyTab"]; + [aCoder encodeBool:_canCloseOnlyTab forKey:@"PSMcanCloseOnlyTab"]; [aCoder encodeBool:_disableTabClose forKey:@"PSMdisableTabClose"]; - [aCoder encodeBool:_hideForSingleTab forKey:@"PSMhideForSingleTab"]; + [aCoder encodeBool:_hideForSingleTab forKey:@"PSMhideForSingleTab"]; [aCoder encodeBool:_allowsBackgroundTabClosing forKey:@"PSMallowsBackgroundTabClosing"]; [aCoder encodeBool:_allowsResizing forKey:@"PSMallowsResizing"]; [aCoder encodeBool:_selectsTabsOnMouseDown forKey:@"PSMselectsTabsOnMouseDown"]; - [aCoder encodeBool:_showAddTabButton forKey:@"PSMshowAddTabButton"]; - [aCoder encodeBool:_sizeCellsToFit forKey:@"PSMsizeCellsToFit"]; - [aCoder encodeInteger:_cellMinWidth forKey:@"PSMcellMinWidth"]; - [aCoder encodeInteger:_cellMaxWidth forKey:@"PSMcellMaxWidth"]; - [aCoder encodeInteger:_cellOptimumWidth forKey:@"PSMcellOptimumWidth"]; - [aCoder encodeInteger:_currentStep forKey:@"PSMcurrentStep"]; - [aCoder encodeBool:_isHidden forKey:@"PSMisHidden"]; - [aCoder encodeObject:partnerView forKey:@"PSMpartnerView"]; - [aCoder encodeBool:_awakenedFromNib forKey:@"PSMawakenedFromNib"]; - [aCoder encodeObject:_lastMouseDownEvent forKey:@"PSMlastMouseDownEvent"]; - [aCoder encodeObject:delegate forKey:@"PSMdelegate"]; + [aCoder encodeBool:_showAddTabButton forKey:@"PSMshowAddTabButton"]; + [aCoder encodeBool:_sizeCellsToFit forKey:@"PSMsizeCellsToFit"]; + [aCoder encodeInteger:_cellMinWidth forKey:@"PSMcellMinWidth"]; + [aCoder encodeInteger:_cellMaxWidth forKey:@"PSMcellMaxWidth"]; + [aCoder encodeInteger:_cellOptimumWidth forKey:@"PSMcellOptimumWidth"]; + [aCoder encodeInteger:_currentStep forKey:@"PSMcurrentStep"]; + [aCoder encodeBool:_isHidden forKey:@"PSMisHidden"]; + [aCoder encodeObject:partnerView forKey:@"PSMpartnerView"]; + [aCoder encodeBool:_awakenedFromNib forKey:@"PSMawakenedFromNib"]; + [aCoder encodeObject:_lastMouseDownEvent forKey:@"PSMlastMouseDownEvent"]; + [aCoder encodeObject:delegate forKey:@"PSMdelegate"]; [aCoder encodeBool:_useOverflowMenu forKey:@"PSMuseOverflowMenu"]; [aCoder encodeBool:_automaticallyAnimates forKey:@"PSMautomaticallyAnimates"]; [aCoder encodeBool:_alwaysShowActiveTab forKey:@"PSMalwaysShowActiveTab"]; - } + } } - (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if (self) { - if ([aDecoder allowsKeyedCoding]) { - _cells = [[aDecoder decodeObjectForKey:@"PSMcells"] retain]; - tabView = [[aDecoder decodeObjectForKey:@"PSMtabView"] retain]; - _overflowPopUpButton = [[aDecoder decodeObjectForKey:@"PSMoverflowPopUpButton"] retain]; - _addTabButton = [[aDecoder decodeObjectForKey:@"PSMaddTabButton"] retain]; - style = [[aDecoder decodeObjectForKey:@"PSMstyle"] retain]; + self = [super initWithCoder:aDecoder]; + if (self) { + // Initialization + [self initAddedProperties]; + [self registerForDraggedTypes:[NSArray arrayWithObjects:@"PSMTabBarControlItemPBType", nil]]; + + // resize + [self setPostsFrameChangedNotifications:YES]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(frameDidChange:) name:NSViewFrameDidChangeNotification object:self]; + if ([aDecoder allowsKeyedCoding]) { + _cells = [[aDecoder decodeObjectForKey:@"PSMcells"] retain]; + tabView = [[aDecoder decodeObjectForKey:@"PSMtabView"] retain]; + _overflowPopUpButton = [[aDecoder decodeObjectForKey:@"PSMoverflowPopUpButton"] retain]; + _addTabButton = [[aDecoder decodeObjectForKey:@"PSMaddTabButton"] retain]; + style = [[aDecoder decodeObjectForKey:@"PSMstyle"] retain]; _orientation = (PSMTabBarOrientation)[aDecoder decodeIntegerForKey:@"PSMorientation"]; - _canCloseOnlyTab = [aDecoder decodeBoolForKey:@"PSMcanCloseOnlyTab"]; + _canCloseOnlyTab = [aDecoder decodeBoolForKey:@"PSMcanCloseOnlyTab"]; _disableTabClose = [aDecoder decodeBoolForKey:@"PSMdisableTabClose"]; - _hideForSingleTab = [aDecoder decodeBoolForKey:@"PSMhideForSingleTab"]; + _hideForSingleTab = [aDecoder decodeBoolForKey:@"PSMhideForSingleTab"]; _allowsBackgroundTabClosing = [aDecoder decodeBoolForKey:@"PSMallowsBackgroundTabClosing"]; _allowsResizing = [aDecoder decodeBoolForKey:@"PSMallowsResizing"]; _selectsTabsOnMouseDown = [aDecoder decodeBoolForKey:@"PSMselectsTabsOnMouseDown"]; - _showAddTabButton = [aDecoder decodeBoolForKey:@"PSMshowAddTabButton"]; - _sizeCellsToFit = [aDecoder decodeBoolForKey:@"PSMsizeCellsToFit"]; - _cellMinWidth = [aDecoder decodeIntegerForKey:@"PSMcellMinWidth"]; - _cellMaxWidth = [aDecoder decodeIntegerForKey:@"PSMcellMaxWidth"]; - _cellOptimumWidth = [aDecoder decodeIntegerForKey:@"PSMcellOptimumWidth"]; - _currentStep = [aDecoder decodeIntegerForKey:@"PSMcurrentStep"]; - _isHidden = [aDecoder decodeBoolForKey:@"PSMisHidden"]; - partnerView = [[aDecoder decodeObjectForKey:@"PSMpartnerView"] retain]; - _awakenedFromNib = [aDecoder decodeBoolForKey:@"PSMawakenedFromNib"]; - _lastMouseDownEvent = [[aDecoder decodeObjectForKey:@"PSMlastMouseDownEvent"] retain]; + _showAddTabButton = [aDecoder decodeBoolForKey:@"PSMshowAddTabButton"]; + _sizeCellsToFit = [aDecoder decodeBoolForKey:@"PSMsizeCellsToFit"]; + _cellMinWidth = [aDecoder decodeIntegerForKey:@"PSMcellMinWidth"]; + _cellMaxWidth = [aDecoder decodeIntegerForKey:@"PSMcellMaxWidth"]; + _cellOptimumWidth = [aDecoder decodeIntegerForKey:@"PSMcellOptimumWidth"]; + _currentStep = [aDecoder decodeIntegerForKey:@"PSMcurrentStep"]; + _isHidden = [aDecoder decodeBoolForKey:@"PSMisHidden"]; + partnerView = [[aDecoder decodeObjectForKey:@"PSMpartnerView"] retain]; + _awakenedFromNib = [aDecoder decodeBoolForKey:@"PSMawakenedFromNib"]; + _lastMouseDownEvent = [[aDecoder decodeObjectForKey:@"PSMlastMouseDownEvent"] retain]; _useOverflowMenu = [aDecoder decodeBoolForKey:@"PSMuseOverflowMenu"]; _automaticallyAnimates = [aDecoder decodeBoolForKey:@"PSMautomaticallyAnimates"]; _alwaysShowActiveTab = [aDecoder decodeBoolForKey:@"PSMalwaysShowActiveTab"]; - delegate = [[aDecoder decodeObjectForKey:@"PSMdelegate"] retain]; - } - } - return self; + delegate = [[aDecoder decodeObjectForKey:@"PSMdelegate"] retain]; + } + } + [self setTarget:self]; + return self; } #pragma mark - #pragma mark IB Palette -- (NSSize)minimumFrameSizeFromKnobPosition:(NSInteger)position -{ - return NSMakeSize(100.0, 22.0); +- (NSSize)minimumFrameSizeFromKnobPosition:(NSInteger)position { + return NSMakeSize(100.0, 22.0); } -- (NSSize)maximumFrameSizeFromKnobPosition:(NSInteger)knobPosition -{ - return NSMakeSize(10000.0, 22.0); +- (NSSize)maximumFrameSizeFromKnobPosition:(NSInteger)knobPosition { + return NSMakeSize(10000.0, 22.0); } -- (void)placeView:(NSRect)newFrame -{ - // this is called any time the view is resized in IB - [self setFrame:newFrame]; - [self update:NO]; +- (void)placeView:(NSRect)newFrame { + // this is called any time the view is resized in IB + [self setFrame:newFrame]; + [self update:NO]; } #pragma mark - #pragma mark Convenience -- (void)bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewItem *)item -{ - [self _bindPropertiesForCell:cell andTabViewItem:item]; - - // watch for changes in the identifier - [item addObserver:self forKeyPath:@"identifier" options:0 context:nil]; +- (void)bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewItem *)item { + [self _bindPropertiesForCell:cell andTabViewItem:item]; + + // watch for changes in the identifier + [item addObserver:self forKeyPath:@"identifier" options:0 context:nil]; } -- (void)_bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewItem *)item -{ - // bind the indicator to the represented object's status (if it exists) - [[cell indicator] setHidden:YES]; - if ([item identifier] != nil) { - if ([[[cell representedObject] identifier] respondsToSelector:@selector(isProcessing)]) { +- (void)_bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewItem *)item { + // bind the indicator to the represented object's status (if it exists) + [[cell indicator] setHidden:YES]; + if([item identifier] != nil) { + if([[[cell representedObject] identifier] respondsToSelector:@selector(isProcessing)]) { NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary]; [bindingOptions setObject:NSNegateBooleanTransformerName forKey:@"NSValueTransformerName"]; [[cell indicator] bind:@"animate" toObject:[item identifier] withKeyPath:@"isProcessing" options:nil]; [[cell indicator] bind:@"hidden" toObject:[item identifier] withKeyPath:@"isProcessing" options:bindingOptions]; - [[item identifier] addObserver:cell forKeyPath:@"isProcessing" options:0 context:nil]; - } - } - - // bind for the existence of an icon - [cell setHasIcon:NO]; - if ([item identifier] != nil) { - if ([[[cell representedObject] identifier] respondsToSelector:@selector(icon)]) { + [[item identifier] addObserver:cell forKeyPath:@"isProcessing" options:0 context:nil]; + } + } + + // bind for the existence of an icon + [cell setHasIcon:NO]; + if([item identifier] != nil) { + if([[[cell representedObject] identifier] respondsToSelector:@selector(icon)]) { NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary]; [bindingOptions setObject:NSIsNotNilTransformerName forKey:@"NSValueTransformerName"]; [cell bind:@"hasIcon" toObject:[item identifier] withKeyPath:@"icon" options:bindingOptions]; [[item identifier] addObserver:cell forKeyPath:@"icon" options:0 context:nil]; - } - } - - // bind for the existence of a counter - [cell setCount:0]; - if ([item identifier] != nil) { - if ([[[cell representedObject] identifier] respondsToSelector:@selector(objectCount)]) { + } + } + + // bind for the existence of a counter + [cell setCount:0]; + if([item identifier] != nil) { + if([[[cell representedObject] identifier] respondsToSelector:@selector(objectCount)]) { [cell bind:@"count" toObject:[item identifier] withKeyPath:@"objectCount" options:nil]; [[item identifier] addObserver:cell forKeyPath:@"objectCount" options:0 context:nil]; } - } - - // bind for the color of a counter - [cell setCountColor:nil]; - if ([item identifier] != nil) { - if ([[[cell representedObject] identifier] respondsToSelector:@selector(countColor)]) { + } + + // bind for the color of a counter + [cell setCountColor:nil]; + if([item identifier] != nil) { + if([[[cell representedObject] identifier] respondsToSelector:@selector(countColor)]) { [cell bind:@"countColor" toObject:[item identifier] withKeyPath:@"countColor" options:nil]; [[item identifier] addObserver:cell forKeyPath:@"countColor" options:0 context:nil]; } - } + } // bind for a large image [cell setHasLargeImage:NO]; - if ([item identifier] != nil) { - if ([[[cell representedObject] identifier] respondsToSelector:@selector(largeImage)]) { + if([item identifier] != nil) { + if([[[cell representedObject] identifier] respondsToSelector:@selector(largeImage)]) { NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary]; [bindingOptions setObject:NSIsNotNilTransformerName forKey:@"NSValueTransformerName"]; [cell bind:@"hasLargeImage" toObject:[item identifier] withKeyPath:@"largeImage" options:bindingOptions]; [[item identifier] addObserver:cell forKeyPath:@"largeImage" options:0 context:nil]; } - } - - [cell setIsEdited:NO]; - if ([item identifier] != nil) { - if ([[[cell representedObject] identifier] respondsToSelector:@selector(isEdited)]) { + } + + [cell setIsEdited:NO]; + if([item identifier] != nil) { + if([[[cell representedObject] identifier] respondsToSelector:@selector(isEdited)]) { [cell bind:@"isEdited" toObject:[item identifier] withKeyPath:@"isEdited" options:nil]; [[item identifier] addObserver:cell forKeyPath:@"isEdited" options:0 context:nil]; } - } - - // bind my string value to the label on the represented tab - [cell bind:@"title" toObject:item withKeyPath:@"label" options:nil]; + } + + // bind my string value to the label on the represented tab + [cell bind:@"title" toObject:item withKeyPath:@"label" options:nil]; } -- (NSMutableArray *)representedTabViewItems -{ - NSMutableArray *temp = [NSMutableArray arrayWithCapacity:[_cells count]]; - NSEnumerator *e = [_cells objectEnumerator]; - PSMTabBarCell *cell; - while ( (cell = [e nextObject])) { - if ([cell representedObject]) { +- (NSMutableArray *)representedTabViewItems { + NSMutableArray *temp = [NSMutableArray arrayWithCapacity:[_cells count]]; + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while((cell = [e nextObject])) { + if([cell representedObject]) { [temp addObject:[cell representedObject]]; } - } - return temp; + } + return temp; } -- (id)cellForPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame -{ - if ([self orientation] == PSMTabBarHorizontalOrientation && !NSPointInRect(point, [self genericCellRect])) { - return nil; - } - - NSInteger i, cnt = [_cells count]; - for (i = 0; i < cnt; i++) { - PSMTabBarCell *cell = [_cells objectAtIndex:i]; - - if (NSPointInRect(point, [cell frame])) { - if (outFrame) { - *outFrame = [cell frame]; - } - return cell; - } - } - return nil; -} - -- (PSMTabBarCell *)lastVisibleTab -{ - NSInteger i, cellCount = [_cells count]; - for (i = 0; i < cellCount; i++) { - if ([[_cells objectAtIndex:i] isInOverflowMenu]) { - return [_cells objectAtIndex:(i - 1)]; - } - } - return [_cells objectAtIndex:(cellCount - 1)]; +- (id)cellForPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame { + if([self orientation] == PSMTabBarHorizontalOrientation && !NSPointInRect(point, [self genericCellRect])) { + return nil; + } + + NSInteger i, cnt = [_cells count]; + for(i = 0; i < cnt; i++) { + PSMTabBarCell *cell = [_cells objectAtIndex:i]; + + if(NSPointInRect(point, [cell frame])) { + if(outFrame) { + *outFrame = [cell frame]; + } + return cell; + } + } + return nil; } -- (NSInteger)numberOfVisibleTabs -{ - NSInteger cellCount = 0; +- (PSMTabBarCell *)lastVisibleTab { + NSInteger i, cellCount = [_cells count]; + for(i = 0; i < cellCount; i++) { + if([[_cells objectAtIndex:i] isInOverflowMenu]) { + return [_cells objectAtIndex:(i - 1)]; + } + } + return [_cells objectAtIndex:(cellCount - 1)]; +} + +- (NSInteger)numberOfVisibleTabs { + NSInteger i, cellCount = 0; PSMTabBarCell *nextCell; - - for (NSUInteger i = 0; i < [_cells count]; i++) { + + for(i = 0; i < [_cells count]; i++) { nextCell = [_cells objectAtIndex:i]; - - if ([nextCell isInOverflowMenu]) { - break; - } - - if (![nextCell isPlaceholder]) { + + if([nextCell isInOverflowMenu]) { + break; + } + + if(![nextCell isPlaceholder]) { cellCount++; } - } - - return cellCount; + } + + return cellCount; } #pragma mark - @@ -2053,9 +1957,9 @@ - (id)accessibilityAttributeValue:(NSString *)attribute { id attributeValue = nil; - if ([attribute isEqualToString: NSAccessibilityRoleAttribute]) { + if([attribute isEqualToString: NSAccessibilityRoleAttribute]) { attributeValue = NSAccessibilityGroupRole; - } else if ([attribute isEqualToString: NSAccessibilityChildrenAttribute]) { + } else if([attribute isEqualToString: NSAccessibilityChildrenAttribute]) { attributeValue = NSAccessibilityUnignoredChildren(_cells); } else { attributeValue = [super accessibilityAttributeValue:attribute]; @@ -2065,21 +1969,21 @@ - (id)accessibilityHitTest:(NSPoint)point { id hitTestResult = self; - + NSEnumerator *enumerator = [_cells objectEnumerator]; PSMTabBarCell *cell = nil; PSMTabBarCell *highlightedCell = nil; - - while (!highlightedCell && (cell = [enumerator nextObject])) { - if ([cell isHighlighted]) { + + while(!highlightedCell && (cell = [enumerator nextObject])) { + if([cell isHighlighted]) { highlightedCell = cell; } } - - if (highlightedCell) { + + if(highlightedCell) { hitTestResult = [highlightedCell accessibilityHitTest:point]; } - + return hitTestResult; } |