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 |