source: trunk/macosx/TorrentCell.m @ 3410

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

add a warning and improve some commented out code....nothing to see here

  • Property svn:keywords set to Date Rev Author Id
File size: 16.8 KB
Line 
1/******************************************************************************
2 * $Id: TorrentCell.m 3410 2007-10-14 14:24:34Z 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 "NSStringAdditions.h"
28#import "CTGradientAdditions.h"
29
30#define BAR_HEIGHT 12.0
31
32#define IMAGE_SIZE_REG 32.0
33#define IMAGE_SIZE_MIN 16.0
34
35//end up being larger than font height
36#define HEIGHT_TITLE 16.0
37#define HEIGHT_STATUS 12.0
38
39#define PADDING_HORIZONAL 2.0
40#define PADDING_ABOVE_IMAGE_REG 9.0
41#define PADDING_BETWEEN_IMAGE_AND_TITLE 5.0
42#define PADDING_BETWEEN_IMAGE_AND_BAR 7.0
43#define PADDING_ABOVE_TITLE 3.0
44#define PADDING_ABOVE_MIN_STATUS 4.0
45#define PADDING_BETWEEN_TITLE_AND_MIN_STATUS 2.0
46#define PADDING_BETWEEN_TITLE_AND_PROGRESS 1.0
47#define PADDING_BETWEEN_PROGRESS_AND_BAR 2.0
48#define PADDING_BETWEEN_TITLE_AND_BAR_MIN 3.0
49#define PADDING_BETWEEN_BAR_AND_STATUS 2.0
50
51@interface TorrentCell (Private)
52
53- (void) drawBar: (NSRect) barRect;
54
55- (NSRect) rectForMinimalStatusWithString: (NSAttributedString *) string inBounds: (NSRect) bounds;
56- (NSRect) rectForTitleWithString: (NSAttributedString *) string basedOnMinimalStatusRect: (NSRect) statusRect
57            inBounds: (NSRect) bounds;
58- (NSRect) rectForProgressWithString: (NSAttributedString *) string inBounds: (NSRect) bounds;
59- (NSRect) rectForStatusWithString: (NSAttributedString *) string inBounds: (NSRect) bounds;
60
61- (NSAttributedString *) attributedTitleWithColor: (NSColor *) color;
62- (NSAttributedString *) attributedStatusString: (NSString *) string withColor: (NSColor *) color;
63
64@end
65
66@implementation TorrentCell
67
68//only called one, so don't worry about release
69- (id) init
70{
71    if ((self = [super init]))
72        {
73        fDefaults = [NSUserDefaults standardUserDefaults];
74       
75        NSMutableParagraphStyle * paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
76        [paragraphStyle setLineBreakMode: NSLineBreakByTruncatingTail];
77   
78        fTitleAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
79                                [NSFont messageFontOfSize: 12.0], NSFontAttributeName,
80                                paragraphStyle, NSParagraphStyleAttributeName, nil];
81        fStatusAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
82                                [NSFont messageFontOfSize: 9.0], NSFontAttributeName,
83                                paragraphStyle, NSParagraphStyleAttributeName, nil];
84        [paragraphStyle release];
85       
86        fBarOverlayColor = [[NSColor colorWithDeviceWhite: 0.0 alpha: 0.2] retain];
87    }
88        return self;
89}
90
91- (NSRect) iconRectForBounds: (NSRect) bounds
92{
93    NSRect result = bounds;
94   
95    result.origin.x += PADDING_HORIZONAL;
96   
97    float imageSize;
98    if ([fDefaults boolForKey: @"SmallView"])
99    {
100        imageSize = IMAGE_SIZE_MIN;
101        result.origin.y += (result.size.height - imageSize) * 0.5;
102    }
103    else
104    {
105        imageSize = IMAGE_SIZE_REG;
106        result.origin.y += PADDING_ABOVE_IMAGE_REG;
107    }
108   
109    result.size = NSMakeSize(imageSize, imageSize);
110   
111    return result;
112}
113
114- (NSRect) titleRectForBounds: (NSRect) bounds
115{
116    return [self rectForTitleWithString: [self attributedTitleWithColor: nil]
117            basedOnMinimalStatusRect: [self minimalStatusRectForBounds: bounds] inBounds: bounds];
118}
119
120- (NSRect) minimalStatusRectForBounds: (NSRect) bounds
121{
122    Torrent * torrent = [self representedObject];
123    NSString * string = [fDefaults boolForKey: @"DisplaySmallStatusRegular"]
124                            ? [torrent shortStatusString] : [torrent remainingTimeString];
125    return [self rectForMinimalStatusWithString: [self attributedStatusString: string withColor: nil] inBounds: bounds];
126}
127
128- (NSRect) progressRectForBounds: (NSRect) bounds
129{
130    return [self rectForProgressWithString: [self attributedStatusString: [[self representedObject] progressString] withColor: nil]
131                    inBounds: bounds];
132}
133
134- (NSRect) barRectForBounds: (NSRect) bounds
135{
136    BOOL minimal = [fDefaults boolForKey: @"SmallView"];
137   
138    NSRect result = bounds;
139    result.size.height = BAR_HEIGHT;
140    result.origin.x = PADDING_HORIZONAL + (minimal ? IMAGE_SIZE_MIN : IMAGE_SIZE_REG) + PADDING_BETWEEN_IMAGE_AND_BAR;
141   
142    result.origin.y += PADDING_ABOVE_TITLE + HEIGHT_TITLE;
143    if (minimal)
144        result.origin.y += PADDING_BETWEEN_TITLE_AND_BAR_MIN;
145    else
146        result.origin.y += PADDING_BETWEEN_TITLE_AND_PROGRESS + HEIGHT_STATUS + PADDING_BETWEEN_PROGRESS_AND_BAR;
147   
148    result.size.width = round(NSMaxX(bounds) - result.origin.x - PADDING_HORIZONAL - BUTTONS_TOTAL_WIDTH);
149   
150    return result;
151}
152
153- (NSRect) statusRectForBounds: (NSRect) bounds
154{
155    return [self rectForStatusWithString: [self attributedStatusString: [[self representedObject] statusString] withColor: nil]
156                    inBounds: bounds];
157}
158
159- (void) drawInteriorWithFrame: (NSRect) cellFrame inView: (NSView *) controlView
160{
161    [super drawInteriorWithFrame: cellFrame inView: controlView];
162   
163    Torrent * torrent = [self representedObject];
164   
165    BOOL minimal = [fDefaults boolForKey: @"SmallView"];
166   
167    //error image
168    BOOL error = [torrent isError];
169    if (error && !fErrorImage)
170    {
171        fErrorImage = [[NSImage imageNamed: @"Error.png"] copy];
172        [fErrorImage setFlipped: YES];
173    }
174   
175    //icon
176    NSImage * icon = minimal && error ? fErrorImage : [torrent icon];
177    NSRect iconRect = [self iconRectForBounds: cellFrame];
178    [icon drawInRect: iconRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0];
179   
180    if (error && !minimal)
181    {
182        NSRect errorRect = NSMakeRect(NSMaxX(iconRect) - IMAGE_SIZE_MIN, NSMaxY(iconRect) - IMAGE_SIZE_MIN,
183                                        IMAGE_SIZE_MIN, IMAGE_SIZE_MIN);
184        [fErrorImage drawInRect: errorRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0];
185    }
186   
187    //text color
188    NSColor * titleColor, * statusColor;
189    if ([self isHighlighted]
190            && [[self highlightColorWithFrame: cellFrame inView: controlView] isEqual: [NSColor alternateSelectedControlColor]])
191    {
192        titleColor = [NSColor whiteColor];
193        statusColor = [NSColor whiteColor];
194    }
195    else
196    {
197        titleColor = [NSColor controlTextColor];
198        statusColor = [NSColor darkGrayColor];
199    }
200   
201    //minimal status
202    NSRect minimalStatusRect;
203    if (minimal)
204    {
205        NSString * string = [fDefaults boolForKey: @"DisplaySmallStatusRegular"]
206                            ? [torrent shortStatusString] : [torrent remainingTimeString];
207        NSAttributedString * minimalString = [self attributedStatusString: string withColor: statusColor];
208        minimalStatusRect = [self rectForMinimalStatusWithString: minimalString inBounds: cellFrame];
209       
210        [minimalString drawInRect: minimalStatusRect];
211    }
212   
213    //title
214    NSAttributedString * titleString = [self attributedTitleWithColor: titleColor];
215    NSRect titleRect = [self rectForTitleWithString: titleString basedOnMinimalStatusRect: minimalStatusRect inBounds: cellFrame];
216    [titleString drawInRect: titleRect];
217   
218    //progress
219    if (!minimal)
220    {
221        NSAttributedString * progressString = [self attributedStatusString: [torrent progressString] withColor: statusColor];
222        NSRect progressRect = [self rectForProgressWithString: progressString inBounds: cellFrame];
223        [progressString drawInRect: progressRect];
224    }
225   
226    //bar
227    NSRect barRect = [self barRectForBounds: cellFrame];
228    [self drawBar: barRect];
229   
230    //status
231    if (!minimal)
232    {
233        NSAttributedString * statusString = [self attributedStatusString: [torrent statusString] withColor: statusColor];
234        [statusString drawInRect: [self rectForStatusWithString: statusString inBounds: cellFrame]];
235    }
236}
237
238@end
239
240@implementation TorrentCell (Private)
241
242- (void) drawBar: (NSRect) barRect
243{
244    Torrent * torrent = [self representedObject];
245   
246    int leftWidth = barRect.size.width;
247    float progress = [torrent progress];
248   
249    if (progress < 1.0)
250    {
251        float rightProgress = 1.0 - progress, progressLeft = [torrent progressLeft];
252        int rightWidth = leftWidth * rightProgress;
253        leftWidth -= rightWidth;
254       
255        if (progressLeft < rightProgress)
256        {
257            int rightNoIncludeWidth = rightWidth * ((rightProgress - progressLeft) / rightProgress);
258            rightWidth -= rightNoIncludeWidth;
259           
260            NSRect noIncludeRect = barRect;
261            noIncludeRect.origin.x += barRect.size.width - rightNoIncludeWidth;
262            noIncludeRect.size.width = rightNoIncludeWidth;
263           
264            if (!fLightGrayGradient)
265                fLightGrayGradient = [[CTGradient progressLightGrayGradient] retain];
266            [fLightGrayGradient fillRect: noIncludeRect angle: -90];
267        }
268       
269        if (rightWidth > 0)
270        {
271            int availableWidth = 0;
272            /*if (![fDefaults boolForKey: @"DisplayProgressBarAvailable"])
273            {
274                //NSLog(@"notAvailableWidth %d rightWidth %d", notAvailableWidth, rightWidth);
275                availableWidth = MAX(0, (float)rightWidth - barRect.size.width * [torrent notAvailableDesired]);
276               
277                if (availableWidth > 0)
278                {
279                    rightWidth -= availableWidth;
280                   
281                    NSRect availableRect = barRect;
282                    availableRect.origin.x += leftWidth;
283                    availableRect.size.width = availableWidth;
284                   
285                    if (!fYellowGradient)
286                        fYellowGradient = [[CTGradient progressYellowGradient] retain];
287                    [fYellowGradient fillRect: availableRect angle: -90];
288                }
289            }*/
290           
291            if (rightWidth > 0)
292            {
293                NSRect includeRect = barRect;
294                includeRect.origin.x += leftWidth + availableWidth;
295                includeRect.size.width = rightWidth;
296               
297                if (!fWhiteGradient)
298                    fWhiteGradient = [[CTGradient progressWhiteGradient] retain];
299                [fWhiteGradient fillRect: includeRect angle: -90];
300            }
301        }
302    }
303   
304    if (leftWidth > 0)
305    {
306        NSRect completeRect = barRect;
307        completeRect.size.width = leftWidth;
308       
309        if ([torrent isActive])
310        {
311            if ([torrent isChecking])
312            {
313                if (!fYellowGradient)
314                    fYellowGradient = [[CTGradient progressYellowGradient] retain];
315                [fYellowGradient fillRect: completeRect angle: -90];
316            }
317            else if ([torrent isSeeding])
318            {
319                int ratioLeftWidth = leftWidth * (1.0 - [torrent progressStopRatio]);
320                leftWidth -= ratioLeftWidth;
321               
322                if (ratioLeftWidth > 0)
323                {
324                    NSRect ratioLeftRect = barRect;
325                    ratioLeftRect.origin.x += leftWidth;
326                    ratioLeftRect.size.width = ratioLeftWidth;
327                   
328                    if (!fLightGreenGradient)
329                        fLightGreenGradient = [[CTGradient progressLightGreenGradient] retain];
330                    [fLightGreenGradient fillRect: ratioLeftRect angle: -90];
331                }
332               
333                if (leftWidth > 0)
334                {
335                    completeRect.size.width = leftWidth;
336                   
337                    if (!fGreenGradient)
338                        fGreenGradient = [[CTGradient progressGreenGradient] retain];
339                    [fGreenGradient fillRect: completeRect angle: -90];
340                }
341            }
342            else
343            {
344                if (!fBlueGradient)
345                    fBlueGradient = [[CTGradient progressBlueGradient] retain];
346                [fBlueGradient fillRect: completeRect angle: -90];
347            }
348        }
349        else
350        {
351            if ([torrent waitingToStart])
352            {
353                if ([torrent progressLeft] <= 0.0)
354                {
355                    if (!fDarkGreenGradient)
356                        fDarkGreenGradient = [[CTGradient progressDarkGreenGradient] retain];
357                    [fDarkGreenGradient fillRect: completeRect angle: -90];
358                }
359                else
360                {
361                    if (!fDarkBlueGradient)
362                        fDarkBlueGradient = [[CTGradient progressDarkBlueGradient] retain];
363                    [fDarkBlueGradient fillRect: completeRect angle: -90];
364                }
365            }
366            else
367            {
368                if (!fGrayGradient)
369                    fGrayGradient = [[CTGradient progressGrayGradient] retain];
370                [fGrayGradient fillRect: completeRect angle: -90];
371            }
372        }
373    }
374   
375    [fBarOverlayColor set];
376    [NSBezierPath strokeRect: NSInsetRect(barRect, 0.5, 0.5)];
377}
378
379- (NSRect) rectForMinimalStatusWithString: (NSAttributedString *) string inBounds: (NSRect) bounds
380{
381    if (![fDefaults boolForKey: @"SmallView"])
382        return NSZeroRect;
383   
384    NSRect result = bounds;
385    result.size = [string size];
386   
387    result.origin.x += bounds.size.width - result.size.width - PADDING_HORIZONAL;
388    result.origin.y += PADDING_ABOVE_MIN_STATUS;
389   
390    return result;
391}
392
393- (NSRect) rectForTitleWithString: (NSAttributedString *) string basedOnMinimalStatusRect: (NSRect) statusRect
394            inBounds: (NSRect) bounds
395{
396    BOOL minimal = [fDefaults boolForKey: @"SmallView"];
397   
398    NSRect result = bounds;
399    result.origin.y += PADDING_ABOVE_TITLE;
400    result.origin.x += PADDING_HORIZONAL + (minimal ? IMAGE_SIZE_MIN : IMAGE_SIZE_REG) + PADDING_BETWEEN_IMAGE_AND_TITLE;
401   
402    result.size = [string size];
403    result.size.width = MIN(result.size.width, NSMaxX(bounds) - result.origin.x - PADDING_HORIZONAL
404                            - (minimal ? PADDING_BETWEEN_TITLE_AND_MIN_STATUS + statusRect.size.width : 0));
405   
406    return result;
407}
408
409- (NSRect) rectForProgressWithString: (NSAttributedString *) string inBounds: (NSRect) bounds
410{
411    if ([fDefaults boolForKey: @"SmallView"])
412        return NSZeroRect;
413   
414    NSRect result = bounds;
415    result.origin.y += PADDING_ABOVE_TITLE + HEIGHT_TITLE + PADDING_BETWEEN_TITLE_AND_PROGRESS;
416    result.origin.x += PADDING_HORIZONAL + IMAGE_SIZE_REG + PADDING_BETWEEN_IMAGE_AND_TITLE;
417   
418    result.size = [string size];
419    result.size.width = MIN(result.size.width, NSMaxX(bounds) - result.origin.x - PADDING_HORIZONAL);
420   
421    return result;
422}
423
424- (NSRect) rectForStatusWithString: (NSAttributedString *) string inBounds: (NSRect) bounds
425{
426    if ([fDefaults boolForKey: @"SmallView"])
427        return NSZeroRect;
428   
429    NSRect result = bounds;
430    result.origin.y += PADDING_ABOVE_TITLE + HEIGHT_TITLE + PADDING_BETWEEN_TITLE_AND_PROGRESS + HEIGHT_STATUS
431                        + PADDING_BETWEEN_PROGRESS_AND_BAR + BAR_HEIGHT + PADDING_BETWEEN_BAR_AND_STATUS;
432    result.origin.x += PADDING_HORIZONAL + IMAGE_SIZE_REG + PADDING_BETWEEN_IMAGE_AND_TITLE;
433   
434    result.size = [string size];
435    result.size.width = MIN(result.size.width, NSMaxX(bounds) - result.origin.x - PADDING_HORIZONAL);
436   
437    return result;
438}
439
440- (NSAttributedString *) attributedTitleWithColor: (NSColor *) color
441{
442    if (color)
443        [fTitleAttributes setObject: color forKey: NSForegroundColorAttributeName];
444   
445    NSString * title = [[self representedObject] name];
446    return [[[NSAttributedString alloc] initWithString: title attributes: fTitleAttributes] autorelease];
447}
448
449- (NSAttributedString *) attributedStatusString: (NSString *) string withColor: (NSColor *) color
450{
451    if (color)
452        [fStatusAttributes setObject: color forKey: NSForegroundColorAttributeName];
453   
454    return [[[NSAttributedString alloc] initWithString: string attributes: fStatusAttributes] autorelease];
455}
456
457@end
Note: See TracBrowser for help on using the repository browser.