| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/cocoa/download_item_cell.h" | 5 #import "chrome/browser/cocoa/download_item_cell.h" |
| 6 | 6 |
| 7 #include "app/gfx/canvas_paint.h" | 7 #include "app/gfx/canvas_paint.h" |
| 8 #include "app/gfx/text_elider.h" | 8 #include "app/gfx/text_elider.h" |
| 9 #include "app/l10n_util.h" | 9 #include "app/l10n_util.h" |
| 10 #include "base/mac_util.h" | 10 #include "base/mac_util.h" |
| 11 #include "base/sys_string_conversions.h" | 11 #include "base/sys_string_conversions.h" |
| 12 #import "chrome/browser/cocoa/download_item_cell.h" | 12 #import "chrome/browser/cocoa/download_item_cell.h" |
| 13 #include "chrome/browser/download/download_item_model.h" | 13 #include "chrome/browser/download/download_item_model.h" |
| 14 #include "chrome/browser/download/download_manager.h" | 14 #include "chrome/browser/download/download_manager.h" |
| 15 #include "chrome/browser/download/download_util.h" | 15 #include "chrome/browser/download/download_util.h" |
| 16 #import "third_party/GTM/AppKit/GTMTheme.h" | 16 #import "third_party/GTM/AppKit/GTMTheme.h" |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 // Distance from top border to icon | 20 // Distance from top border to icon |
| 21 const CGFloat kImagePaddingTop = 7; | 21 const CGFloat kImagePaddingTop = 7; |
| 22 | 22 |
| 23 // Distance from left border to icon | 23 // Distance from left border to icon |
| 24 const CGFloat kImagePaddingLeft = 8; | 24 const CGFloat kImagePaddingLeft = 9; |
| 25 | 25 |
| 26 // Width of icon | 26 // Width of icon |
| 27 const CGFloat kImageWidth = 16; | 27 const CGFloat kImageWidth = 16; |
| 28 | 28 |
| 29 // Height of icon | 29 // Height of icon |
| 30 const CGFloat kImageHeight = 16; | 30 const CGFloat kImageHeight = 16; |
| 31 | 31 |
| 32 // x coordinate of download name string, in view coords | 32 // x coordinate of download name string, in view coords |
| 33 const CGFloat kTextPosLeft = kImagePaddingLeft + | 33 const CGFloat kTextPosLeft = kImagePaddingLeft + |
| 34 kImageWidth + download_util::kSmallProgressIconOffset; | 34 kImageWidth + download_util::kSmallProgressIconOffset; |
| 35 | 35 |
| 36 // Distance from end of download name string to dropdown area | 36 // Distance from end of download name string to dropdown area |
| 37 const CGFloat kTextPaddingRight = 3; | 37 const CGFloat kTextPaddingRight = 3; |
| 38 | 38 |
| 39 // y coordinate of download name string, in view coords, when status message | 39 // y coordinate of download name string, in view coords, when status message |
| 40 // is visible | 40 // is visible |
| 41 const CGFloat kPrimaryTextPosTop = 5; | 41 const CGFloat kPrimaryTextPosTop = 3; |
| 42 | 42 |
| 43 // y coordinate of download name string, in view coords, when status message | 43 // y coordinate of download name string, in view coords, when status message |
| 44 // is not visible | 44 // is not visible |
| 45 const CGFloat kPrimaryTextOnlyPosTop = 10; | 45 const CGFloat kPrimaryTextOnlyPosTop = 10; |
| 46 | 46 |
| 47 // y coordinate of status message, in view coords | 47 // y coordinate of status message, in view coords |
| 48 const CGFloat kSecondaryTextPosTop = 17; | 48 const CGFloat kSecondaryTextPosTop = 18; |
| 49 |
| 50 // Grey value of status text |
| 51 const CGFloat kSecondaryTextColor = 0.5; |
| 49 | 52 |
| 50 // Width of dropdown area on the right (includes 1px for the border on each | 53 // Width of dropdown area on the right (includes 1px for the border on each |
| 51 // side). | 54 // side). |
| 52 const CGFloat kDropdownAreaWidth = 14; | 55 const CGFloat kDropdownAreaWidth = 14; |
| 53 | 56 |
| 54 // Width of dropdown arrow | 57 // Width of dropdown arrow |
| 55 const CGFloat kDropdownArrowWidth = 5; | 58 const CGFloat kDropdownArrowWidth = 5; |
| 56 | 59 |
| 57 // Height of dropdown arrow | 60 // Height of dropdown arrow |
| 58 const CGFloat kDropdownArrowHeight = 3; | 61 const CGFloat kDropdownArrowHeight = 3; |
| 59 | 62 |
| 63 // Vertical displacement of dropdown area, relative to the "centered" position. |
| 64 const CGFloat kDropdownAreaY = -2; |
| 65 |
| 60 // Duration of the two-lines-to-one-line animation, in seconds | 66 // Duration of the two-lines-to-one-line animation, in seconds |
| 61 NSTimeInterval kHideStatusDuration = 0.3; | 67 NSTimeInterval kHideStatusDuration = 0.3; |
| 62 | 68 |
| 63 // Duration of the 'download complete' animation, in seconds | 69 // Duration of the 'download complete' animation, in seconds |
| 64 const int kCompleteAnimationDuration = 2.5; | 70 const int kCompleteAnimationDuration = 2.5; |
| 65 | 71 |
| 66 } | 72 } |
| 67 | 73 |
| 68 // This is a helper class to animate the fading out of the status text. | 74 // This is a helper class to animate the fading out of the status text. |
| 69 @interface DownloadItemCellAnimation : NSAnimation { | 75 @interface DownloadItemCellAnimation : NSAnimation { |
| 70 DownloadItemCell* cell_; | 76 DownloadItemCell* cell_; |
| 71 } | 77 } |
| 72 - (id)initWithDownloadItemCell:(DownloadItemCell*)cell | 78 - (id)initWithDownloadItemCell:(DownloadItemCell*)cell |
| 73 duration:(NSTimeInterval)duration | 79 duration:(NSTimeInterval)duration |
| 74 animationCurve:(NSAnimationCurve)animationCurve; | 80 animationCurve:(NSAnimationCurve)animationCurve; |
| 75 @end | 81 @end |
| 76 | 82 |
| 77 @interface DownloadItemCell(Private) | 83 @interface DownloadItemCell(Private) |
| 78 - (void)updateTrackingAreas:(id)sender; | 84 - (void)updateTrackingAreas:(id)sender; |
| 79 - (void)hideSecondaryTitle; | 85 - (void)hideSecondaryTitle; |
| 80 - (void)animation:(NSAnimation*)animation | 86 - (void)animation:(NSAnimation*)animation |
| 81 progressed:(NSAnimationProgress)progress; | 87 progressed:(NSAnimationProgress)progress; |
| 88 - (NSString*)elideTitle:(int)availableWidth; |
| 89 - (NSString*)elideStatus:(int)availableWidth; |
| 82 @end | 90 @end |
| 83 | 91 |
| 84 @implementation DownloadItemCell | 92 @implementation DownloadItemCell |
| 85 | 93 |
| 86 @synthesize secondaryTitle = secondaryTitle_; | 94 @synthesize secondaryTitle = secondaryTitle_; |
| 87 @synthesize secondaryFont = secondaryFont_; | 95 @synthesize secondaryFont = secondaryFont_; |
| 88 | 96 |
| 89 - (void)setInitialState { | 97 - (void)setInitialState { |
| 90 isStatusTextVisible_ = NO; | 98 isStatusTextVisible_ = NO; |
| 91 titleY_ = kPrimaryTextPosTop; | 99 titleY_ = kPrimaryTextPosTop; |
| 92 statusAlpha_ = 1.0; | 100 statusAlpha_ = 1.0; |
| 93 | 101 |
| 94 [self setFont:[NSFont systemFontOfSize: | 102 [self setFont:[NSFont systemFontOfSize: |
| 95 [NSFont systemFontSizeForControlSize:NSSmallControlSize]]]; | 103 [NSFont systemFontSizeForControlSize:NSSmallControlSize]]]; |
| 96 [self setSecondaryFont:[NSFont systemFontOfSize: | 104 [self setSecondaryFont:[NSFont systemFontOfSize: |
| 97 [NSFont systemFontSizeForControlSize:NSMiniControlSize]]]; | 105 [NSFont systemFontSizeForControlSize:NSSmallControlSize]]]; |
| 98 | 106 |
| 99 [self updateTrackingAreas:self]; | 107 [self updateTrackingAreas:self]; |
| 100 [[NSNotificationCenter defaultCenter] | 108 [[NSNotificationCenter defaultCenter] |
| 101 addObserver:self | 109 addObserver:self |
| 102 selector:@selector(updateTrackingAreas:) | 110 selector:@selector(updateTrackingAreas:) |
| 103 name:NSViewFrameDidChangeNotification | 111 name:NSViewFrameDidChangeNotification |
| 104 object:[self controlView]]; | 112 object:[self controlView]]; |
| 105 } | 113 } |
| 106 | 114 |
| 107 // For nib instantiations | 115 // For nib instantiations |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 | 286 |
| 279 NSBezierPath* path = [NSBezierPath bezierPath]; | 287 NSBezierPath* path = [NSBezierPath bezierPath]; |
| 280 [path moveToPoint:rect.origin]; | 288 [path moveToPoint:rect.origin]; |
| 281 [path appendBezierPathWithArcFromPoint:bottomRight | 289 [path appendBezierPathWithArcFromPoint:bottomRight |
| 282 toPoint:topRight | 290 toPoint:topRight |
| 283 radius:radius]; | 291 radius:radius]; |
| 284 [path appendBezierPathWithArcFromPoint:topRight | 292 [path appendBezierPathWithArcFromPoint:topRight |
| 285 toPoint:topLeft | 293 toPoint:topLeft |
| 286 radius:radius]; | 294 radius:radius]; |
| 287 [path lineToPoint:topLeft]; | 295 [path lineToPoint:topLeft]; |
| 288 [path closePath]; // Right path is closed | |
| 289 return path; | 296 return path; |
| 290 } | 297 } |
| 291 | 298 |
| 292 - (void)elideTitle:(int)availableWidth { | 299 - (NSString*)elideTitle:(int)availableWidth { |
| 293 NSFont* font = [self font]; | 300 NSFont* font = [self font]; |
| 294 gfx::Font font_chr = | 301 gfx::Font font_chr = |
| 295 gfx::Font::CreateFont(base::SysNSStringToWide([font fontName]), | 302 gfx::Font::CreateFont(base::SysNSStringToWide([font fontName]), |
| 296 [font pointSize]); | 303 [font pointSize]); |
| 297 | 304 |
| 298 NSString* titleString = base::SysWideToNSString( | 305 return base::SysWideToNSString( |
| 299 ElideFilename(downloadPath_, font_chr, availableWidth)); | 306 ElideFilename(downloadPath_, font_chr, availableWidth)); |
| 300 [self setTitle:titleString]; | 307 } |
| 308 |
| 309 - (NSString*)elideStatus:(int)availableWidth { |
| 310 NSFont* font = [self secondaryFont]; |
| 311 gfx::Font font_chr = |
| 312 gfx::Font::CreateFont(base::SysNSStringToWide([font fontName]), |
| 313 [font pointSize]); |
| 314 |
| 315 return base::SysWideToNSString(ElideText( |
| 316 base::SysNSStringToWide([self secondaryTitle]), |
| 317 font_chr, |
| 318 availableWidth)); |
| 301 } | 319 } |
| 302 | 320 |
| 303 - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { | 321 - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { |
| 304 // Constants from Cole. Will kConstant them once the feedback loop | 322 // Constants from Cole. Will kConstant them once the feedback loop |
| 305 // is complete. | 323 // is complete. |
| 306 NSRect drawFrame = NSInsetRect(cellFrame, 1.5, 1.5); | 324 NSRect drawFrame = NSInsetRect(cellFrame, 1.5, 1.5); |
| 307 NSRect innerFrame = NSInsetRect(cellFrame, 2, 2); | 325 NSRect innerFrame = NSInsetRect(cellFrame, 2, 2); |
| 308 | 326 |
| 309 const float radius = 5; | 327 const float radius = 5; |
| 310 NSWindow* window = [controlView window]; | 328 NSWindow* window = [controlView window]; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 showHighlightGradient:[self isMouseOverDropdownPart] | 365 showHighlightGradient:[self isMouseOverDropdownPart] |
| 348 hoverAlpha:0.0 | 366 hoverAlpha:0.0 |
| 349 active:active | 367 active:active |
| 350 cellFrame:cellFrame]; | 368 cellFrame:cellFrame]; |
| 351 | 369 |
| 352 [self drawInteriorWithFrame:innerFrame inView:controlView]; | 370 [self drawInteriorWithFrame:innerFrame inView:controlView]; |
| 353 } | 371 } |
| 354 | 372 |
| 355 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { | 373 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { |
| 356 // Draw title | 374 // Draw title |
| 357 [self elideTitle:cellFrame.size.width - | 375 CGFloat textWidth = cellFrame.size.width - |
| 358 (kTextPosLeft + kTextPaddingRight + kDropdownAreaWidth)]; | 376 (kTextPosLeft + kTextPaddingRight + kDropdownAreaWidth); |
| 377 [self setTitle:[self elideTitle:textWidth]]; |
| 378 |
| 379 NSColor* themeTextColor = [[[self controlView] gtm_theme] |
| 380 textColorForStyle:GTMThemeStyleBookmarksBarButton |
| 381 state:GTMThemeStateActiveWindow]; |
| 359 | 382 |
| 360 NSColor* color = [self isButtonPartPressed] | 383 NSColor* color = [self isButtonPartPressed] |
| 361 ? [NSColor alternateSelectedControlTextColor] : [NSColor textColor]; | 384 ? [NSColor alternateSelectedControlTextColor] : themeTextColor; |
| 362 NSString* primaryText = [self title]; | 385 NSString* primaryText = [self title]; |
| 363 | 386 |
| 364 NSDictionary* primaryTextAttributes = [NSDictionary | 387 NSDictionary* primaryTextAttributes = [NSDictionary |
| 365 dictionaryWithObjectsAndKeys: | 388 dictionaryWithObjectsAndKeys: |
| 366 color, NSForegroundColorAttributeName, | 389 color, NSForegroundColorAttributeName, |
| 367 [self font], NSFontAttributeName, | 390 [self font], NSFontAttributeName, |
| 368 nil]; | 391 nil]; |
| 369 NSPoint primaryPos = NSMakePoint( | 392 NSPoint primaryPos = NSMakePoint( |
| 370 cellFrame.origin.x + kTextPosLeft, | 393 cellFrame.origin.x + kTextPosLeft, |
| 371 titleY_); | 394 titleY_); |
| 372 | 395 |
| 373 [primaryText drawAtPoint:primaryPos withAttributes:primaryTextAttributes]; | 396 [primaryText drawAtPoint:primaryPos withAttributes:primaryTextAttributes]; |
| 374 | 397 |
| 375 // Draw secondary title, if any | 398 // Draw secondary title, if any |
| 376 if ([self secondaryTitle] != nil && statusAlpha_ > 0) { | 399 if ([self secondaryTitle] != nil && statusAlpha_ > 0) { |
| 377 NSString* secondaryText = [self secondaryTitle]; | 400 NSString* secondaryText = [self elideStatus:textWidth]; |
| 378 NSColor* secondaryColor = [color colorWithAlphaComponent:statusAlpha_]; | 401 NSColor* secondaryColor = [NSColor colorWithDeviceWhite:kSecondaryTextColor |
| 402 alpha:statusAlpha_]; |
| 379 NSDictionary* secondaryTextAttributes = [NSDictionary | 403 NSDictionary* secondaryTextAttributes = [NSDictionary |
| 380 dictionaryWithObjectsAndKeys: | 404 dictionaryWithObjectsAndKeys: |
| 381 secondaryColor, NSForegroundColorAttributeName, | 405 secondaryColor, NSForegroundColorAttributeName, |
| 382 [self secondaryFont], NSFontAttributeName, | 406 [self secondaryFont], NSFontAttributeName, |
| 383 nil]; | 407 nil]; |
| 384 NSPoint secondaryPos = NSMakePoint( | 408 NSPoint secondaryPos = NSMakePoint( |
| 385 cellFrame.origin.x + kTextPosLeft, | 409 cellFrame.origin.x + kTextPosLeft, |
| 386 kSecondaryTextPosTop); | 410 kSecondaryTextPosTop); |
| 387 [secondaryText drawAtPoint:secondaryPos | 411 [secondaryText drawAtPoint:secondaryPos |
| 388 withAttributes:secondaryTextAttributes]; | 412 withAttributes:secondaryTextAttributes]; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 | 447 |
| 424 // Draw icon | 448 // Draw icon |
| 425 NSRect imageRect = NSZeroRect; | 449 NSRect imageRect = NSZeroRect; |
| 426 imageRect.size = [[self image] size]; | 450 imageRect.size = [[self image] size]; |
| 427 [[self image] setFlipped:[controlView isFlipped]]; | 451 [[self image] setFlipped:[controlView isFlipped]]; |
| 428 [[self image] drawInRect:[self imageRectForBounds:cellFrame] | 452 [[self image] drawInRect:[self imageRectForBounds:cellFrame] |
| 429 fromRect:imageRect | 453 fromRect:imageRect |
| 430 operation:NSCompositeSourceOver | 454 operation:NSCompositeSourceOver |
| 431 fraction:[self isEnabled] ? 1.0 : 0.5]; | 455 fraction:[self isEnabled] ? 1.0 : 0.5]; |
| 432 | 456 |
| 457 // Separator between button and popup parts |
| 458 CGFloat lx = NSMaxX(cellFrame) - kDropdownAreaWidth + 0.5; |
| 459 [[NSColor colorWithDeviceWhite:0.0 alpha:0.1] set]; |
| 460 [NSBezierPath strokeLineFromPoint:NSMakePoint(lx, NSMinY(cellFrame) + 1) |
| 461 toPoint:NSMakePoint(lx, NSMaxY(cellFrame) - 1)]; |
| 462 [[NSColor colorWithDeviceWhite:1.0 alpha:0.1] set]; |
| 463 [NSBezierPath strokeLineFromPoint:NSMakePoint(lx + 1, NSMinY(cellFrame) + 1) |
| 464 toPoint:NSMakePoint(lx + 1, NSMaxY(cellFrame) - 1)]; |
| 465 |
| 433 // Popup arrow. Put center of mass of the arrow in the center of the | 466 // Popup arrow. Put center of mass of the arrow in the center of the |
| 434 // dropdown area. | 467 // dropdown area. |
| 435 CGFloat cx = NSMaxX(cellFrame) - kDropdownAreaWidth/2 + 0.5; | 468 CGFloat cx = NSMaxX(cellFrame) - kDropdownAreaWidth/2 + 0.5; |
| 436 CGFloat cy = NSMidY(cellFrame); | 469 CGFloat cy = NSMidY(cellFrame); |
| 437 NSPoint p1 = NSMakePoint(cx - kDropdownArrowWidth/2, | 470 NSPoint p1 = NSMakePoint(cx - kDropdownArrowWidth/2, |
| 438 cy - kDropdownArrowHeight/3); | 471 cy - kDropdownArrowHeight/3 + kDropdownAreaY); |
| 439 NSPoint p2 = NSMakePoint(cx + kDropdownArrowWidth/2, | 472 NSPoint p2 = NSMakePoint(cx + kDropdownArrowWidth/2, |
| 440 cy - kDropdownArrowHeight/3); | 473 cy - kDropdownArrowHeight/3 + kDropdownAreaY); |
| 441 NSPoint p3 = NSMakePoint(cx, cy + kDropdownArrowHeight*2/3); | 474 NSPoint p3 = NSMakePoint(cx, cy + kDropdownArrowHeight*2/3 + kDropdownAreaY); |
| 442 NSBezierPath *triangle = [NSBezierPath bezierPath]; | 475 NSBezierPath *triangle = [NSBezierPath bezierPath]; |
| 443 [triangle moveToPoint:p1]; | 476 [triangle moveToPoint:p1]; |
| 444 [triangle lineToPoint:p2]; | 477 [triangle lineToPoint:p2]; |
| 445 [triangle lineToPoint:p3]; | 478 [triangle lineToPoint:p3]; |
| 446 [triangle closePath]; | 479 [triangle closePath]; |
| 447 | 480 |
| 481 NSGraphicsContext* context = [NSGraphicsContext currentContext]; |
| 482 [context saveGraphicsState]; |
| 483 |
| 484 scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]); |
| 485 [shadow setShadowColor:[NSColor whiteColor]]; |
| 486 [shadow setShadowOffset:NSMakeSize(0, -1)]; |
| 487 [shadow setShadowBlurRadius:0.0]; |
| 488 [shadow set]; |
| 489 |
| 448 NSColor* fill = [self isDropdownPartPressed] | 490 NSColor* fill = [self isDropdownPartPressed] |
| 449 ? [NSColor alternateSelectedControlTextColor] : [NSColor textColor]; | 491 ? [NSColor alternateSelectedControlTextColor] : themeTextColor; |
| 450 [fill setFill]; | 492 [fill setFill]; |
| 493 |
| 451 [triangle fill]; | 494 [triangle fill]; |
| 495 |
| 496 [context restoreGraphicsState]; |
| 452 } | 497 } |
| 453 | 498 |
| 454 - (NSRect)imageRectForBounds:(NSRect)cellFrame { | 499 - (NSRect)imageRectForBounds:(NSRect)cellFrame { |
| 455 return NSMakeRect(cellFrame.origin.x + kImagePaddingLeft, | 500 return NSMakeRect(cellFrame.origin.x + kImagePaddingLeft, |
| 456 cellFrame.origin.y + kImagePaddingTop, | 501 cellFrame.origin.y + kImagePaddingTop, |
| 457 kImageWidth, | 502 kImageWidth, |
| 458 kImageHeight); | 503 kImageHeight); |
| 459 } | 504 } |
| 460 | 505 |
| 461 - (void)hideSecondaryTitle { | 506 - (void)hideSecondaryTitle { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 } | 552 } |
| 508 return self; | 553 return self; |
| 509 } | 554 } |
| 510 | 555 |
| 511 - (void)setCurrentProgress:(NSAnimationProgress)progress { | 556 - (void)setCurrentProgress:(NSAnimationProgress)progress { |
| 512 [super setCurrentProgress:progress]; | 557 [super setCurrentProgress:progress]; |
| 513 [cell_ animation:self progressed:progress]; | 558 [cell_ animation:self progressed:progress]; |
| 514 } | 559 } |
| 515 | 560 |
| 516 @end | 561 @end |
| OLD | NEW |