root/trunk/Views/JVDetailCell.m

Revision 3460, 13.7 kB (checked in by timothy, 2 years ago)

Removing the retain/autorelease idiom for accessor methods.

Line 
1 #import "JVDetailCell.h"
2
3 @implementation JVDetailCell
4 - (id) init {
5         if( ( self = [super init] ) ) {
6                 _altImage = nil;
7                 _statusImage = nil;
8                 _mainText = nil;
9                 _infoText = nil;
10
11                 [self setImageAlignment:NSImageAlignLeft];
12                 [self setImageScaling:NSScaleProportionally];
13                 [self setImageFrameStyle:NSImageFrameNone];
14                 [self setLineBreakMode:NSLineBreakByTruncatingTail];
15         }
16
17         return self;
18 }
19
20 - (id) copyWithZone:(NSZone *) zone {
21         JVDetailCell *cell = (JVDetailCell *)[super copyWithZone:zone];
22         cell -> _statusImage = [_statusImage retain];
23         cell -> _altImage = [_altImage retain];
24         cell -> _mainText = [_mainText copyWithZone:zone];
25         cell -> _infoText = [_infoText copyWithZone:zone];
26         cell -> _lineBreakMode = _lineBreakMode;
27         return cell;
28 }
29
30 - (void) dealloc {
31         [_altImage release];
32         [_statusImage release];
33         [_mainText release];
34         [_infoText release];
35
36         _altImage = nil;
37         _statusImage = nil;
38         _mainText = nil;
39         _infoText = nil;
40
41         [super dealloc];
42 }
43
44 #pragma mark -
45
46 - (void) setStatusImage:(NSImage *) image {
47         [_statusImage autorelease];
48         _statusImage = [image retain];
49 }
50
51 - (NSImage *) statusImage {
52         return _statusImage;
53 }
54
55 #pragma mark -
56
57 - (void) setStatusNumber:(unsigned) number {
58         _statusNumber = number;
59 }
60
61 - (unsigned) statusNumber {
62         return _statusNumber;
63 }
64
65 #pragma mark -
66
67 - (void) setImportantStatusNumber:(unsigned) number {
68         _importantStatusNumber = number;
69 }
70
71 - (unsigned) importantStatusNumber {
72         return _importantStatusNumber;
73 }
74
75 #pragma mark -
76
77 - (void) setHighlightedImage:(NSImage *) image {
78         [_altImage autorelease];
79         _altImage = [image retain];
80 }
81
82 - (NSImage *) highlightedImage {
83         return _altImage;
84 }
85
86 #pragma mark -
87
88 - (void) setMainText:(NSString *) text {
89         [_mainText autorelease];
90         _mainText = [text copy];
91 }
92
93 - (NSString *) mainText {
94         return _mainText;
95 }
96
97 #pragma mark -
98
99 - (void) setInformationText:(NSString *) text {
100         [_infoText autorelease];
101         _infoText = [text copy];
102 }
103
104 - (NSString *) informationText {
105         return _infoText;
106 }
107
108 #pragma mark -
109
110 - (void) setBoldAndWhiteOnHighlight:(BOOL) boldAndWhite {
111         _boldAndWhiteOnHighlight = boldAndWhite;
112 }
113
114 - (BOOL) boldAndWhiteOnHighlight {
115         return _boldAndWhiteOnHighlight;
116 }
117
118 #pragma mark -
119
120 - (void) drawWithFrame:(NSRect) cellFrame inView:(NSView *) controlView {
121         float imageWidth = 0.;
122         BOOL highlighted = ( [self isHighlighted] && [[controlView window] firstResponder] == controlView && [[controlView window] isKeyWindow] && [[NSApplication sharedApplication] isActive] );
123
124         NSMutableParagraphStyle *paraStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
125         [paraStyle setLineBreakMode:_lineBreakMode];
126         [paraStyle setAlignment:[self alignment]];
127
128         NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithObjectsAndKeys:[self font], NSFontAttributeName, paraStyle, NSParagraphStyleAttributeName, ( [self isEnabled] ? ( highlighted ? [NSColor alternateSelectedControlTextColor] : [NSColor controlTextColor] ) : ( highlighted ? [NSColor alternateSelectedControlTextColor] : [[NSColor controlTextColor] colorWithAlphaComponent:0.50] ) ), NSForegroundColorAttributeName, nil];
129         NSMutableDictionary *subAttributes = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSFont toolTipsFontOfSize:9.], NSFontAttributeName, paraStyle, NSParagraphStyleAttributeName, ( [self isEnabled] ? ( highlighted ? [NSColor alternateSelectedControlTextColor] : [[NSColor controlTextColor] colorWithAlphaComponent:0.75] ) : ( highlighted ? [NSColor alternateSelectedControlTextColor] : [[NSColor controlTextColor] colorWithAlphaComponent:0.40] ) ), NSForegroundColorAttributeName, nil];
130         NSImage *mainImage = nil, *curImage = nil;
131         NSSize mainStringSize = [_mainText sizeWithAttributes:attributes];
132         NSSize subStringSize = [_infoText sizeWithAttributes:subAttributes];
133
134         if( _boldAndWhiteOnHighlight && [self isHighlighted] ) {
135                 NSFont *boldFont = [[NSFontManager sharedFontManager] fontWithFamily:@"Lucida Grande" traits:0 weight:15 size:11.];
136                 NSShadow *shadow = [[NSShadow allocWithZone:nil] init];
137                 NSColor *whiteColor = [NSColor whiteColor];
138                 if( ! [self isEnabled] ) whiteColor = [whiteColor colorWithAlphaComponent:0.5];
139
140         [shadow setShadowOffset:NSMakeSize( 0, -1 )];
141                 [shadow setShadowBlurRadius:0.1];
142                 [shadow setShadowColor:[[NSColor shadowColor] colorWithAlphaComponent:0.2]];
143
144                 [attributes setObject:boldFont forKey:NSFontAttributeName];
145                 [attributes setObject:whiteColor forKey:NSForegroundColorAttributeName];
146                 [attributes setObject:shadow forKey:NSShadowAttributeName];
147
148                 boldFont = [[NSFontManager sharedFontManager] fontWithFamily:@"Lucida Grande" traits:0 weight:15 size:9.];
149                 [subAttributes setObject:boldFont forKey:NSFontAttributeName];
150                 [subAttributes setObject:whiteColor forKey:NSForegroundColorAttributeName];
151                 [subAttributes setObject:shadow forKey:NSShadowAttributeName];
152                 [shadow release];
153         }
154
155         if( highlighted && _altImage ) {
156                 mainImage = [[self image] retain];
157                 [self setImage:_altImage];
158         }
159
160         if( ! [self isEnabled] && [self image] ) {
161                 NSImage *fadedImage = [[[NSImage alloc] initWithSize:[[self image] size]] autorelease];
162                 [fadedImage lockFocus];
163                 [[self image] dissolveToPoint:NSMakePoint( 0., 0. ) fraction:0.5];
164                 [fadedImage unlockFocus];
165                 curImage = [[self image] retain];
166                 [self setImage:fadedImage];
167         }
168
169         cellFrame = NSMakeRect( cellFrame.origin.x + 1., cellFrame.origin.y, cellFrame.size.width - 1., cellFrame.size.height );
170         [super drawWithFrame:cellFrame inView:controlView];
171
172         if( ! [self isEnabled] ) {
173                 [self setImage:curImage];
174                 [curImage autorelease];
175         }
176
177         if( highlighted && mainImage ) {
178                 [self setImage:mainImage];
179                 [mainImage autorelease];
180         }
181
182         if( [self image] ) {
183                 switch( [self imageScaling] ) {
184                 case NSScaleProportionally:
185                         if( NSHeight( cellFrame ) < [[self image] size].height )
186                                 imageWidth = ( NSHeight( cellFrame ) / [[self image] size].height ) * [[self image] size].width;
187                         else imageWidth = [[self image] size].width;
188                         break;
189                 default:
190                 case NSScaleNone:
191                         imageWidth = [[self image] size].width;
192                         break;
193                 case NSScaleToFit:
194                         imageWidth = [[self image] size].width;
195                         break;
196                 }
197         }
198
199 #define JVDetailCellLabelPadding 3.
200 #define JVDetailCellImageLabelPadding 5.
201 #define JVDetailCellTextLeading 3.
202 #define JVDetailCellStatusImageLeftPadding 2.
203 #define JVDetailCellStatusImageRightPadding JVDetailCellStatusImageLeftPadding
204
205         float statusWidth = ( _statusImage ? [_statusImage size].width + JVDetailCellStatusImageRightPadding : 0. );
206         if( ! _statusImage && ( _statusNumber || _importantStatusNumber ) ) {
207                 NSColor *textColor = [NSColor whiteColor];
208                 NSColor *backgroundColor = [NSColor colorWithCalibratedRed:0.6 green:0.6705882352941176 blue:0.7725490196078431 alpha:1.];
209                 NSColor *importantColor = [NSColor colorWithCalibratedRed:0.831372549019608 green:0.572549019607843 blue:0.541176470588235 alpha:1.];
210
211                 if( ! _statusNumber && _importantStatusNumber )
212                         backgroundColor = importantColor;
213
214                 if( [self isHighlighted] ) {
215                         textColor = [backgroundColor shadowWithLevel:0.2];
216                         backgroundColor = [backgroundColor highlightWithLevel:0.7];
217                 }
218
219                 NSFont *font = [[NSFontManager sharedFontManager] fontWithFamily:@"Helvetica" traits:NSBoldFontMask weight:9 size:11.];
220                 NSMutableParagraphStyle *numberParaStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
221                 [numberParaStyle setAlignment:NSCenterTextAlignment];
222
223                 NSDictionary *statusNumberAttributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, numberParaStyle, NSParagraphStyleAttributeName, textColor, NSForegroundColorAttributeName, [NSNumber numberWithFloat:1.0], NSKernAttributeName, nil];
224
225                 NSString *statusText = [NSString stringWithFormat:@"%d", ( _statusNumber ? _statusNumber : _importantStatusNumber )];
226                 NSSize numberSize = [statusText sizeWithAttributes:statusNumberAttributes];
227                 statusWidth = numberSize.width + 12.;
228
229                 if( imageWidth + ( imageWidth ? JVDetailCellImageLabelPadding : JVDetailCellLabelPadding ) + statusWidth < NSWidth( cellFrame ) ) {
230                         float radius = ( _importantStatusNumber ? 8. : 7. );
231                         NSRect mainRect = NSMakeRect( NSMinX( cellFrame ) + NSWidth( cellFrame ) - statusWidth - 2., NSMinY( cellFrame ) + ( ( NSHeight( cellFrame ) / 2 ) - radius ), statusWidth, radius * 2 );
232                         NSRect pathRect = NSInsetRect( mainRect, radius, radius );
233
234                         NSBezierPath *mainPath = [NSBezierPath bezierPath];
235                         [mainPath appendBezierPathWithArcWithCenter:NSMakePoint( NSMinX( pathRect ), NSMinY( pathRect ) ) radius:radius startAngle:180. endAngle:270.];
236                         [mainPath appendBezierPathWithArcWithCenter:NSMakePoint( NSMaxX( pathRect ), NSMinY( pathRect ) ) radius:radius startAngle:270. endAngle:360.];
237                         [mainPath appendBezierPathWithArcWithCenter:NSMakePoint( NSMaxX( pathRect ), NSMaxY( pathRect ) ) radius:radius startAngle:0. endAngle:90.];
238                         [mainPath appendBezierPathWithArcWithCenter:NSMakePoint( NSMinX( pathRect ), NSMaxY( pathRect ) ) radius:radius startAngle:90. endAngle:180.];
239                         [mainPath closePath];
240
241                         if( _importantStatusNumber ) {
242                                 NSString *importantStatusText = [NSString stringWithFormat:@"%d", _importantStatusNumber];
243                                 numberSize = [importantStatusText sizeWithAttributes:statusNumberAttributes];
244                                 float mainStatusWidth = statusWidth;
245                                 statusWidth += numberSize.width + 10.;
246                                 radius = 7.;
247
248                                 NSRect rect = NSMakeRect( NSMinX( cellFrame ) + NSWidth( cellFrame ) - statusWidth - 2., NSMinY( cellFrame ) + ( ( NSHeight( cellFrame ) / 2 ) - radius ), statusWidth - mainStatusWidth + 10., radius * 2 );
249                                 pathRect = NSInsetRect( rect, radius, radius );
250
251                                 NSBezierPath *path = [NSBezierPath bezierPath];
252                                 [path appendBezierPathWithArcWithCenter:NSMakePoint( NSMinX( pathRect ), NSMinY( pathRect ) ) radius:radius startAngle:180. endAngle:270.];
253                                 [path appendBezierPathWithArcWithCenter:NSMakePoint( NSMaxX( pathRect ), NSMinY( pathRect ) ) radius:radius startAngle:270. endAngle:360.];
254                                 [path appendBezierPathWithArcWithCenter:NSMakePoint( NSMaxX( pathRect ), NSMaxY( pathRect ) ) radius:radius startAngle:0. endAngle:90.];
255                                 [path appendBezierPathWithArcWithCenter:NSMakePoint( NSMinX( pathRect ), NSMaxY( pathRect ) ) radius:radius startAngle:90. endAngle:180.];
256                                 [path closePath];
257
258                                 if( [self isHighlighted] ) [[NSColor whiteColor] set];
259                                 else [[NSColor colorWithCalibratedRed:0.92156862745098 green:0.231372549019608 blue:0.243137254901961 alpha:0.85] set];
260                                 [path fill];
261
262                                 rect.origin.x -= 3.;
263                                 [importantStatusText drawInRect:rect withAttributes:statusNumberAttributes];
264                         }
265
266                         [backgroundColor set];
267                         [mainPath fill];
268
269                         if( _importantStatusNumber ) {
270                                 if( [self isHighlighted] ) [[NSColor colorWithCalibratedRed:0.5803921568627451 green:0.6705882352941176 blue:0.7882352941176471 alpha:1.] set];
271                                 else [[NSColor whiteColor] set];
272
273                                 [mainPath setLineWidth:1.25];
274                                 [mainPath stroke];
275                         }
276
277                         if( _importantStatusNumber ) mainRect.origin.y += 1.;
278                         [statusText drawInRect:mainRect withAttributes:statusNumberAttributes];
279
280                         statusWidth += JVDetailCellStatusImageRightPadding + 3.;
281
282                 } else statusWidth = 0.;
283         }
284
285         if( ( ! [_infoText length] && [_mainText length] ) || ( ( subStringSize.height + mainStringSize.height ) >= NSHeight( cellFrame ) - 2. ) ) {
286                 float mainYLocation = 0.;
287
288                 if( NSHeight( cellFrame ) >= mainStringSize.height ) {
289                         mainYLocation = NSMinY( cellFrame ) + ( NSHeight( cellFrame ) / 2 ) - ( mainStringSize.height / 2 );
290                         [_mainText drawInRect:NSMakeRect( NSMinX( cellFrame ) + imageWidth + ( imageWidth ? JVDetailCellImageLabelPadding : JVDetailCellLabelPadding ), mainYLocation, NSWidth( cellFrame ) - imageWidth - ( JVDetailCellImageLabelPadding * 1. ) - statusWidth, [_mainText sizeWithAttributes:attributes].height ) withAttributes:attributes];
291                 }
292         } else if( [_infoText length] && [_mainText length] ) {
293                 float mainYLocation = 0., subYLocation = 0.;
294
295                 if( NSHeight( cellFrame ) >= mainStringSize.height ) {
296                         mainYLocation = NSMinY( cellFrame ) + ( NSHeight( cellFrame ) / 2 ) - mainStringSize.height + ( JVDetailCellTextLeading / 2. );
297                         [_mainText drawInRect:NSMakeRect( cellFrame.origin.x + imageWidth + ( imageWidth ? JVDetailCellImageLabelPadding : JVDetailCellLabelPadding ), mainYLocation, NSWidth( cellFrame ) - imageWidth - ( JVDetailCellImageLabelPadding * 1. ) - statusWidth, [_mainText sizeWithAttributes:attributes].height ) withAttributes:attributes];
298
299                         subYLocation = NSMinY( cellFrame ) + ( NSHeight( cellFrame ) / 2 ) + subStringSize.height - mainStringSize.height + ( JVDetailCellTextLeading / 2. );
300                         [_infoText drawInRect:NSMakeRect( NSMinX( cellFrame ) + imageWidth + ( imageWidth ? JVDetailCellImageLabelPadding : JVDetailCellLabelPadding ), subYLocation, NSWidth( cellFrame ) - imageWidth - ( JVDetailCellImageLabelPadding * 1. ) - statusWidth, [_infoText sizeWithAttributes:subAttributes].height ) withAttributes:subAttributes];
301                 }
302         }
303
304         if( _statusImage && NSHeight( cellFrame ) >= [_statusImage size].height ) {
305                 [_statusImage compositeToPoint:NSMakePoint( NSMinX( cellFrame ) + NSWidth( cellFrame ) - statusWidth, NSMaxY( cellFrame ) - ( ( NSHeight( cellFrame ) / 2 ) - ( [_statusImage size].height / 2 ) ) ) operation:NSCompositeSourceAtop fraction:( [self isEnabled] ? 1. : 0.5)];
306         }
307 }
308
309 #pragma mark -
310
311 - (void) setImageScaling:(NSImageScaling) newScaling {
312         [super setImageScaling:( newScaling == NSScaleProportionally || newScaling == NSScaleNone ? newScaling : NSScaleProportionally )];
313 }
314
315 - (void) setImageAlignment:(NSImageAlignment) newAlign {
316         [super setImageAlignment:NSImageAlignLeft];
317 }
318
319 - (void) setLineBreakMode:(NSLineBreakMode) mode {
320         _lineBreakMode = mode;
321 }
322
323 - (NSLineBreakMode) lineBreakMode {
324         return _lineBreakMode;
325 }
326
327 - (void) setStringValue:(NSString *) string {
328         [self setMainText:string];
329 }
330
331 - (void) setObjectValue:(id <NSCopying>) obj {
332         if( ! obj || [(NSObject *)obj isKindOfClass:[NSImage class]] ) {
333                 [super setObjectValue:obj];
334         } else if( [(NSObject *)obj isKindOfClass:[NSString class]] ) {
335                 [self setMainText:(NSString *)obj];
336         }
337 }
338
339 - (NSString *) stringValue {
340         return _mainText;
341 }
342 @end
Note: See TracBrowser for help on using the browser.