source: trunk/macosx/TorrentCell.m @ 4232

Last change on this file since 4232 was 4232, checked in by livings124, 15 years ago

remove unused variables

  • Property svn:keywords set to Date Rev Author Id
File size: 21.8 KB
Line 
1/******************************************************************************
2 * $Id: TorrentCell.m 4232 2007-12-20 01:15:13Z livings124 $
3 *
4 * Copyright (c) 2006-2007 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#import "TorrentCell.h"
26#import "TorrentTableView.h"
27#import "GroupsWindowController.h"
28#import "NSApplicationAdditions.h"
29#import "NSStringAdditions.h"
30#import "NSBezierPathAdditions.h"
31#import "CTGradientAdditions.h"
32
33#define BAR_HEIGHT 12.0
34
35#define IMAGE_SIZE_REG 32.0
36#define IMAGE_SIZE_MIN 16.0
37
38//end up being larger than font height
39#define HEIGHT_TITLE 16.0
40#define HEIGHT_STATUS 12.0
41
42#define PADDING_HORIZONAL 2.0
43#define PADDING_ABOVE_IMAGE_REG 9.0
44#define PADDING_BETWEEN_IMAGE_AND_TITLE 5.0
45#define PADDING_BETWEEN_IMAGE_AND_BAR 7.0
46#define PADDING_ABOVE_TITLE 3.0
47#define PADDING_ABOVE_MIN_STATUS 4.0
48#define PADDING_BETWEEN_TITLE_AND_MIN_STATUS 2.0
49#define PADDING_BETWEEN_TITLE_AND_PROGRESS 1.0
50#define PADDING_BETWEEN_PROGRESS_AND_BAR 2.0
51#define PADDING_BETWEEN_TITLE_AND_BAR_MIN 3.0
52#define PADDING_BETWEEN_BAR_AND_STATUS 2.0
53
54#define WIDTH_GROUP 40.0
55#define WIDTH_GROUP_MIN 24.0
56
57#define MAX_PIECES 324
58#define BLANK_PIECE -99
59
60@interface TorrentCell (Private)
61
62- (void) drawBar: (NSRect) barRect;
63- (void) drawRegularBar: (NSRect) barRect;
64- (void) drawPiecesBar: (NSRect) barRect;
65
66- (NSRect) rectForMinimalStatusWithString: (NSAttributedString *) string inBounds: (NSRect) bounds;
67- (NSRect) rectForTitleWithString: (NSAttributedString *) string basedOnMinimalStatusRect: (NSRect) statusRect
68            inBounds: (NSRect) bounds;
69- (NSRect) rectForProgressWithString: (NSAttributedString *) string inBounds: (NSRect) bounds;
70- (NSRect) rectForStatusWithString: (NSAttributedString *) string inBounds: (NSRect) bounds;
71
72- (NSAttributedString *) attributedTitleWithColor: (NSColor *) color;
73- (NSAttributedString *) attributedStatusString: (NSString *) string withColor: (NSColor *) color;
74
75@end
76
77@implementation TorrentCell
78
79//only called once, so don't worry about releasing
80- (id) init
81{
82    if ((self = [super init]))
83        {
84        fDefaults = [NSUserDefaults standardUserDefaults];
85       
86        NSMutableParagraphStyle * paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
87        [paragraphStyle setLineBreakMode: NSLineBreakByTruncatingTail];
88   
89        fTitleAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
90                                [NSFont messageFontOfSize: 12.0], NSFontAttributeName,
91                                paragraphStyle, NSParagraphStyleAttributeName, nil];
92        fStatusAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
93                                [NSFont messageFontOfSize: 9.0], NSFontAttributeName,
94                                paragraphStyle, NSParagraphStyleAttributeName, nil];
95        [paragraphStyle release];
96       
97        //store box colors
98        fGrayColor = [[NSColor colorWithCalibratedRed: 0.9 green: 0.9 blue: 0.9 alpha: 1.0] retain];
99        fBlue1Color = [[NSColor colorWithCalibratedRed: 0.8 green: 1.0 blue: 1.0 alpha: 1.0] retain];
100        fBlue2Color = [[NSColor colorWithCalibratedRed: 0.6 green: 1.0 blue: 1.0 alpha: 1.0] retain];
101        fBlue3Color = [[NSColor colorWithCalibratedRed: 0.6 green: 0.8 blue: 1.0 alpha: 1.0] retain];
102        fBlue4Color = [[NSColor colorWithCalibratedRed: 0.4 green: 0.6 blue: 1.0 alpha: 1.0] retain];
103        fBlueColor = [[NSColor colorWithCalibratedRed: 0.0 green: 0.4 blue: 0.8 alpha: 1.0] retain];
104       
105        fBarOverlayColor = [[NSColor colorWithDeviceWhite: 0.0 alpha: 0.2] retain];
106    }
107        return self;
108}
109
110- (id) copyWithZone: (NSZone *) zone
111{
112    TorrentCell * copy = [super copyWithZone: zone];
113   
114    copy->fBitmap = nil;
115    copy->fPieces = NULL;
116   
117    return copy;
118}
119
120- (void) dealloc
121{
122    [fBitmap release];
123    if (fPieces)
124        free(fPieces);
125   
126    [super dealloc];
127}
128
129- (NSRect) iconRectForBounds: (NSRect) bounds
130{
131    NSRect result = bounds;
132   
133    result.origin.x += PADDING_HORIZONAL;
134   
135    float imageSize;
136    if ([fDefaults boolForKey: @"SmallView"])
137    {
138        imageSize = IMAGE_SIZE_MIN;
139        result.origin.y += (result.size.height - imageSize) * 0.5;
140    }
141    else
142    {
143        imageSize = IMAGE_SIZE_REG;
144        result.origin.y += PADDING_ABOVE_IMAGE_REG;
145    }
146   
147    result.size = NSMakeSize(imageSize, imageSize);
148   
149    return result;
150}
151
152- (NSRect) titleRectForBounds: (NSRect) bounds
153{
154    return [self rectForTitleWithString: [self attributedTitleWithColor: nil]
155            basedOnMinimalStatusRect: [self minimalStatusRectForBounds: bounds] inBounds: bounds];
156}
157
158- (NSRect) minimalStatusRectForBounds: (NSRect) bounds
159{
160    Torrent * torrent = [self representedObject];
161    NSString * string = [fDefaults boolForKey: @"DisplaySmallStatusRegular"]
162                            ? [torrent shortStatusString] : [torrent remainingTimeString];
163    return [self rectForMinimalStatusWithString: [self attributedStatusString: string withColor: nil] inBounds: bounds];
164}
165
166- (NSRect) progressRectForBounds: (NSRect) bounds
167{
168    return [self rectForProgressWithString: [self attributedStatusString: [[self representedObject] progressString] withColor: nil]
169                    inBounds: bounds];
170}
171
172- (NSRect) barRectForBounds: (NSRect) bounds
173{
174    BOOL minimal = [fDefaults boolForKey: @"SmallView"];
175   
176    NSRect result = bounds;
177    result.size.height = BAR_HEIGHT;
178    result.origin.x = PADDING_HORIZONAL + (minimal ? IMAGE_SIZE_MIN : IMAGE_SIZE_REG) + PADDING_BETWEEN_IMAGE_AND_BAR;
179   
180    result.origin.y += PADDING_ABOVE_TITLE + HEIGHT_TITLE;
181    if (minimal)
182        result.origin.y += PADDING_BETWEEN_TITLE_AND_BAR_MIN;
183    else
184        result.origin.y += PADDING_BETWEEN_TITLE_AND_PROGRESS + HEIGHT_STATUS + PADDING_BETWEEN_PROGRESS_AND_BAR;
185   
186    result.size.width = round(NSMaxX(bounds) - result.origin.x - PADDING_HORIZONAL - BUTTONS_TOTAL_WIDTH);
187   
188    return result;
189}
190
191- (NSRect) statusRectForBounds: (NSRect) bounds
192{
193    return [self rectForStatusWithString: [self attributedStatusString: [[self representedObject] statusString] withColor: nil]
194                    inBounds: bounds];
195}
196
197- (NSUInteger) hitTestForEvent: (NSEvent *) event inRect: (NSRect) cellFrame ofView: (NSView *) controlView
198{
199    return NSCellHitContentArea;
200}
201
202- (void) drawWithFrame: (NSRect) cellFrame inView: (NSView *) controlView
203{
204    [super drawWithFrame: cellFrame inView: controlView];
205   
206    Torrent * torrent = [self representedObject];
207   
208    BOOL minimal = [fDefaults boolForKey: @"SmallView"];
209   
210    //group coloring
211    NSRect iconRect = [self iconRectForBounds: cellFrame];
212   
213    int groupValue = [torrent groupValue];
214    if (groupValue != -1)
215    {
216        NSRect groupRect = NSInsetRect(iconRect, -2.0, -3.0);
217        if (!minimal)
218        {
219            groupRect.size.height--;
220            groupRect.origin.y--;
221        }
222       
223        [[[GroupsWindowController groupsController] gradientForIndex: groupValue] fillBezierPath:
224            [NSBezierPath bezierPathWithRoundedRect: groupRect radius: 6.0] angle: 90.0];
225    }
226   
227    //error image
228    BOOL error = [torrent isError];
229    if (error && !fErrorImage)
230    {
231        fErrorImage = [[NSImage imageNamed: @"Error.png"] copy];
232        [fErrorImage setFlipped: YES];
233    }
234   
235    //icon
236    NSImage * icon = minimal && error ? fErrorImage : [torrent icon];
237    [icon drawInRect: iconRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0];
238   
239    if (error && !minimal)
240    {
241        NSRect errorRect = NSMakeRect(NSMaxX(iconRect) - IMAGE_SIZE_MIN, NSMaxY(iconRect) - IMAGE_SIZE_MIN,
242                                        IMAGE_SIZE_MIN, IMAGE_SIZE_MIN);
243        [fErrorImage drawInRect: errorRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0];
244    }
245   
246    //text color
247    NSColor * titleColor, * statusColor;
248    if ([NSApp isOnLeopardOrBetter] ? [self backgroundStyle] == NSBackgroundStyleDark : [self isHighlighted]
249        && [[self highlightColorWithFrame: cellFrame inView: controlView] isEqual: [NSColor alternateSelectedControlColor]])
250    {
251        titleColor = [NSColor whiteColor];
252        statusColor = [NSColor whiteColor];
253    }
254    else
255    {
256        titleColor = [NSColor controlTextColor];
257        statusColor = [NSColor darkGrayColor];
258    }
259   
260    //minimal status
261    NSRect minimalStatusRect;
262    if (minimal)
263    {
264        NSString * string = [fDefaults boolForKey: @"DisplaySmallStatusRegular"]
265                            ? [torrent shortStatusString] : [torrent remainingTimeString];
266        NSAttributedString * minimalString = [self attributedStatusString: string withColor: statusColor];
267        minimalStatusRect = [self rectForMinimalStatusWithString: minimalString inBounds: cellFrame];
268       
269        [minimalString drawInRect: minimalStatusRect];
270    }
271   
272    //title
273    NSAttributedString * titleString = [self attributedTitleWithColor: titleColor];
274    NSRect titleRect = [self rectForTitleWithString: titleString basedOnMinimalStatusRect: minimalStatusRect inBounds: cellFrame];
275    [titleString drawInRect: titleRect];
276   
277    //progress
278    if (!minimal)
279    {
280        NSAttributedString * progressString = [self attributedStatusString: [torrent progressString] withColor: statusColor];
281        NSRect progressRect = [self rectForProgressWithString: progressString inBounds: cellFrame];
282        [progressString drawInRect: progressRect];
283    }
284   
285    //bar
286    [self drawBar: [self barRectForBounds: cellFrame]];
287   
288    //status
289    if (!minimal)
290    {
291        NSAttributedString * statusString = [self attributedStatusString: [torrent statusString] withColor: statusColor];
292        [statusString drawInRect: [self rectForStatusWithString: statusString inBounds: cellFrame]];
293    }
294}
295
296@end
297
298@implementation TorrentCell (Private)
299
300- (void) drawBar: (NSRect) barRect
301{
302    if ([fDefaults boolForKey: @"PiecesBar"])
303    {
304        NSRect regularBarRect = barRect, piecesBarRect = barRect;
305        regularBarRect.size.height /= 2.5;
306        piecesBarRect.origin.y += regularBarRect.size.height;
307        piecesBarRect.size.height -= regularBarRect.size.height;
308       
309        [self drawRegularBar: regularBarRect];
310        [self drawPiecesBar: piecesBarRect];
311    }
312    else
313    {
314        if (fPieces)
315        {
316            free(fPieces);
317            fPieces = NULL;
318            [fBitmap release];
319            fBitmap = nil;
320        }
321       
322        [self drawRegularBar: barRect];
323    }
324   
325    [fBarOverlayColor set];
326    [NSBezierPath strokeRect: NSInsetRect(barRect, 0.5, 0.5)];
327}
328
329- (void) drawRegularBar: (NSRect) barRect
330{
331    Torrent * torrent = [self representedObject];
332   
333    int leftWidth = barRect.size.width;
334    float progress = [torrent progress];
335   
336    if (progress < 1.0)
337    {
338        float rightProgress = 1.0 - progress, progressLeft = [torrent progressLeft];
339        int rightWidth = leftWidth * rightProgress;
340        leftWidth -= rightWidth;
341       
342        if (progressLeft < rightProgress)
343        {
344            int rightNoIncludeWidth = rightWidth * ((rightProgress - progressLeft) / rightProgress);
345            rightWidth -= rightNoIncludeWidth;
346           
347            NSRect noIncludeRect = barRect;
348            noIncludeRect.origin.x += barRect.size.width - rightNoIncludeWidth;
349            noIncludeRect.size.width = rightNoIncludeWidth;
350           
351            if (!fLightGrayGradient)
352                fLightGrayGradient = [[CTGradient progressLightGrayGradient] retain];
353            [fLightGrayGradient fillRect: noIncludeRect angle: -90];
354        }
355       
356        if (rightWidth > 0)
357        {
358            if ([torrent isActive] && ![torrent allDownloaded] && [fDefaults boolForKey: @"DisplayProgressBarAvailable"])
359            {
360                int notAvailableWidth = MIN(barRect.size.width * [torrent notAvailableDesired], rightWidth);
361                rightWidth -= notAvailableWidth;
362               
363                if (notAvailableWidth > 0)
364                {
365                    NSRect notAvailableRect = barRect;
366                    notAvailableRect.origin.x += leftWidth + rightWidth;
367                    notAvailableRect.size.width = notAvailableWidth;
368                   
369                    if (!fRedGradient)
370                        fRedGradient = [[CTGradient progressRedGradient] retain];
371                    [fRedGradient fillRect: notAvailableRect angle: -90];
372                }
373            }
374           
375            if (rightWidth > 0)
376            {
377                NSRect includeRect = barRect;
378                includeRect.origin.x += leftWidth;
379                includeRect.size.width = rightWidth;
380               
381                if (!fWhiteGradient)
382                    fWhiteGradient = [[CTGradient progressWhiteGradient] retain];
383                [fWhiteGradient fillRect: includeRect angle: -90];
384            }
385        }
386    }
387   
388    if (leftWidth > 0)
389    {
390        NSRect completeRect = barRect;
391        completeRect.size.width = leftWidth;
392       
393        if ([torrent isActive])
394        {
395            if ([torrent isChecking])
396            {
397                if (!fYellowGradient)
398                    fYellowGradient = [[CTGradient progressYellowGradient] retain];
399                [fYellowGradient fillRect: completeRect angle: -90];
400            }
401            else if ([torrent isSeeding])
402            {
403                int ratioLeftWidth = leftWidth * (1.0 - [torrent progressStopRatio]);
404                leftWidth -= ratioLeftWidth;
405               
406                if (ratioLeftWidth > 0)
407                {
408                    NSRect ratioLeftRect = barRect;
409                    ratioLeftRect.origin.x += leftWidth;
410                    ratioLeftRect.size.width = ratioLeftWidth;
411                   
412                    if (!fLightGreenGradient)
413                        fLightGreenGradient = [[CTGradient progressLightGreenGradient] retain];
414                    [fLightGreenGradient fillRect: ratioLeftRect angle: -90];
415                }
416               
417                if (leftWidth > 0)
418                {
419                    completeRect.size.width = leftWidth;
420                   
421                    if (!fGreenGradient)
422                        fGreenGradient = [[CTGradient progressGreenGradient] retain];
423                    [fGreenGradient fillRect: completeRect angle: -90];
424                }
425            }
426            else
427            {
428                if (!fBlueGradient)
429                    fBlueGradient = [[CTGradient progressBlueGradient] retain];
430                [fBlueGradient fillRect: completeRect angle: -90];
431            }
432        }
433        else
434        {
435            if ([torrent waitingToStart])
436            {
437                if ([torrent progressLeft] <= 0.0)
438                {
439                    if (!fDarkGreenGradient)
440                        fDarkGreenGradient = [[CTGradient progressDarkGreenGradient] retain];
441                    [fDarkGreenGradient fillRect: completeRect angle: -90];
442                }
443                else
444                {
445                    if (!fDarkBlueGradient)
446                        fDarkBlueGradient = [[CTGradient progressDarkBlueGradient] retain];
447                    [fDarkBlueGradient fillRect: completeRect angle: -90];
448                }
449            }
450            else
451            {
452                if (!fGrayGradient)
453                    fGrayGradient = [[CTGradient progressGrayGradient] retain];
454                [fGrayGradient fillRect: completeRect angle: -90];
455            }
456        }
457    }
458}
459
460- (void) drawPiecesBar: (NSRect) barRect
461{
462    if (!fBitmap)
463        fBitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: nil
464            pixelsWide: MAX_PIECES pixelsHigh: barRect.size.height bitsPerSample: 8 samplesPerPixel: 4 hasAlpha: YES
465            isPlanar: NO colorSpaceName: NSCalibratedRGBColorSpace bytesPerRow: 0 bitsPerPixel: 0];
466   
467    if (!fPieces)
468    {
469        fPieces = malloc(MAX_PIECES);
470        int i;
471        for (i = 0; i < MAX_PIECES; i++)
472            fPieces[i] = BLANK_PIECE;
473    }
474   
475    #warning add flashing orange
476   
477    Torrent * torrent = [self representedObject];
478   
479    int pieceCount = MIN([torrent pieceCount], MAX_PIECES);
480    float * piecePercent = malloc(pieceCount * sizeof(float));
481    [torrent getAmountFinished: piecePercent size: pieceCount];
482   
483    int i, h, index;
484    float increment = (float)pieceCount / MAX_PIECES;
485    NSColor * pieceColor;
486    for (i = 0; i < MAX_PIECES; i++)
487    {
488        index = i * increment;
489        pieceColor = nil;
490       
491        if (piecePercent[index] >= 1.0)
492        {
493            if (fPieces[i] != -1)
494            {
495                pieceColor = fBlueColor;
496                fPieces[i] = -1;
497            }
498        }
499        else if (piecePercent[index] <= 0.0)
500        {
501            if (fPieces[i] != 0)
502            {
503                pieceColor = fGrayColor;
504                fPieces[i] = 0;
505            }
506        }
507        else if (piecePercent[index] <= 0.25)
508        {
509            if (fPieces[i] != 1)
510            {
511                pieceColor = fBlue1Color;
512                fPieces[i] = 1;
513            }
514        }
515        else if (piecePercent[index] <= 0.5)
516        {
517            if (fPieces[i] != 2)
518            {
519                pieceColor = fBlue2Color;
520                fPieces[i] = 2;
521            }
522        }
523        else if (piecePercent[index] <= 0.75)
524        {
525            if (fPieces[i] != 3)
526            {
527                pieceColor = fBlue3Color;
528                fPieces[i] = 3;
529            }
530        }
531        else
532        {
533            if (fPieces[i] != 4)
534            {
535                pieceColor = fBlue4Color;
536                fPieces[i] = 4;
537            }
538        }
539       
540        if (pieceColor)
541            for (h = 0; h < barRect.size.height; h++)
542                [fBitmap setColor: pieceColor atX: i y: h];
543    }
544   
545    free(piecePercent);
546   
547    //actually draw image
548    [fBitmap drawInRect: barRect];
549   
550    if (!fTransparentGradient)
551        fTransparentGradient = [[CTGradient progressTransparentGradient] retain];
552    [fTransparentGradient fillRect: barRect angle: -90];
553}
554
555- (NSRect) rectForMinimalStatusWithString: (NSAttributedString *) string inBounds: (NSRect) bounds
556{
557    if (![fDefaults boolForKey: @"SmallView"])
558        return NSZeroRect;
559   
560    NSRect result = bounds;
561    result.size = [string size];
562   
563    result.origin.x += bounds.size.width - result.size.width - PADDING_HORIZONAL;
564    result.origin.y += PADDING_ABOVE_MIN_STATUS;
565   
566    return result;
567}
568
569- (NSRect) rectForTitleWithString: (NSAttributedString *) string basedOnMinimalStatusRect: (NSRect) statusRect
570            inBounds: (NSRect) bounds
571{
572    BOOL minimal = [fDefaults boolForKey: @"SmallView"];
573   
574    NSRect result = bounds;
575    result.origin.y += PADDING_ABOVE_TITLE;
576    result.origin.x += PADDING_HORIZONAL + (minimal ? IMAGE_SIZE_MIN : IMAGE_SIZE_REG) + PADDING_BETWEEN_IMAGE_AND_TITLE;
577   
578    result.size = [string size];
579    result.size.width = MIN(result.size.width, NSMaxX(bounds) - result.origin.x - PADDING_HORIZONAL
580                            - (minimal ? PADDING_BETWEEN_TITLE_AND_MIN_STATUS + statusRect.size.width : 0));
581   
582    return result;
583}
584
585- (NSRect) rectForProgressWithString: (NSAttributedString *) string inBounds: (NSRect) bounds
586{
587    if ([fDefaults boolForKey: @"SmallView"])
588        return NSZeroRect;
589   
590    NSRect result = bounds;
591    result.origin.y += PADDING_ABOVE_TITLE + HEIGHT_TITLE + PADDING_BETWEEN_TITLE_AND_PROGRESS;
592    result.origin.x += PADDING_HORIZONAL + IMAGE_SIZE_REG + PADDING_BETWEEN_IMAGE_AND_TITLE;
593   
594    result.size = [string size];
595    result.size.width = MIN(result.size.width, NSMaxX(bounds) - result.origin.x - PADDING_HORIZONAL);
596   
597    return result;
598}
599
600- (NSRect) rectForStatusWithString: (NSAttributedString *) string inBounds: (NSRect) bounds
601{
602    if ([fDefaults boolForKey: @"SmallView"])
603        return NSZeroRect;
604   
605    NSRect result = bounds;
606    result.origin.y += PADDING_ABOVE_TITLE + HEIGHT_TITLE + PADDING_BETWEEN_TITLE_AND_PROGRESS + HEIGHT_STATUS
607                        + PADDING_BETWEEN_PROGRESS_AND_BAR + BAR_HEIGHT + PADDING_BETWEEN_BAR_AND_STATUS;
608    result.origin.x += PADDING_HORIZONAL + IMAGE_SIZE_REG + PADDING_BETWEEN_IMAGE_AND_TITLE;
609   
610    result.size = [string size];
611    result.size.width = MIN(result.size.width, NSMaxX(bounds) - result.origin.x - PADDING_HORIZONAL);
612   
613    return result;
614}
615
616- (NSAttributedString *) attributedTitleWithColor: (NSColor *) color
617{
618    if (color)
619        [fTitleAttributes setObject: color forKey: NSForegroundColorAttributeName];
620   
621    NSString * title = [[self representedObject] name];
622    return [[[NSAttributedString alloc] initWithString: title attributes: fTitleAttributes] autorelease];
623}
624
625- (NSAttributedString *) attributedStatusString: (NSString *) string withColor: (NSColor *) color
626{
627    if (color)
628        [fStatusAttributes setObject: color forKey: NSForegroundColorAttributeName];
629   
630    return [[[NSAttributedString alloc] initWithString: string attributes: fStatusAttributes] autorelease];
631}
632
633@end
Note: See TracBrowser for help on using the repository browser.