Transmission: update from 2.42 to 2.50
[tomato.git] / release / src / router / transmission / macosx / PiecesView.m
blobafd2bf3a6a98f1ce7c58b6283ca7d8cc52b1d7b6
1 /******************************************************************************
2  * $Id: PiecesView.m 13162 2012-01-14 17:12:04Z livings124 $
3  *
4  * Copyright (c) 2006-2012 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  *****************************************************************************/
25 #import "PiecesView.h"
26 #import "Torrent.h"
27 #import "InfoWindowController.h"
29 #import "transmission.h"
30 #import "utils.h"
32 #define MAX_ACROSS 18
33 #define BETWEEN 1.0
35 #define HIGH_PEERS 30
37 enum
39     PIECE_NONE,
40     PIECE_SOME,
41     PIECE_HIGH_PEERS,
42     PIECE_FINISHED,
43     PIECE_FLASHING
46 @implementation PiecesView
48 - (void) awakeFromNib
50     //store box colors
51     fGreenAvailabilityColor = [[NSColor colorWithCalibratedRed: 0.0 green: 1.0 blue: 0.4 alpha: 1.0] retain];
52     fBluePieceColor = [[NSColor colorWithCalibratedRed: 0.0 green: 0.4 blue: 0.8 alpha: 1.0] retain];
53     
54     //actually draw the box
55     [self setTorrent: nil];
58 - (void) dealloc
60     tr_free(fPieces);
61     
62     [fGreenAvailabilityColor release];
63     [fBluePieceColor release];
64     
65     [super dealloc];
68 - (void) setTorrent: (Torrent *) torrent
70     [self clearView];
71     
72     fTorrent = (torrent && ![torrent isMagnet]) ? torrent : nil;
73     if (fTorrent)
74     {
75         //determine relevant values
76         fNumPieces = MIN([fTorrent pieceCount], MAX_ACROSS * MAX_ACROSS);
77         fAcross = ceil(sqrt(fNumPieces));
78         
79         const CGFloat width = [self bounds].size.width;
80         fWidth = (width - (fAcross + 1) * BETWEEN) / fAcross;
81         fExtraBorder = (width - ((fWidth + BETWEEN) * fAcross + BETWEEN)) / 2;
82     }
83     
84     NSImage * back = [[NSImage alloc] initWithSize: [self bounds].size];
85     [back lockFocus];
86     
87     NSGradient * gradient = [[NSGradient alloc] initWithStartingColor: [NSColor colorWithCalibratedWhite: 0.0 alpha: 0.4]
88                                 endingColor: [NSColor colorWithCalibratedWhite: 0.2 alpha: 0.4]];
89     [gradient drawInRect: [self bounds] angle: 90.0];
90     [gradient release];
91     [back unlockFocus];
92     
93     [self setImage: back];
94     [back release];
95     
96     [self setNeedsDisplay];
99 - (void) clearView
101     tr_free(fPieces);
102     fPieces = NULL;
105 - (void) updateView
107     if (!fTorrent)
108         return;
109     
110     //determine if first time
111     const BOOL first = fPieces == NULL;
112     if (first)
113         fPieces = (int8_t *)tr_malloc(fNumPieces * sizeof(int8_t));
115     int8_t * pieces = NULL;
116     float * piecesPercent = NULL;
117     
118     const BOOL showAvailablity = [[NSUserDefaults standardUserDefaults] boolForKey: @"PiecesViewShowAvailability"];
119     if (showAvailablity)
120     {   
121         pieces = (int8_t *)tr_malloc(fNumPieces * sizeof(int8_t));
122         [fTorrent getAvailability: pieces size: fNumPieces];
123     }
124     else
125     {   
126         piecesPercent = (float *)tr_malloc(fNumPieces * sizeof(float));
127         [fTorrent getAmountFinished: piecesPercent size: fNumPieces];
128     }
129     
130     NSImage * image = [self image];
131     
132     NSRect fillRects[fNumPieces];
133     NSColor * fillColors[fNumPieces];
134     
135     NSInteger usedCount = 0;
136     
137     for (NSInteger index = 0; index < fNumPieces; index++)
138     {
139         NSColor * pieceColor = nil;
140         
141         if (showAvailablity ? pieces[index] == -1 : piecesPercent[index] == 1.0)
142         {
143             if (first || fPieces[index] != PIECE_FINISHED)
144             {
145                 if (!first && fPieces[index] != PIECE_FLASHING)
146                 {
147                     pieceColor = [NSColor orangeColor];
148                     fPieces[index] = PIECE_FLASHING;
149                 }
150                 else
151                 {
152                     pieceColor = fBluePieceColor;
153                     fPieces[index] = PIECE_FINISHED;
154                 }
155             }
156         }
157         else if (showAvailablity ? pieces[index] == 0 : piecesPercent[index] == 0.0)
158         {
159             if (first || fPieces[index] != PIECE_NONE)
160             {
161                 pieceColor = [NSColor whiteColor];
162                 fPieces[index] = PIECE_NONE;
163             }
164         }
165         else if (showAvailablity && pieces[index] >= HIGH_PEERS)
166         {
167             if (first || fPieces[index] != PIECE_HIGH_PEERS)
168             {
169                 pieceColor = fGreenAvailabilityColor;
170                 fPieces[index] = PIECE_HIGH_PEERS;
171             }
172         }
173         else
174         {
175             //always redraw "mixed"
176             CGFloat percent = showAvailablity ? (CGFloat)pieces[index]/HIGH_PEERS : piecesPercent[index];
177             NSColor * fullColor = showAvailablity ? fGreenAvailabilityColor : fBluePieceColor;
178             pieceColor = [[NSColor whiteColor] blendedColorWithFraction: percent ofColor: fullColor];
179             fPieces[index] = PIECE_SOME;
180         }
181         
182         if (pieceColor)
183         {
184             const NSInteger across = index % fAcross,
185                             down = index / fAcross;
186             fillRects[usedCount] = NSMakeRect(across * (fWidth + BETWEEN) + BETWEEN + fExtraBorder,
187                                                 [image size].width - (down + 1) * (fWidth + BETWEEN) - fExtraBorder,
188                                                 fWidth, fWidth);
189             fillColors[usedCount] = pieceColor;
190             
191             usedCount++;
192         }
193     }
194     
195     if (usedCount > 0)
196     {
197         [image lockFocus];
198         NSRectFillListWithColors(fillRects, fillColors, usedCount);
199         [image unlockFocus];
200         [self setNeedsDisplay];
201     }
202     
203     tr_free(pieces);
204     tr_free(piecesPercent);
207 - (BOOL) acceptsFirstMouse: (NSEvent *) event
209     return YES;
212 - (void) mouseDown: (NSEvent *) event
214     if (fTorrent)
215     {
216         const BOOL availability = ![[NSUserDefaults standardUserDefaults] boolForKey: @"PiecesViewShowAvailability"];
217         [[NSUserDefaults standardUserDefaults] setBool: availability forKey: @"PiecesViewShowAvailability"];
218         
219         [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdatePiecesView" object: self];
220     }
221     
222     [super mouseDown: event];
225 @end