source: trunk/macosx/TorrentCell.m @ 341

Last change on this file since 341 was 341, checked in by livings124, 16 years ago

This look for the progress bars matches the new smooth aqua look a lot more and is generated from images instead of drawing the bar from scratch.

The advanced bar should also be easier on the eyes now that the overlay isn't as extreme.

Thanks to FOOOD for the images.

  • Property svn:keywords set to Date Rev Author Id
File size: 11.1 KB
Line 
1/******************************************************************************
2 * $Id: TorrentCell.m 341 2006-06-12 16:58:04Z livings124 $
3 *
4 * Copyright (c) 2006 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 "StringAdditions.h"
28
29#define BAR_HEIGHT 12.0
30
31@interface TorrentCell (Private)
32
33- (void) placeBar: (NSImage *) barImage width: (float) width point: (NSPoint) point;
34- (void) buildSimpleBar: (int) width point: (NSPoint) point;
35- (void) buildAdvancedBar: (int) width point: (NSPoint) point;
36
37@end
38
39@implementation TorrentCell
40
41static NSImage * fProgressWhite, * fProgressBlue, * fProgressGray, * fProgressGreen,
42                * fProgressAdvanced, * fProgressEndWhite, * fProgressEndBlue,
43                * fProgressEndGray, * fProgressEndGreen, * fProgressEndAdvanced;
44
45// Used to optimize drawing. They contain packed RGBA pixels for every color needed.
46static uint32_t kBorder[] =
47    { 0x00000005, 0x00000010, 0x00000015, 0x00000015,
48      0x00000015, 0x00000015, 0x00000015, 0x00000015,
49      0x00000015, 0x00000015, 0x00000010, 0x00000005 };
50
51static uint32_t kBack[] = { 0xB4B4B4FF, 0xE3E3E3FF };
52
53static uint32_t kRed = 0xFF6450FF, //255, 100, 80
54    kBlue1 = 0xA0DCFFFF, //160, 220, 255
55    kBlue2 = 0x78BEFFFF, //120, 190, 255
56    kBlue3 = 0x50A0FFFF, //80, 160, 255
57    kBlue4 = 0x1E46B4FF, //30, 70, 180
58    kGray = 0x828282FF, //130, 130, 130
59    kGreen = 0x00FF00FF; //0, 255, 0
60
61- (id) init
62{
63    if ((self = [super init]))
64    {
65        NSSize startSize = NSMakeSize(100.0, BAR_HEIGHT);
66        if (!fProgressWhite)
67        {
68            fProgressWhite = [NSImage imageNamed: @"ProgressBarWhite.png"];
69            [fProgressWhite setScalesWhenResized: YES];
70            [fProgressWhite setSize: startSize];
71        }
72        if (!fProgressBlue)
73        {
74            fProgressBlue = [NSImage imageNamed: @"ProgressBarBlue.png"];
75            [fProgressBlue setScalesWhenResized: YES];
76            [fProgressBlue setSize: startSize];
77        }
78        if (!fProgressGray)
79        {
80            fProgressGray = [NSImage imageNamed: @"ProgressBarGray.png"];
81            [fProgressGray setScalesWhenResized: YES];
82            [fProgressGray setSize: startSize];
83        }
84        if (!fProgressGreen)
85        {
86            fProgressGreen = [NSImage imageNamed: @"ProgressBarGreen.png"];
87            [fProgressGreen setScalesWhenResized: YES];
88            [fProgressGreen setSize: startSize];
89        }
90        if (!fProgressAdvanced)
91        {
92            fProgressAdvanced = [NSImage imageNamed: @"ProgressBarAdvanced.png"];
93            [fProgressAdvanced setScalesWhenResized: YES];
94            [fProgressAdvanced setSize: startSize];
95        }
96       
97        if (!fProgressEndWhite)
98            fProgressEndWhite = [NSImage imageNamed: @"ProgressBarEndWhite.png"];
99        if (!fProgressEndBlue)
100            fProgressEndBlue = [NSImage imageNamed: @"ProgressBarEndBlue.png"];
101        if (!fProgressEndGray)
102            fProgressEndGray = [NSImage imageNamed: @"ProgressBarEndGray.png"];
103        if (!fProgressEndGreen)
104            fProgressEndGreen = [NSImage imageNamed: @"ProgressBarEndGreen.png"];
105        if (!fProgressEndAdvanced)
106            fProgressEndAdvanced = [NSImage imageNamed: @"ProgressBarEndAdvanced.png"];
107    }
108    return self;
109}
110
111- (void) setTorrent: (Torrent *) torrent
112{
113    fTorrent = torrent;
114}
115
116- (void) placeBar: (NSImage *) barImage width: (float) width point: (NSPoint) point
117{
118    if ([barImage size].width < width)
119        [barImage setSize: NSMakeSize(width * 1.5, BAR_HEIGHT)];
120
121    [barImage compositeToPoint: point fromRect: NSMakeRect(0, 0, width, BAR_HEIGHT)
122                        operation: NSCompositeSourceOver];
123}
124
125- (void) buildSimpleBar: (int) width point: (NSPoint) point
126{
127    width -= 2.0;
128    if ([fTorrent isSeeding])
129    {
130        [fProgressEndGreen compositeToPoint: point operation: NSCompositeSourceOver];
131       
132        point.x += 1.0;
133        [self placeBar: fProgressGreen width: width point: point];
134       
135        point.x += width;
136        [fProgressEndGreen compositeToPoint: point operation: NSCompositeSourceOver];
137    }
138    else
139    {
140        NSImage * barActiveEnd, * barActive;
141        if ([fTorrent isActive])
142        {
143            barActiveEnd = fProgressEndBlue;
144            barActive = fProgressBlue;
145        }
146        else
147        {
148            barActiveEnd = fProgressEndGray;
149            barActive = fProgressGray;
150        }
151       
152        float completedWidth = [fTorrent progress] * width,
153                remainingWidth = width - completedWidth;
154   
155        if (completedWidth >= 1.0)
156            [barActiveEnd compositeToPoint: point operation: NSCompositeSourceOver];
157        else
158            [fProgressEndWhite compositeToPoint: point operation: NSCompositeSourceOver];
159       
160        point.x += 1.0;
161        [self placeBar: barActive width: completedWidth point: point];
162       
163        point.x += completedWidth;
164        [self placeBar: fProgressWhite width: remainingWidth point: point];
165       
166        point.x += remainingWidth;
167        [fProgressEndWhite compositeToPoint: point operation: NSCompositeSourceOver];
168    }
169}
170
171- (void) buildAdvancedBar: (int) width point: (NSPoint) point
172{
173    //if seeding, there's no need for the advanced bar
174    if ([fTorrent isSeeding])
175    {
176        [self buildSimpleBar: width point: point];
177        return;
178    }
179
180    NSBitmapImageRep * bitmap = [[NSBitmapImageRep alloc]
181        initWithBitmapDataPlanes: nil pixelsWide: width
182        pixelsHigh: BAR_HEIGHT bitsPerSample: 8 samplesPerPixel: 4
183        hasAlpha: YES isPlanar: NO colorSpaceName:
184        NSCalibratedRGBColorSpace bytesPerRow: 0 bitsPerPixel: 0];
185
186    int h, w;
187    uint32_t * p;
188    uint8_t * bitmapData = [bitmap bitmapData];
189    int bytesPerRow = [bitmap bytesPerRow];
190
191    /* Left and right borders */
192    p = (uint32_t *) bitmapData;
193    for( h = 0; h < BAR_HEIGHT; h++ )
194    {
195        p[0] = htonl( kBorder[h] );
196        p[width - 1] = htonl( kBorder[h] );
197        p += bytesPerRow / 4;
198    }
199
200    int8_t * pieces = malloc( width );
201    [fTorrent getAvailability: pieces size: width];
202
203    /* First two lines: dark blue to show progression */
204    int end  = lrintf( floor( [fTorrent progress] * ( width - 2 ) ) );
205    for( h = 0; h < 2; h++ )
206    {
207        p = (uint32_t *) ( bitmapData + h * bytesPerRow ) + 1;
208        for( w = 0; w < end; w++ )
209            p[w] = htonl( kBlue4 );
210        for( w = end; w < width - 2; w++ )
211            p[w] = htonl( kBack[h] );
212    }
213
214    /* Lines 2 to 14: blue or grey depending on whether
215       we have the piece or not */
216    uint32_t color;
217    for( w = 0; w < width - 2; w++ )
218    {
219        /* Point to pixel ( 2 + w, 2 ). We will then draw
220           "vertically" */
221        p = (uint32_t *) ( bitmapData + 2 * bytesPerRow ) + 1 + w;
222
223        if (pieces[w] < 0)
224            color = kGray;
225        else if (pieces[w] == 0)
226            color = kRed;
227        else if (pieces[w] == 1)
228            color = kBlue1;
229        else if (pieces[w] == 2)
230            color = kBlue2;
231        else
232            color = kBlue3;
233
234        for( h = 2; h < BAR_HEIGHT; h++ )
235        {
236            p[0] = htonl( color );
237            p = (uint32_t *) ( (uint8_t *) p + bytesPerRow );
238        }
239    }
240
241    free( pieces );
242   
243    //actually draw image
244    NSImage * img = [[NSImage alloc] initWithSize: [bitmap size]];
245    [img addRepresentation: bitmap];
246    [img compositeToPoint: point operation: NSCompositeSourceOver];
247    [img release];
248    [bitmap release];
249   
250    //draw overlay over advanced bar
251    [self placeBar: fProgressAdvanced width: width point: point];
252}
253
254- (void) drawWithFrame: (NSRect) cellFrame inView: (NSView *) view
255{
256    BOOL highlighted = [self isHighlighted] && [[view window] isKeyWindow];
257    NSDictionary * nameAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
258                    highlighted ? [NSColor whiteColor] : [NSColor blackColor],
259                    NSForegroundColorAttributeName,
260                    [NSFont messageFontOfSize: 12.0], NSFontAttributeName, nil];
261    NSDictionary * statusAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
262                    highlighted ? [NSColor whiteColor] : [NSColor darkGrayColor],
263                    NSForegroundColorAttributeName,
264                    [NSFont messageFontOfSize: 9.0], NSFontAttributeName, nil];
265
266    NSPoint pen = cellFrame.origin;
267    float padding = 3.0, linePadding = 2.0;
268
269    //icon
270    NSImage * icon = [fTorrent iconFlipped];
271    NSSize iconSize = [icon size];
272   
273    pen.x += padding;
274    pen.y += (cellFrame.size.height - iconSize.height) * 0.5;
275   
276    [icon drawAtPoint: pen fromRect: NSMakeRect( 0, 0, iconSize.width, iconSize.height )
277            operation: NSCompositeSourceOver fraction: 1.0];
278
279    float extraNameShift = 1.0,
280        mainWidth = cellFrame.size.width - iconSize.width - 3.0 * padding - extraNameShift;
281
282    //name string
283    pen.x += iconSize.width + padding + extraNameShift;
284    pen.y = cellFrame.origin.y + padding;
285    NSAttributedString * nameString = [[fTorrent name] attributedStringFittingInWidth: mainWidth
286                                attributes: nameAttributes];
287    [nameString drawAtPoint: pen];
288   
289    //progress string
290    pen.y += [nameString size].height + linePadding - 1.0;
291   
292    NSAttributedString * progressString = [[fTorrent progressString]
293        attributedStringFittingInWidth: mainWidth attributes: statusAttributes];
294    [progressString drawAtPoint: pen];
295
296    //progress bar
297    pen.x -= extraNameShift;
298    pen.y += [progressString size].height + linePadding + BAR_HEIGHT;
299   
300    float barWidth = mainWidth + extraNameShift - BUTTONS_TOTAL_WIDTH + padding;
301   
302    if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseAdvancedBar"])
303        [self buildAdvancedBar: barWidth point: pen];
304    else
305        [self buildSimpleBar: barWidth point: pen];
306
307    //status strings
308    pen.x += extraNameShift;
309    pen.y += linePadding;
310    NSAttributedString * statusString = [[fTorrent statusString]
311        attributedStringFittingInWidth: mainWidth attributes: statusAttributes];
312    [statusString drawAtPoint: pen];
313   
314    [nameAttributes release];
315    [statusAttributes release];
316}
317
318@end
Note: See TracBrowser for help on using the repository browser.