| 258 | | - (NSBezierPath *)arrowPathInSize:(NSSize)arrowSize pointingDown:(BOOL)pointItDown |
|---|
| 259 | | { |
|---|
| 260 | | if(!arrowPath) { |
|---|
| 261 | | arrowPath = [[NSBezierPath bezierPath] retain]; |
|---|
| 262 | | |
|---|
| 263 | | /* 5 |
|---|
| 264 | | * / \ |
|---|
| 265 | | * / \ 1-7 = points |
|---|
| 266 | | *6-7 3-4 the point of the triangle is 100% from the bottom. |
|---|
| 267 | | * | the back edge of the triangle is 50% from the bottom. |
|---|
| 268 | | * 1-2 |
|---|
| 269 | | */ |
|---|
| 270 | | |
|---|
| 271 | | # define ONE_THIRD (1.0/3.0) |
|---|
| 272 | | # define TWO_THIRDS (2.0/3.0) |
|---|
| 273 | | # define ONE_HALF 0.5 |
|---|
| 274 | | |
|---|
| 275 | | //start with the bottom vertex. |
|---|
| 276 | | [arrowPath moveToPoint:NSMakePoint(ONE_THIRD, 0.0)]; //1 |
|---|
| 277 | | [arrowPath lineToPoint:NSMakePoint(TWO_THIRDS, 0.0)]; //2 |
|---|
| 278 | | //up to the inner right corner. |
|---|
| 279 | | [arrowPath relativeLineToPoint:NSMakePoint(0.0, ONE_HALF)]; //3 |
|---|
| 280 | | //far right. |
|---|
| 281 | | [arrowPath relativeLineToPoint:NSMakePoint(ONE_THIRD, 0.0)]; //4 |
|---|
| 282 | | //top center - the point of the arrow. |
|---|
| 283 | | [arrowPath lineToPoint:NSMakePoint(ONE_HALF, 1.0)]; //5 |
|---|
| 284 | | //far left. |
|---|
| 285 | | [arrowPath lineToPoint:NSMakePoint(0.0, ONE_HALF)]; //6 |
|---|
| 286 | | //inner left corner. |
|---|
| 287 | | [arrowPath relativeLineToPoint:NSMakePoint(ONE_THIRD, 0.0)]; //7 |
|---|
| 288 | | //to the finish line! yay! |
|---|
| 289 | | [arrowPath closePath]; |
|---|
| 290 | | } |
|---|
| 291 | | |
|---|
| 292 | | NSBezierPath *path = [arrowPath copy]; |
|---|
| 293 | | |
|---|
| 294 | | NSAffineTransform *transform = [NSAffineTransform transform]; |
|---|
| 295 | | |
|---|
| 296 | | if(pointItDown) { |
|---|
| 297 | | //http://developer.apple.com/documentation/Carbon/Conceptual/QuickDrawToQuartz2D/tq_other/chapter_3_section_2.html |
|---|
| 298 | | [transform translateXBy:0.0 yBy:1.0]; |
|---|
| 299 | | [transform scaleXBy:1.0 yBy:-1.0]; |
|---|
| 300 | | |
|---|
| 301 | | [path transformUsingAffineTransform:transform]; |
|---|
| 302 | | |
|---|
| 303 | | transform = [NSAffineTransform transform]; |
|---|
| 304 | | } |
|---|
| 305 | | |
|---|
| 306 | | [transform scaleXBy:arrowSize.width yBy:arrowSize.height]; |
|---|
| 307 | | |
|---|
| 308 | | [path transformUsingAffineTransform:transform]; |
|---|
| 309 | | |
|---|
| 310 | | return [path autorelease]; |
|---|
| 311 | | } |
|---|
| 312 | | |
|---|
| 325 | | |
|---|
| 326 | | BOOL pointingDown = (type == Incoming_FileTransfer); |
|---|
| 327 | | BOOL drawArrow = pointingDown || (type == Outgoing_FileTransfer); |
|---|
| 328 | | |
|---|
| | 273 | NSString *badgeArrow = nil; |
|---|
| | 274 | NSFont *appleGothicFont = [NSFont fontWithName:@"AppleGothic" size:24]; |
|---|
| | 275 | |
|---|
| | 276 | switch (type) { |
|---|
| | 277 | case Incoming_FileTransfer: |
|---|
| | 278 | badgeArrow = DOWNLOAD_ARROW; |
|---|
| | 279 | break; |
|---|
| | 280 | case Outgoing_FileTransfer: |
|---|
| | 281 | badgeArrow = UPLOAD_ARROW; |
|---|
| | 282 | break; |
|---|
| | 283 | case Unknown_FileTransfer: |
|---|
| | 284 | default: |
|---|
| | 285 | break; |
|---|
| | 286 | } |
|---|
| | 287 | |
|---|
| | 288 | if (!badgeArrow || !appleGothicFont) |
|---|
| | 289 | return systemIcon; |
|---|
| | 290 | |
|---|
| 333 | | NSRect bottomRight = NSMakeRect(NSMidX(rect), |
|---|
| 334 | | ([iconImage isFlipped] ? NSMidY(rect) : NSMinY(rect)), |
|---|
| 335 | | (NSWidth(rect)/2.0), |
|---|
| 336 | | (NSHeight(rect)/2.0)); |
|---|
| 337 | | |
|---|
| | 295 | NSRect bottomRight = NSMakeRect(NSMidX(rect), ([iconImage isFlipped] ? NSMidY(rect) : NSMinY(rect)), (NSWidth(rect)/2.0), (NSHeight(rect)/2.0)); |
|---|
| | 296 | |
|---|
| | 297 | NSMutableDictionary *atts = [(NSMutableDictionary *)[[NSDictionary dictionaryWithObjectsAndKeys: |
|---|
| | 298 | [NSColor alternateSelectedControlColor], NSForegroundColorAttributeName, |
|---|
| | 299 | appleGothicFont, NSFontAttributeName, // AppleGothic has our arrow glyphs |
|---|
| | 300 | nil] mutableCopy] autorelease]; |
|---|
| | 301 | |
|---|
| | 302 | NSSize arrowSize = [badgeArrow sizeWithAttributes:atts]; |
|---|
| | 303 | while (arrowSize.height > NSHeight(bottomRight)*0.9) { // shrink arrow to fit |
|---|
| | 304 | NSFont *tempFont = (NSFont *)[atts objectForKey:NSFontAttributeName]; |
|---|
| | 305 | [atts setObject:[NSFont fontWithName:[tempFont fontName] size:[tempFont pointSize]*0.99] forKey:NSFontAttributeName]; |
|---|
| | 306 | arrowSize = [badgeArrow sizeWithAttributes:atts]; |
|---|
| | 307 | } |
|---|
| | 308 | |
|---|
| 355 | | |
|---|
| 356 | | //and the arrow on top of it. |
|---|
| 357 | | if(drawArrow) { |
|---|
| 358 | | NSBezierPath *arrow = [self arrowPathInSize:bottomRight.size pointingDown:pointingDown]; |
|---|
| 359 | | |
|---|
| 360 | | //bring it into position. |
|---|
| 361 | | NSAffineTransform *transform = [NSAffineTransform transform]; |
|---|
| 362 | | [transform translateXBy:circleRect.origin.x yBy:circleRect.origin.y]; |
|---|
| 363 | | [arrow transformUsingAffineTransform:transform]; |
|---|
| 364 | | |
|---|
| 365 | | [[NSColor alternateSelectedControlColor] setFill]; |
|---|
| 366 | | [arrow fill]; |
|---|
| 367 | | } |
|---|
| | 325 | |
|---|
| | 326 | NSMutableParagraphStyle *mps = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; |
|---|
| | 327 | [mps setAlignment:NSCenterTextAlignment]; |
|---|
| | 328 | float lineheight = NSHeight(circleRect) * 0.99; |
|---|
| | 329 | [mps setMaximumLineHeight:lineheight]; |
|---|
| | 330 | [mps setMinimumLineHeight:lineheight]; |
|---|
| | 331 | [mps setLineHeightMultiple:lineheight]; |
|---|
| | 332 | [atts setObject:mps forKey:NSParagraphStyleAttributeName]; |
|---|
| | 333 | [mps release]; |
|---|
| | 334 | |
|---|
| | 335 | [badgeArrow drawInRect:circleRect withAttributes:atts]; |
|---|