5 // Created by John Pannell on 10/13/05.
6 // Copyright 2005 Positive Spin Media. All rights reserved.
9 #import "PSMTabBarCell.h"
10 #import "PSMTabBarControl.h"
11 #import "PSMTabStyle.h"
12 #import "PSMProgressIndicator.h"
13 #import "PSMTabDragAssistant.h"
16 @implementation PSMTabBarCell
19 #pragma mark Creation/Destruction
20 - (id)initWithControlView:(PSMTabBarControl *)controlView
24 _controlView = controlView;
25 _closeButtonTrackingTag = 0;
27 _closeButtonOver = NO;
28 _closeButtonPressed = NO;
29 _indicator = [[PSMProgressIndicator alloc] initWithFrame:NSMakeRect(0.0,0.0,kPSMTabBarIndicatorWidth,kPSMTabBarIndicatorWidth)];
30 [_indicator setStyle:NSProgressIndicatorSpinningStyle];
31 [_indicator setAutoresizingMask:NSViewMinYMargin];
32 _hasCloseButton = YES;
33 _isCloseButtonSuppressed = NO;
40 - (id)initPlaceholderWithFrame:(NSRect)frame expanded:(BOOL)value inControlView:(PSMTabBarControl *)controlView
44 _controlView = controlView;
47 frame.size.width = 0.0;
48 [self setFrame:frame];
49 _closeButtonTrackingTag = 0;
51 _closeButtonOver = NO;
52 _closeButtonPressed = NO;
54 _hasCloseButton = YES;
55 _isCloseButtonSuppressed = NO;
59 [self setCurrentStep:(kPSMTabDragAnimationSteps - 1)];
61 [self setCurrentStep:0];
76 #pragma mark Accessors
83 - (void)setControlView:(id)view
85 // no retain release pattern, as this simply switches a tab to another view.
89 - (NSTrackingRectTag)closeButtonTrackingTag
91 return _closeButtonTrackingTag;
94 - (void)setCloseButtonTrackingTag:(NSTrackingRectTag)tag
96 _closeButtonTrackingTag = tag;
99 - (NSTrackingRectTag)cellTrackingTag
101 return _cellTrackingTag;
104 - (void)setCellTrackingTag:(NSTrackingRectTag)tag
106 _cellTrackingTag = tag;
111 return _frame.size.width;
119 - (void)setFrame:(NSRect)rect
124 - (void)setStringValue:(NSString *)aString
126 [super setStringValue:aString];
127 _stringSize = [[self attributedStringValue] size];
128 // need to redisplay now - binding observation was too quick.
129 [_controlView update];
137 - (NSAttributedString *)attributedStringValue
139 return [(id <PSMTabStyle>)[_controlView style] attributedStringValueForTabCell:self];
147 - (void)setTabState:(int)state
152 - (NSProgressIndicator *)indicator
157 - (BOOL)isInOverflowMenu
159 return _isInOverflowMenu;
162 - (void)setIsInOverflowMenu:(BOOL)value
164 _isInOverflowMenu = value;
167 - (BOOL)closeButtonPressed
169 return _closeButtonPressed;
172 - (void)setCloseButtonPressed:(BOOL)value
174 _closeButtonPressed = value;
177 - (BOOL)closeButtonOver
179 return _closeButtonOver;
182 - (void)setCloseButtonOver:(BOOL)value
184 _closeButtonOver = value;
187 - (BOOL)hasCloseButton
189 return _hasCloseButton;
192 - (void)setHasCloseButton:(BOOL)set;
194 _hasCloseButton = set;
197 - (void)setCloseButtonSuppressed:(BOOL)suppress;
199 _isCloseButtonSuppressed = suppress;
202 - (BOOL)isCloseButtonSuppressed;
204 return _isCloseButtonSuppressed;
212 - (void)setHasIcon:(BOOL)value
215 [_controlView update]; // binding notice is too fast
223 - (void)setCount:(int)value
226 [_controlView update]; // binding notice is too fast
229 - (BOOL)isPlaceholder
231 return _isPlaceholder;
234 - (void)setIsPlaceholder:(BOOL)value;
236 _isPlaceholder = value;
244 - (void)setCurrentStep:(int)value
249 if(value > (kPSMTabDragAnimationSteps - 1))
250 value = (kPSMTabDragAnimationSteps - 1);
252 _currentStep = value;
256 #pragma mark Component Attributes
258 - (NSRect)indicatorRectForFrame:(NSRect)cellFrame
260 return [(id <PSMTabStyle>)[_controlView style] indicatorRectForTabCell:self];
263 - (NSRect)closeButtonRectForFrame:(NSRect)cellFrame
265 return [(id <PSMTabStyle>)[_controlView style] closeButtonRectForTabCell:self];
268 - (float)minimumWidthOfCell
270 return [(id <PSMTabStyle>)[_controlView style] minimumWidthOfTabCell:self];
273 - (float)desiredWidthOfCell
275 return [(id <PSMTabStyle>)[_controlView style] desiredWidthOfTabCell:self];
281 - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
284 [[NSColor colorWithCalibratedWhite:0.0 alpha:0.2] set];
285 NSRectFillUsingOperation(cellFrame, NSCompositeSourceAtop);
289 [(id <PSMTabStyle>)[_controlView style] drawTabCell:self];
293 #pragma mark Tracking
295 - (void)mouseEntered:(NSEvent *)theEvent
297 // check for which tag
298 if([theEvent trackingNumber] == _closeButtonTrackingTag){
299 _closeButtonOver = YES;
301 if([theEvent trackingNumber] == _cellTrackingTag){
302 [self setHighlighted:YES];
304 [_controlView setNeedsDisplay];
307 - (void)mouseExited:(NSEvent *)theEvent
309 // check for which tag
310 if([theEvent trackingNumber] == _closeButtonTrackingTag){
311 _closeButtonOver = NO;
313 if([theEvent trackingNumber] == _cellTrackingTag){
314 [self setHighlighted:NO];
316 [_controlView setNeedsDisplay];
320 #pragma mark Drag Support
322 - (NSImage*)dragImageForRect:(NSRect)cellFrame
324 if(([self state] == NSOnState) && ([[_controlView styleName] isEqualToString:@"Metal"]))
325 cellFrame.size.width += 1.0;
326 [_controlView lockFocus];
327 NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:cellFrame];
328 [_controlView unlockFocus];
329 NSImage *image = [[[NSImage alloc] initWithSize:[rep size]] autorelease];
330 [image addRepresentation:rep];
331 NSImage *returnImage = [[[NSImage alloc] initWithSize:[rep size]] autorelease];
332 [returnImage lockFocus];
333 [image compositeToPoint:NSMakePoint(0.0, 0.0) operation:NSCompositeSourceOver fraction:0.7];
334 [returnImage unlockFocus];
335 if(![[self indicator] isHidden]){
336 NSImage *pi = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"pi"]];
337 [returnImage lockFocus];
338 NSPoint indicatorPoint = NSMakePoint([self frame].size.width - MARGIN_X - kPSMTabBarIndicatorWidth, MARGIN_Y);
339 if(([self state] == NSOnState) && ([[_controlView styleName] isEqualToString:@"Metal"]))
340 indicatorPoint.y += 1.0;
341 [pi compositeToPoint:indicatorPoint operation:NSCompositeSourceOver fraction:0.7];
342 [returnImage unlockFocus];
349 #pragma mark Archiving
351 - (void)encodeWithCoder:(NSCoder *)aCoder {
352 [super encodeWithCoder:aCoder];
353 if ([aCoder allowsKeyedCoding]) {
354 [aCoder encodeRect:_frame forKey:@"frame"];
355 [aCoder encodeSize:_stringSize forKey:@"stringSize"];
356 [aCoder encodeInt:_currentStep forKey:@"currentStep"];
357 [aCoder encodeBool:_isPlaceholder forKey:@"isPlaceholder"];
358 [aCoder encodeInt:_tabState forKey:@"tabState"];
359 [aCoder encodeInt:_closeButtonTrackingTag forKey:@"closeButtonTrackingTag"];
360 [aCoder encodeInt:_cellTrackingTag forKey:@"cellTrackingTag"];
361 [aCoder encodeBool:_closeButtonOver forKey:@"closeButtonOver"];
362 [aCoder encodeBool:_closeButtonPressed forKey:@"closeButtonPressed"];
363 [aCoder encodeObject:_indicator forKey:@"indicator"];
364 [aCoder encodeBool:_isInOverflowMenu forKey:@"isInOverflowMenu"];
365 [aCoder encodeBool:_hasCloseButton forKey:@"hasCloseButton"];
366 [aCoder encodeBool:_isCloseButtonSuppressed forKey:@"isCloseButtonSuppressed"];
367 [aCoder encodeBool:_hasIcon forKey:@"hasIcon"];
368 [aCoder encodeInt:_count forKey:@"count"];
372 - (id)initWithCoder:(NSCoder *)aDecoder {
373 self = [super initWithCoder:aDecoder];
375 if ([aDecoder allowsKeyedCoding]) {
376 _frame = [aDecoder decodeRectForKey:@"frame"];
377 NSLog(@"decoding cell");
378 _stringSize = [aDecoder decodeSizeForKey:@"stringSize"];
379 _currentStep = [aDecoder decodeIntForKey:@"currentStep"];
380 _isPlaceholder = [aDecoder decodeBoolForKey:@"isPlaceholder"];
381 _tabState = [aDecoder decodeIntForKey:@"tabState"];
382 _closeButtonTrackingTag = [aDecoder decodeIntForKey:@"closeButtonTrackingTag"];
383 _cellTrackingTag = [aDecoder decodeIntForKey:@"cellTrackingTag"];
384 _closeButtonOver = [aDecoder decodeBoolForKey:@"closeButtonOver"];
385 _closeButtonPressed = [aDecoder decodeBoolForKey:@"closeButtonPressed"];
386 _indicator = [[aDecoder decodeObjectForKey:@"indicator"] retain];
387 _isInOverflowMenu = [aDecoder decodeBoolForKey:@"isInOverflowMenu"];
388 _hasCloseButton = [aDecoder decodeBoolForKey:@"hasCloseButton"];
389 _isCloseButtonSuppressed = [aDecoder decodeBoolForKey:@"isCloseButtonSuppressed"];
390 _hasIcon = [aDecoder decodeBoolForKey:@"hasIcon"];
391 _count = [aDecoder decodeIntForKey:@"count"];