source: trunk/macosx/TorrentCell.m @ 272

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

First commit on my own 8-)

Sorting by progress, sorting no longer causes crashes.
New look for the table.
Info is now inspector: can set individual and multiple ratio limits, shows listing of files, more info in general, resizes when changing tabs, can change tabs with cmd-left and cmd-right.
Menu items moved to "Transfers" menu.
Sliding status bar in its own view.
Prefs moved into their own nib.
Toolbar items for pause and resume selected (many wanted this, but it needs better icons)
New icons for Transfers and General.
A lot of tweaking of main window to fix alignment etc.
Sparkle used for updated (still needs to be added to website to work).

And a lot more tweaking and changes that I'm too lazy to list.

...now let's hope I commit this right

  • Property svn:keywords set to Date Rev Author Id
File size: 9.8 KB
Line 
1/******************************************************************************
2 * $Id: TorrentCell.m 272 2006-06-06 18:05:57Z 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 "StringAdditions.h"
27
28#define BAR_HEIGHT 12
29
30@implementation TorrentCell
31
32/***********************************************************************
33 * Static tables
34 ***********************************************************************
35 * We use these tables to optimize the drawing. They contain packed
36 * RGBA pixels for every color we might need.
37 **********************************************************************/
38
39static uint32_t kBorder[] =
40    { 0x00000005, 0x00000010, 0x00000015, 0x00000015,
41      0x00000015, 0x00000015, 0x00000015, 0x00000015,
42      0x00000015, 0x00000015, 0x00000010, 0x00000005 };
43
44static uint32_t kBack[] =
45    { 0xB4B4B4FF, 0xE3E3E3FF, 0xE8E8E8FF, 0xDEDEDEFF,
46      0xDBDBDBFF, 0xE5E5E5FF, 0xE7E7E7FF, 0xF5F5F5FF,
47      0xFAFAFAFF, 0xDEDEDEFF, 0x0000003F, 0x00000015 };
48
49/* Coefficients for the "3D effect":
50   0.59, 0.91, 0.97, 0.92, 0.79, 0.76, 0.85, 0.93, 1.00, 0.99 */
51
52/* 255, 100, 80 */
53static uint32_t kRed[] =
54    { 0x963A2FFF, 0xE85B48FF, 0xF7614DFF, 0xEA5C49FF,
55      0xC94F3FFF, 0xC14C3CFF, 0xD85544FF, 0xED5D4AFF,
56      0xFF6450FF, 0xFC634FFF, 0x0000003F, 0x00000015 };
57
58/* 160, 220, 255 */
59static uint32_t kBlue1[] =
60    { 0x5E8196FF, 0x91C8E8FF, 0x9BD5F7FF, 0x93CAEAFF,
61      0x7EADC9FF, 0x79A7C1FF, 0x88BBD8FF, 0x94CCEDFF,
62      0xA0DCFFFF, 0x9ED9FCFF, 0x0000003F, 0x00000015 };
63
64/* 120, 190, 255 */
65static uint32_t kBlue2[] =
66    { 0x467096FF, 0x6DACE8FF, 0x74B8F7FF, 0x6EAEEAFF,
67      0x5E96C9FF, 0x5B90C1FF, 0x66A1D8FF, 0x6FB0EDFF,
68      0x78BEFFFF, 0x76BCFCFF, 0x0000003F, 0x00000015 };
69
70/* 80, 160, 255 */
71static uint32_t kBlue3[] =
72    { 0x2F5E96FF, 0x4891E8FF, 0x4D9BF7FF, 0x4993EAFF,
73      0x3F7EC9FF, 0x3C79C1FF, 0x4488D8FF, 0x4A94EDFF,
74      0x50A0FFFF, 0x4F9EFCFF, 0x0000003F, 0x00000015 };
75
76/* 30, 70, 180 */
77static uint32_t kBlue4[] =
78    { 0x11296AFF, 0x1B3FA3FF, 0x1D43AEFF, 0x1B40A5FF,
79      0x17378EFF, 0x163588FF, 0x193B99FF, 0x1B41A7FF,
80      0x1E46B4FF, 0x1D45B2FF, 0x0000003F, 0x00000015 };
81
82/* 130, 130, 130 */
83static uint32_t kGray[] =
84    { 0x4C4C4CFF, 0x767676FF, 0x7E7E7EFF, 0x777777FF,
85      0x666666FF, 0x626262FF, 0x6E6E6EFF, 0x787878FF,
86      0x828282FF, 0x808080FF, 0x0000003F, 0x00000015 };
87
88/* 0, 255, 0 */
89static uint32_t kGreen[] =
90    { 0x009600FF, 0x00E800FF, 0x00F700FF, 0x00EA00FF,
91      0x00C900FF, 0x00C100FF, 0x00D800FF, 0x00ED00FF,
92      0x00FF00FF, 0x00FC00FF, 0x0000003F, 0x00000015 };
93
94- (void) setTorrent: (Torrent *) torrent
95{
96    fTorrent = torrent;
97}
98
99- (void) buildSimpleBar: (int) width bitmap: (NSBitmapImageRep *) bitmap
100{
101    int        h, w, end, pixelsPerRow;
102    uint32_t * p;
103    uint32_t * colors;
104
105    pixelsPerRow = [bitmap bytesPerRow] / 4;
106
107    p   = (uint32_t *) [bitmap bitmapData] + 1;
108    end = lrintf( floor( [fTorrent progress] * ( width - 2 ) ) );
109
110    if( [fTorrent isSeeding] )
111        colors = kGreen;
112    else if( [fTorrent isActive] )
113        colors = kBlue2;
114    else
115        colors = kGray;
116
117    for( h = 0; h < BAR_HEIGHT; h++ )
118    {
119        for( w = 0; w < end; w++ )
120        {
121            p[w] = htonl( colors[h] );
122        }
123        for( w = end; w < width - 2; w++ )
124        {
125            p[w] = htonl( kBack[h] );
126        }
127        p += pixelsPerRow;
128    }
129}
130
131- (void) buildAdvancedBar: (int) width bitmap: (NSBitmapImageRep *) bitmap
132{
133    int      h, w, end, pixelsPerRow;
134    uint32_t * p, * colors;
135    uint8_t  * bitmapData  = [bitmap bitmapData];
136    int        bytesPerRow = [bitmap bytesPerRow];
137
138    int8_t * pieces = malloc( width );
139    [fTorrent getAvailability: pieces size: width];
140
141    if( [fTorrent isSeeding] )
142    {
143        /* All green, same as the simple bar */
144        [self buildSimpleBar: width bitmap: bitmap];
145        return;
146    }
147
148    pixelsPerRow = bytesPerRow / 4;
149
150    /* First two lines: dark blue to show progression */
151    end  = lrintf( floor( [fTorrent progress] * ( width - 2 ) ) );
152    for( h = 0; h < 2; h++ )
153    {
154        p = (uint32_t *) ( bitmapData + h * bytesPerRow ) + 1;
155        for( w = 0; w < end; w++ )
156        {
157            p[w] = htonl( kBlue4[h] );
158        }
159        for( w = end; w < width - 2; w++ )
160        {
161            p[w] = htonl( kBack[h] );
162        }
163    }
164
165    /* Lines 2 to 14: blue or grey depending on whether
166       we have the piece or not */
167    for( w = 0; w < width - 2; w++ )
168    {
169        /* Point to pixel ( 2 + w, 2 ). We will then draw
170           "vertically" */
171        p  = (uint32_t *) ( bitmapData + 2 * bytesPerRow ) + 1 + w;
172
173        if( pieces[w] < 0 )
174        {
175            colors = kGray;
176        }
177        else if( pieces[w] < 1 )
178        {
179            colors = kRed;
180        }
181        else if( pieces[w] < 2 )
182        {
183            colors = kBlue1;
184        }
185        else if( pieces[w] < 3 )
186        {
187            colors = kBlue2;
188        }
189        else
190        {
191            colors = kBlue3;
192        }
193
194        for( h = 2; h < BAR_HEIGHT; h++ )
195        {
196            p[0] = htonl( colors[h] );
197            p    = (uint32_t *) ( (uint8_t *) p + bytesPerRow );
198        }
199    }
200
201    free( pieces );
202}
203
204- (void) buildBarWithWidth: (int) width bitmap: (NSBitmapImageRep *) bitmap
205{
206    int h;
207    uint32_t * p;
208
209    /* Left and right borders */
210    p = (uint32_t *) [bitmap bitmapData];
211    for( h = 0; h < BAR_HEIGHT; h++ )
212    {
213        p[0]          = htonl( kBorder[h] );
214        p[width - 1] = htonl( kBorder[h] );
215        p += [bitmap bytesPerRow] / 4;
216    }
217
218    /* ...and redraw the progress bar on the top of it */
219    if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseAdvancedBar"])
220        [self buildAdvancedBar: width bitmap: bitmap];
221    else
222        [self buildSimpleBar: width bitmap: bitmap];
223}
224
225- (void) drawWithFrame: (NSRect) cellFrame inView: (NSView *) view
226{
227    BOOL highlighted = [self isHighlighted] && [[view window] isKeyWindow];
228    NSDictionary * nameAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
229                    highlighted ? [NSColor whiteColor] : [NSColor blackColor],
230                    NSForegroundColorAttributeName,
231                    [NSFont messageFontOfSize: 12], NSFontAttributeName, nil];
232    NSDictionary * statusAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
233                    highlighted ? [NSColor whiteColor] : [NSColor darkGrayColor],
234                    NSForegroundColorAttributeName,
235                    [NSFont messageFontOfSize: 9], NSFontAttributeName, nil];
236
237    NSPoint pen = cellFrame.origin;
238    float padding = 3.0, linePadding = 2.0;
239
240    //icon
241    NSImage * icon = [fTorrent iconFlipped];
242    NSSize iconSize = [icon size];
243   
244    pen.x += padding;
245    pen.y += (cellFrame.size.height - iconSize.height) * 0.5;
246   
247    [icon drawAtPoint: pen fromRect:
248        NSMakeRect( 0, 0, iconSize.width, iconSize.height )
249        operation: NSCompositeSourceOver fraction: 1.0];
250
251    float extraNameShift = 1.0,
252        mainWidth = cellFrame.size.width - iconSize.width - 3.0 * padding - extraNameShift;
253
254    //name string
255    pen.x += iconSize.width + padding + extraNameShift;
256    pen.y = cellFrame.origin.y + padding;
257    NSAttributedString * nameString = [[fTorrent name] attributedStringFittingInWidth: mainWidth
258                                attributes: nameAttributes];
259    [nameString drawAtPoint: pen];
260   
261    //progress string
262    pen.y += [nameString size].height + linePadding - 1.0;
263   
264    NSAttributedString * progressString = [[fTorrent progressString]
265        attributedStringFittingInWidth: mainWidth attributes: statusAttributes];
266    [progressString drawAtPoint: pen];
267
268    //progress bar
269    pen.x -= extraNameShift;
270    pen.y += [progressString size].height + linePadding;
271   
272    float barWidth = mainWidth + extraNameShift - 39.5 - padding;
273   
274    NSBitmapImageRep * bitmap = [[NSBitmapImageRep alloc]
275        initWithBitmapDataPlanes: nil pixelsWide: barWidth
276        pixelsHigh: BAR_HEIGHT bitsPerSample: 8 samplesPerPixel: 4
277        hasAlpha: YES isPlanar: NO colorSpaceName:
278        NSCalibratedRGBColorSpace bytesPerRow: 0 bitsPerPixel: 0];
279    NSImage * img = [[NSImage alloc] initWithSize: [bitmap size]];
280    [img addRepresentation: bitmap];
281    [img setFlipped: YES];
282   
283    [self buildBarWithWidth: barWidth bitmap: bitmap];
284   
285    [img drawAtPoint: pen fromRect: NSMakeRect( 0, 0,
286            [img size].width, [img size].height )
287        operation: NSCompositeSourceOver fraction: 1.0];
288    [img release];
289    [bitmap release];
290
291    //status strings
292    pen.x += extraNameShift;
293    pen.y += BAR_HEIGHT + linePadding;
294    NSAttributedString * statusString = [[fTorrent statusString]
295        attributedStringFittingInWidth: mainWidth attributes: statusAttributes];
296    [statusString drawAtPoint: pen];
297   
298    [nameAttributes release];
299    [statusAttributes release];
300}
301
302@end
Note: See TracBrowser for help on using the repository browser.