1 /******************************************************************************
2 * $Id: PiecesView.m 13162 2012-01-14 17:12:04Z livings124 $
4 * Copyright (c) 2006-2012 Transmission authors and contributors
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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"
27 #import "InfoWindowController.h"
29 #import "transmission.h"
46 @implementation PiecesView
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];
54 //actually draw the box
55 [self setTorrent: nil];
62 [fGreenAvailabilityColor release];
63 [fBluePieceColor release];
68 - (void) setTorrent: (Torrent *) torrent
72 fTorrent = (torrent && ![torrent isMagnet]) ? torrent : nil;
75 //determine relevant values
76 fNumPieces = MIN([fTorrent pieceCount], MAX_ACROSS * MAX_ACROSS);
77 fAcross = ceil(sqrt(fNumPieces));
79 const CGFloat width = [self bounds].size.width;
80 fWidth = (width - (fAcross + 1) * BETWEEN) / fAcross;
81 fExtraBorder = (width - ((fWidth + BETWEEN) * fAcross + BETWEEN)) / 2;
84 NSImage * back = [[NSImage alloc] initWithSize: [self bounds].size];
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];
93 [self setImage: back];
96 [self setNeedsDisplay];
110 //determine if first time
111 const BOOL first = fPieces == NULL;
113 fPieces = (int8_t *)tr_malloc(fNumPieces * sizeof(int8_t));
115 int8_t * pieces = NULL;
116 float * piecesPercent = NULL;
118 const BOOL showAvailablity = [[NSUserDefaults standardUserDefaults] boolForKey: @"PiecesViewShowAvailability"];
121 pieces = (int8_t *)tr_malloc(fNumPieces * sizeof(int8_t));
122 [fTorrent getAvailability: pieces size: fNumPieces];
126 piecesPercent = (float *)tr_malloc(fNumPieces * sizeof(float));
127 [fTorrent getAmountFinished: piecesPercent size: fNumPieces];
130 NSImage * image = [self image];
132 NSRect fillRects[fNumPieces];
133 NSColor * fillColors[fNumPieces];
135 NSInteger usedCount = 0;
137 for (NSInteger index = 0; index < fNumPieces; index++)
139 NSColor * pieceColor = nil;
141 if (showAvailablity ? pieces[index] == -1 : piecesPercent[index] == 1.0)
143 if (first || fPieces[index] != PIECE_FINISHED)
145 if (!first && fPieces[index] != PIECE_FLASHING)
147 pieceColor = [NSColor orangeColor];
148 fPieces[index] = PIECE_FLASHING;
152 pieceColor = fBluePieceColor;
153 fPieces[index] = PIECE_FINISHED;
157 else if (showAvailablity ? pieces[index] == 0 : piecesPercent[index] == 0.0)
159 if (first || fPieces[index] != PIECE_NONE)
161 pieceColor = [NSColor whiteColor];
162 fPieces[index] = PIECE_NONE;
165 else if (showAvailablity && pieces[index] >= HIGH_PEERS)
167 if (first || fPieces[index] != PIECE_HIGH_PEERS)
169 pieceColor = fGreenAvailabilityColor;
170 fPieces[index] = PIECE_HIGH_PEERS;
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;
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,
189 fillColors[usedCount] = pieceColor;
198 NSRectFillListWithColors(fillRects, fillColors, usedCount);
200 [self setNeedsDisplay];
204 tr_free(piecesPercent);
207 - (BOOL) acceptsFirstMouse: (NSEvent *) event
212 - (void) mouseDown: (NSEvent *) event
216 const BOOL availability = ![[NSUserDefaults standardUserDefaults] boolForKey: @"PiecesViewShowAvailability"];
217 [[NSUserDefaults standardUserDefaults] setBool: availability forKey: @"PiecesViewShowAvailability"];
219 [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdatePiecesView" object: self];
222 [super mouseDown: event];