| | 270 | - (NSBezierPath *)arrowPathInSize:(NSSize)arrowSize pointingDown:(BOOL)pointItDown |
|---|
| | 271 | { |
|---|
| | 272 | if(!arrowPath) { |
|---|
| | 273 | arrowPath = [[NSBezierPath bezierPath] retain]; |
|---|
| | 274 | |
|---|
| | 275 | /* 5 |
|---|
| | 276 | * / \ |
|---|
| | 277 | * / \ 1-7 = points |
|---|
| | 278 | *6-7 3-4 the point of the triangle is 100% from the bottom. |
|---|
| | 279 | * | the back edge of the triangle is 50% from the bottom. |
|---|
| | 280 | * 1-2 |
|---|
| | 281 | */ |
|---|
| | 282 | |
|---|
| | 283 | # define ONE_THIRD (1.0/3.0) |
|---|
| | 284 | # define TWO_THIRDS (2.0/3.0) |
|---|
| | 285 | # define ONE_HALF 0.5 |
|---|
| | 286 | |
|---|
| | 287 | //start with the bottom vertex. |
|---|
| | 288 | [arrowPath moveToPoint:NSMakePoint(ONE_THIRD, 0.0)]; //1 |
|---|
| | 289 | [arrowPath lineToPoint:NSMakePoint(TWO_THIRDS, 0.0)]; //2 |
|---|
| | 290 | //up to the inner right corner. |
|---|
| | 291 | [arrowPath relativeLineToPoint:NSMakePoint(0.0, ONE_HALF)]; //3 |
|---|
| | 292 | //far right. |
|---|
| | 293 | [arrowPath relativeLineToPoint:NSMakePoint(ONE_THIRD, 0.0)]; //4 |
|---|
| | 294 | //top center - the point of the arrow. |
|---|
| | 295 | [arrowPath lineToPoint:NSMakePoint(ONE_HALF, 1.0)]; //5 |
|---|
| | 296 | //far left. |
|---|
| | 297 | [arrowPath lineToPoint:NSMakePoint(0.0, ONE_HALF)]; //6 |
|---|
| | 298 | //inner left corner. |
|---|
| | 299 | [arrowPath relativeLineToPoint:NSMakePoint(ONE_THIRD, 0.0)]; //7 |
|---|
| | 300 | //to the finish line! yay! |
|---|
| | 301 | [arrowPath closePath]; |
|---|
| | 302 | } |
|---|
| | 303 | |
|---|
| | 304 | NSBezierPath *path = [arrowPath copy]; |
|---|
| | 305 | |
|---|
| | 306 | NSAffineTransform *transform = [NSAffineTransform transform]; |
|---|
| | 307 | |
|---|
| | 308 | if(pointItDown) { |
|---|
| | 309 | //http://developer.apple.com/documentation/Carbon/Conceptual/QuickDrawToQuartz2D/tq_other/chapter_3_section_2.html |
|---|
| | 310 | NSLog(@"arrow bounds (before): %@", NSStringFromRect([path bounds])); |
|---|
| | 311 | [transform translateXBy:0.0 yBy:1.0]; |
|---|
| | 312 | [transform scaleXBy:1.0 yBy:-1.0]; |
|---|
| | 313 | |
|---|
| | 314 | [path transformUsingAffineTransform:transform]; |
|---|
| | 315 | |
|---|
| | 316 | NSLog(@"arrow bounds (after transform): %@", NSStringFromRect([path bounds])); |
|---|
| | 317 | |
|---|
| | 318 | transform = [NSAffineTransform transform]; |
|---|
| | 319 | } |
|---|
| | 320 | |
|---|
| | 321 | NSLog(@"arrowSize: %@", NSStringFromSize(arrowSize)); |
|---|
| | 322 | [transform scaleXBy:arrowSize.width yBy:arrowSize.height]; |
|---|
| | 323 | |
|---|
| | 324 | [path transformUsingAffineTransform:transform]; |
|---|
| | 325 | |
|---|
| | 326 | return [path autorelease]; |
|---|
| | 327 | } |
|---|
| | 328 | |
|---|
| 285 | | NSString *badgeArrow = nil; |
|---|
| 286 | | NSFont *appleGothicFont = [NSFont fontWithName:@"AppleGothic" size:24]; |
|---|
| 287 | | |
|---|
| 288 | | switch (type) { |
|---|
| 289 | | case Incoming_FileTransfer: |
|---|
| 290 | | badgeArrow = DOWNLOAD_ARROW; |
|---|
| 291 | | break; |
|---|
| 292 | | case Outgoing_FileTransfer: |
|---|
| 293 | | badgeArrow = UPLOAD_ARROW; |
|---|
| 294 | | break; |
|---|
| 295 | | case Unknown_FileTransfer: |
|---|
| 296 | | default: |
|---|
| 297 | | break; |
|---|
| 298 | | } |
|---|
| 299 | | |
|---|
| 300 | | if (!badgeArrow || !appleGothicFont) |
|---|
| 301 | | return systemIcon; |
|---|
| 302 | | |
|---|
| | 341 | |
|---|
| | 342 | BOOL pointingDown = (type == Incoming_FileTransfer); |
|---|
| | 343 | BOOL drawArrow = pointingDown || (type == Outgoing_FileTransfer); |
|---|
| | 344 | |
|---|
| 312 | | NSMutableDictionary *atts = [(NSMutableDictionary *)[[NSDictionary dictionaryWithObjectsAndKeys: |
|---|
| 313 | | [NSColor alternateSelectedControlColor], NSForegroundColorAttributeName, |
|---|
| 314 | | appleGothicFont, NSFontAttributeName, // AppleGothic has our arrow glyphs |
|---|
| 315 | | nil] mutableCopy] autorelease]; |
|---|
| 316 | | |
|---|
| 317 | | NSSize arrowSize = [badgeArrow sizeWithAttributes:atts]; |
|---|
| 318 | | while (arrowSize.height > NSHeight(bottomRight)*0.9) { // shrink arrow to fit |
|---|
| 319 | | NSFont *tempFont = (NSFont *)[atts objectForKey:NSFontAttributeName]; |
|---|
| 320 | | [atts setObject:[NSFont fontWithName:[tempFont fontName] size:[tempFont pointSize]*0.99] forKey:NSFontAttributeName]; |
|---|
| 321 | | arrowSize = [badgeArrow sizeWithAttributes:atts]; |
|---|
| 322 | | } |
|---|
| 323 | | |
|---|
| 340 | | |
|---|
| 341 | | NSMutableParagraphStyle *mps = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; |
|---|
| 342 | | [mps setAlignment:NSCenterTextAlignment]; |
|---|
| 343 | | float lineheight = NSHeight(circleRect) * 0.99; |
|---|
| 344 | | [mps setMaximumLineHeight:lineheight]; |
|---|
| 345 | | [mps setMinimumLineHeight:lineheight]; |
|---|
| 346 | | [mps setLineHeightMultiple:lineheight]; |
|---|
| 347 | | [atts setObject:mps forKey:NSParagraphStyleAttributeName]; |
|---|
| 348 | | [mps release]; |
|---|
| 349 | | |
|---|
| 350 | | [badgeArrow drawInRect:circleRect withAttributes:atts]; |
|---|
| | 371 | |
|---|
| | 372 | //and the arrow on top of it. |
|---|
| | 373 | if(drawArrow) { |
|---|
| | 374 | NSBezierPath *arrow = [self arrowPathInSize:bottomRight.size pointingDown:pointingDown]; |
|---|
| | 375 | |
|---|
| | 376 | //bring it into position. |
|---|
| | 377 | NSAffineTransform *transform = [NSAffineTransform transform]; |
|---|
| | 378 | [transform translateXBy:circleRect.origin.x yBy:circleRect.origin.y]; |
|---|
| | 379 | [arrow transformUsingAffineTransform:transform]; |
|---|
| | 380 | |
|---|
| | 381 | NSLog(@"arrow bounds (after): %@", NSStringFromRect([arrow bounds])); |
|---|
| | 382 | [[NSColor alternateSelectedControlColor] setFill]; |
|---|
| | 383 | [arrow fill]; |
|---|
| | 384 | } |
|---|