source: branches/new_api/macosx/TorrentCell.m @ 157

Last change on this file since 157 was 157, checked in by titer, 16 years ago

Optimized buildAdvancedBar a bit

File size: 10.3 KB
Line 
1/******************************************************************************
2 * Copyright (c) 2005-2006 Transmission authors and contributors
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 *****************************************************************************/
22
23#import "TorrentCell.h"
24#import "StringAdditions.h"
25
26#define BAR_HEIGHT 12
27
28@implementation TorrentCell
29
30/***********************************************************************
31 * Static tables
32 ***********************************************************************
33 * We use these tables to optimize the drawing. They contain packed
34 * RGBA pixels for every color we might need.
35 **********************************************************************/
36
37static uint32_t kBorder[] =
38    { 0x00000005, 0x00000010, 0x00000015, 0x00000015,
39      0x00000015, 0x00000015, 0x00000015, 0x00000015,
40      0x00000015, 0x00000015, 0x00000010, 0x00000005 };
41
42static uint32_t kBack[] =
43    { 0xB4B4B4FF, 0xE3E3E3FF, 0xE8E8E8FF, 0xDEDEDEFF,
44      0xDBDBDBFF, 0xE5E5E5FF, 0xE7E7E7FF, 0xF5F5F5FF,
45      0xFAFAFAFF, 0xDEDEDEFF, 0x0000003F, 0x00000015 };
46
47/* Coefficients for the "3D effect":
48   0.59, 0.91, 0.97, 0.92, 0.79, 0.76, 0.85, 0.93, 1.00, 0.99 */
49
50/* 255, 100, 80 */
51static uint32_t kRed[] =
52    { 0x963A2FFF, 0xE85B48FF, 0xF7614DFF, 0xEA5C49FF,
53      0xC94F3FFF, 0xC14C3CFF, 0xD85544FF, 0xED5D4AFF,
54      0xFF6450FF, 0xFC634FFF, 0x0000003F, 0x00000015 };
55
56/* 160, 220, 255 */
57static uint32_t kBlue1[] =
58    { 0x5E8196FF, 0x91C8E8FF, 0x9BD5F7FF, 0x93CAEAFF,
59      0x7EADC9FF, 0x79A7C1FF, 0x88BBD8FF, 0x94CCEDFF,
60      0xA0DCFFFF, 0x9ED9FCFF, 0x0000003F, 0x00000015 };
61
62/* 120, 190, 255 */
63static uint32_t kBlue2[] =
64    { 0x467096FF, 0x6DACE8FF, 0x74B8F7FF, 0x6EAEEAFF,
65      0x5E96C9FF, 0x5B90C1FF, 0x66A1D8FF, 0x6FB0EDFF,
66      0x78BEFFFF, 0x76BCFCFF, 0x0000003F, 0x00000015 };
67
68/* 80, 160, 255 */
69static uint32_t kBlue3[] =
70    { 0x2F5E96FF, 0x4891E8FF, 0x4D9BF7FF, 0x4993EAFF,
71      0x3F7EC9FF, 0x3C79C1FF, 0x4488D8FF, 0x4A94EDFF,
72      0x50A0FFFF, 0x4F9EFCFF, 0x0000003F, 0x00000015 };
73
74/* 30, 70, 180 */
75static uint32_t kBlue4[] =
76    { 0x11296AFF, 0x1B3FA3FF, 0x1D43AEFF, 0x1B40A5FF,
77      0x17378EFF, 0x163588FF, 0x193B99FF, 0x1B41A7FF,
78      0x1E46B4FF, 0x1D45B2FF, 0x0000003F, 0x00000015 };
79
80/* 130, 130, 130 */
81static uint32_t kGray[] =
82    { 0x4C4C4CFF, 0x767676FF, 0x7E7E7EFF, 0x777777FF,
83      0x666666FF, 0x626262FF, 0x6E6E6EFF, 0x787878FF,
84      0x828282FF, 0x808080FF, 0x0000003F, 0x00000015 };
85
86/* 0, 255, 0 */
87static uint32_t kGreen[] =
88    { 0x009600FF, 0x00E800FF, 0x00F700FF, 0x00EA00FF,
89      0x00C900FF, 0x00C100FF, 0x00D800FF, 0x00ED00FF,
90      0x00FF00FF, 0x00FC00FF, 0x0000003F, 0x00000015 };
91
92- (void) setTorrent: (Torrent *) torrent
93{
94    fTorrent = torrent;
95}
96
97- (void) setTextColor: (NSColor *) color
98{
99    fTextColor = color;
100}
101
102/***********************************************************************
103 * init
104 ***********************************************************************
105 * Prepares the NSBitmapImageReps we are going to need in order to
106 * draw.
107 **********************************************************************/
108- (id) init
109{
110    self = [super init];
111
112    return self;
113}
114
115/***********************************************************************
116 * buildSimpleBar
117 **********************************************************************/
118- (void) buildSimpleBar
119{
120    int        h, w, end, pixelsPerRow;
121    uint32_t * p;
122    uint32_t * colors;
123
124    pixelsPerRow = [fBitmap bytesPerRow] / 4;
125
126    p   = (uint32_t *) [fBitmap bitmapData] + 1;
127    end = lrintf( floor( [fTorrent progress] * ( fWidth - 2 ) ) );
128
129    if( [fTorrent isSeeding] )
130        colors = kGreen;
131    else if( [fTorrent isActive] )
132        colors = kBlue2;
133    else
134        colors = kGray;
135
136    for( h = 0; h < BAR_HEIGHT; h++ )
137    {
138        for( w = 0; w < end; w++ )
139        {
140            p[w] = htonl( colors[h] );
141        }
142        for( w = end; w < fWidth - 2; w++ )
143        {
144            p[w] = htonl( kBack[h] );
145        }
146        p += pixelsPerRow;
147    }
148}
149
150/***********************************************************************
151 * buildAdvancedBar
152 **********************************************************************/
153- (void) buildAdvancedBar
154{
155    int      h, w, end, pixelsPerRow;
156    uint32_t * p, * colors;
157    uint8_t  * bitmapData  = [fBitmap bitmapData];
158    int        bytesPerRow = [fBitmap bytesPerRow];
159
160    fPieces = malloc( fWidth );
161    [fTorrent getAvailability: fPieces size: fWidth];
162
163    if( [fTorrent isSeeding] )
164    {
165        /* All green, same as the simple bar */
166        [self buildSimpleBar];
167        return;
168    }
169
170    pixelsPerRow = [fBitmap bytesPerRow] / 4;
171
172    /* First two lines: dark blue to show progression */
173    end  = lrintf( floor( [fTorrent progress] * ( fWidth - 2 ) ) );
174    for( h = 0; h < 2; h++ )
175    {
176        p = (uint32_t *) ( bitmapData + h * bytesPerRow ) + 1;
177        for( w = 0; w < end; w++ )
178        {
179            p[w] = htonl( kBlue4[h] );
180        }
181        for( w = end; w < fWidth - 2; w++ )
182        {
183            p[w] = htonl( kBack[h] );
184        }
185    }
186
187    /* Lines 2 to 14: blue or grey depending on whether
188       we have the piece or not */
189    for( w = 0; w < fWidth - 2; w++ )
190    {
191        /* Point to pixel ( 2 + w, 2 ). We will then draw
192           "vertically" */
193        p  = (uint32_t *) ( bitmapData + 2 * bytesPerRow ) + 1 + w;
194
195        if( fPieces[w] < 0 )
196        {
197            colors = kGray;
198        }
199        else if( fPieces[w] < 1 )
200        {
201            colors = kRed;
202        }
203        else if( fPieces[w] < 2 )
204        {
205            colors = kBlue1;
206        }
207        else if( fPieces[w] < 3 )
208        {
209            colors = kBlue2;
210        }
211        else
212        {
213            colors = kBlue3;
214        }
215
216        for( h = 2; h < BAR_HEIGHT; h++ )
217        {
218            p[0] = htonl( colors[h] );
219            p    = (uint32_t *) ( (uint8_t *) p + bytesPerRow );
220        }
221    }
222
223    free( fPieces );
224}
225
226- (void) buildBar
227{
228    int h;
229    uint32_t * p;
230
231    /* Left and right borders */
232    p = (uint32_t *) [fBitmap bitmapData];
233    for( h = 0; h < BAR_HEIGHT; h++ )
234    {
235        p[0]          = htonl( kBorder[h] );
236        p[fWidth - 1] = htonl( kBorder[h] );
237        p += [fBitmap bytesPerRow] / 4;
238    }
239
240    /* ...and redraw the progress bar on the top of it */
241    if( [[NSUserDefaults standardUserDefaults]
242            boolForKey:@"UseAdvancedBar"])
243    {
244        [self buildAdvancedBar];
245    }
246    else
247    {
248        [self buildSimpleBar];
249    }
250}
251
252/***********************************************************************
253 * drawWithFrame
254 ***********************************************************************
255 * We have the strings, we have the bitmap. Let's just draw them where
256 * they belong.
257 **********************************************************************/
258- (void) drawWithFrame: (NSRect) cellFrame inView: (NSView *) view
259{
260    if( ![view lockFocusIfCanDraw] )
261    {
262        return;
263    }
264
265    NSMutableDictionary * attributes;
266    attributes = [NSMutableDictionary dictionaryWithCapacity: 2];
267    [attributes setObject: fTextColor
268        forKey: NSForegroundColorAttributeName];
269
270    NSPoint pen = cellFrame.origin;
271
272    /* Draw the icon */
273    pen.x += 5; pen.y += 10;
274    NSImage * icon = [fTorrent icon];
275    [icon drawAtPoint: pen fromRect:
276        NSMakeRect( 0, 0, [icon size].width, [icon size].height )
277        operation: NSCompositeSourceOver fraction: 1.0];
278
279    NSString * string;
280    fWidth  = NSWidth( cellFrame ) - [icon size].width - 15;
281
282    /* Draw file or folder name */
283    pen.x += [icon size].width + 5; pen.y -= 7;
284    [attributes setObject: [NSFont messageFontOfSize: 11]
285        forKey: NSFontAttributeName];
286    NSString * sizeString = [NSString stringWithFormat: @" (%@)",
287        [NSString stringForFileSize: [fTorrent size]]];
288    string = [[[fTorrent name] stringFittingInWidth: fWidth - 50 -
289        [sizeString sizeWithAttributes: attributes].width
290        withAttributes: attributes] stringByAppendingString: sizeString];
291    [string drawAtPoint: pen withAttributes: attributes];
292
293    /* Draw the progress bar */
294    pen.y += 17;
295    fBitmap = [[NSBitmapImageRep alloc]
296        initWithBitmapDataPlanes: nil pixelsWide: fWidth
297        pixelsHigh: BAR_HEIGHT bitsPerSample: 8 samplesPerPixel: 4
298        hasAlpha: YES isPlanar: NO colorSpaceName:
299        NSCalibratedRGBColorSpace bytesPerRow: 0 bitsPerPixel: 0];
300    NSImage * img = [[NSImage alloc] initWithSize: [fBitmap size]];
301    [img addRepresentation: fBitmap];
302    [img setFlipped: YES];
303    [self buildBar];
304    [img drawAtPoint: pen fromRect: NSMakeRect( 0, 0,
305            [img size].width, [img size].height )
306        operation: NSCompositeSourceOver fraction: 1.0];
307    [img release];
308    [fBitmap release];
309
310    /* Status strings */
311    [attributes setObject: [NSFont messageFontOfSize: 9]
312            forKey: NSFontAttributeName];
313    pen.y += BAR_HEIGHT + 2;
314    [[fTorrent statusString] drawAtPoint: pen withAttributes: attributes];
315    pen.y += 13;
316    string = [[fTorrent infoString] stringFittingInWidth:
317        ( cellFrame.size.width - 77 ) withAttributes: attributes];
318    [string drawAtPoint: pen withAttributes: attributes];
319
320    /* Rates */
321    pen.x += fWidth - 70; pen.y -= 13;
322    [[fTorrent downloadString] drawAtPoint: pen withAttributes: attributes];
323    pen.y += 13;
324    [[fTorrent uploadString] drawAtPoint: pen withAttributes: attributes];
325
326    [view unlockFocus];
327}
328
329@end
Note: See TracBrowser for help on using the repository browser.