ProgressCell.m (7263B)
1 /****************************************************************************** 2 * Copyright 2008, 2016 (see file COPYING for more information) 3 * 4 * Loosely based on TorrentCell from Transmission (.png files are from 5 * the original). 6 *****************************************************************************/ 7 8 #import "ProgressCell.h" 9 10 #define BAR_HEIGHT 12.0 11 12 static NSImage *_ProgressWhite, *_ProgressBlue, *_ProgressGray, *_ProgressGreen, 13 *_ProgressAdvanced, *_ProgressEndWhite, *_ProgressEndBlue, 14 *_ProgressEndGray, *_ProgressEndGreen, *_ProgressLightGreen, 15 *_ProgressEndAdvanced, * _ErrorImage; 16 static NSSize ZeroSize; 17 18 @implementation ProgressCell 19 20 + (void) initialize 21 { 22 NSSize startSize = NSMakeSize(100.0, BAR_HEIGHT); 23 ZeroSize = NSMakeSize(0.0, 0.0); 24 25 _ProgressWhite = [NSImage imageNamed: @"ProgressBarWhite.png"]; 26 [_ProgressWhite setScalesWhenResized: YES]; 27 28 _ProgressBlue = [NSImage imageNamed: @"ProgressBarBlue.png"]; 29 [_ProgressBlue setScalesWhenResized: YES]; 30 [_ProgressBlue setSize: startSize]; 31 32 _ProgressGray = [NSImage imageNamed: @"ProgressBarGray.png"]; 33 [_ProgressGray setScalesWhenResized: YES]; 34 [_ProgressGray setSize: startSize]; 35 36 _ProgressGreen = [NSImage imageNamed: @"ProgressBarGreen.png"]; 37 [_ProgressGreen setScalesWhenResized: YES]; 38 39 _ProgressLightGreen = [NSImage imageNamed: @"ProgressBarLightGreen.png"]; 40 [_ProgressLightGreen setScalesWhenResized: YES]; 41 42 _ProgressAdvanced = [NSImage imageNamed: @"ProgressBarAdvanced.png"]; 43 [_ProgressAdvanced setScalesWhenResized: YES]; 44 45 _ProgressEndWhite = [NSImage imageNamed: @"ProgressBarEndWhite.png"]; 46 _ProgressEndBlue = [NSImage imageNamed: @"ProgressBarEndBlue.png"]; 47 _ProgressEndGray = [NSImage imageNamed: @"ProgressBarEndGray.png"]; 48 _ProgressEndGreen = [NSImage imageNamed: @"ProgressBarEndGreen.png"]; 49 _ProgressEndAdvanced = [NSImage imageNamed: @"ProgressBarEndAdvanced.png"]; 50 51 _ErrorImage = [[NSImage imageNamed: @"Error.tiff"] copy]; 52 [_ErrorImage setFlipped: YES]; 53 } 54 55 - (id)init 56 { 57 self = [super init]; 58 _minVal = 0.0; 59 _maxVal = 100.0; 60 _isActive = YES; 61 _statusString = @""; 62 63 return self; 64 } 65 66 - (void)dealloc 67 { 68 [_icon release]; 69 [_statusString release]; 70 [super dealloc]; 71 } 72 73 - (void)setStatusString:(NSString *)string 74 { 75 _statusString = [string retain]; 76 } 77 78 - (void)setIcon:(NSImage *)image 79 { 80 _icon = [image retain]; 81 } 82 83 - (void)setIsActive:(BOOL)yn 84 { 85 _isActive = yn; 86 } 87 88 - (void)drawBarImage:(NSImage *)barImage width:(float)width point:(NSPoint)point 89 { 90 if (width <= 0.0) 91 return; 92 93 if ([barImage size].width < width) 94 [barImage setSize: NSMakeSize(width * 2.0, BAR_HEIGHT)]; 95 96 [barImage compositeToPoint: point fromRect: NSMakeRect(0, 0, width, BAR_HEIGHT) operation: NSCompositeSourceOver]; 97 } 98 99 - (void)drawBar:(float)width point:(NSPoint)point 100 { 101 id objectValue = [self objectValue]; 102 if (!objectValue) return; 103 104 float value = [objectValue floatValue]; 105 float progress = (value - _minVal)/ (_maxVal - _minVal); 106 107 width -= 2.0; 108 float completedWidth, remainingWidth = 0.0; 109 110 //bar images and widths 111 NSImage * barLeftEnd, * barRightEnd, * barComplete, * barRemaining; 112 if (progress >= 1.0) { 113 completedWidth = width; 114 barLeftEnd = _ProgressEndGreen; 115 barRightEnd = _ProgressEndGreen; 116 barComplete = _ProgressGreen; 117 barRemaining = _ProgressLightGreen; 118 } 119 else { 120 completedWidth = progress * width; 121 remainingWidth = width - completedWidth; 122 barLeftEnd = (remainingWidth == width) ? _ProgressEndWhite 123 : ((_isActive) ? _ProgressEndBlue : _ProgressEndGray); 124 barRightEnd = (completedWidth < width) ? _ProgressEndWhite 125 : ((_isActive) ? _ProgressEndBlue : _ProgressEndGray); 126 barComplete = _isActive ? _ProgressBlue : _ProgressGray; 127 barRemaining = _ProgressWhite; 128 } 129 130 [barLeftEnd compositeToPoint: point operation: NSCompositeSourceOver]; 131 132 point.x += 1.0; 133 [self drawBarImage: barComplete width: completedWidth point: point]; 134 135 point.x += completedWidth; 136 [self drawBarImage: barRemaining width: remainingWidth point: point]; 137 138 point.x += remainingWidth; 139 [barRightEnd compositeToPoint: point operation: NSCompositeSourceOver]; 140 } 141 142 - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)view 143 { 144 NSPoint pen = cellFrame.origin; 145 const float PADDING = 3.0; 146 147 // progress bar 148 pen.y += PADDING + BAR_HEIGHT; 149 float mainWidth = cellFrame.size.width; 150 float barWidth = mainWidth; 151 [self drawBar: barWidth point: pen]; 152 153 //icon 154 NSImage * image = _isError ? _ErrorImage : _icon; 155 if (image) { 156 NSSize imageSize = [image size]; 157 NSRect imageFrame; 158 imageFrame.origin = cellFrame.origin; 159 imageFrame.size = imageSize; 160 imageFrame.origin.x += ceil((cellFrame.size.width - imageSize.width) / 2); 161 imageFrame.origin.y += [view isFlipped] ? 162 ceil((cellFrame.size.height + imageSize.height) / 2) 163 : ceil((cellFrame.size.height - imageSize.height) / 2); 164 [image compositeToPoint:imageFrame.origin operation:NSCompositeSourceOver]; 165 } 166 167 // status string 168 if (_statusString) { 169 BOOL highlighted = [self isHighlighted] && [[self highlightColorWithFrame: cellFrame inView: view] 170 isEqual: [NSColor alternateSelectedControlColor]]; 171 NSMutableParagraphStyle * paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 172 [paragraphStyle setLineBreakMode: NSLineBreakByTruncatingTail]; 173 174 NSDictionary * statusAttributes = [[NSDictionary alloc] initWithObjectsAndKeys: 175 highlighted ? [NSColor whiteColor] : [NSColor darkGrayColor], NSForegroundColorAttributeName, 176 [NSFont boldSystemFontOfSize: 9.0], NSFontAttributeName, 177 paragraphStyle, NSParagraphStyleAttributeName, nil]; 178 [paragraphStyle release]; 179 180 NSSize statusSize = [_statusString sizeWithAttributes: statusAttributes]; 181 pen = cellFrame.origin; 182 pen.x += (cellFrame.size.width - statusSize.width) * 0.5; 183 pen.y += (cellFrame.size.height - statusSize.height) * 0.5; 184 185 [_statusString drawInRect: NSMakeRect(pen.x, pen.y, statusSize.width, statusSize.height) 186 withAttributes: statusAttributes]; 187 [statusAttributes release]; 188 } 189 } 190 191 - (id)copyWithZone: (NSZone *)zone 192 { 193 ProgressCell *newObj = [super copyWithZone: zone]; 194 newObj->_statusString = [_statusString retain]; 195 newObj->_icon = [_icon retain]; 196 return newObj; 197 } 198 199 @end