OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/ui/cocoa/tabpose_window.h" | 5 #import "chrome/browser/ui/cocoa/tabpose_window.h" |
6 | 6 |
7 #import <QuartzCore/QuartzCore.h> | 7 #import <QuartzCore/QuartzCore.h> |
8 | 8 |
9 #include "app/resource_bundle.h" | 9 #include "app/resource_bundle.h" |
10 #include "base/mac_util.h" | 10 #include "base/mac_util.h" |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
425 | 425 |
426 NSRect Tile::GetStartRectRelativeTo(const Tile& tile) const { | 426 NSRect Tile::GetStartRectRelativeTo(const Tile& tile) const { |
427 NSRect rect = start_thumb_rect_; | 427 NSRect rect = start_thumb_rect_; |
428 rect.origin.x -= tile.start_thumb_rect_.origin.x; | 428 rect.origin.x -= tile.start_thumb_rect_.origin.x; |
429 rect.origin.y -= tile.start_thumb_rect_.origin.y; | 429 rect.origin.y -= tile.start_thumb_rect_.origin.y; |
430 return rect; | 430 return rect; |
431 } | 431 } |
432 | 432 |
433 NSRect Tile::GetFaviconStartRectRelativeTo(const Tile& tile) const { | 433 NSRect Tile::GetFaviconStartRectRelativeTo(const Tile& tile) const { |
434 NSRect thumb_start = GetStartRectRelativeTo(tile); | 434 NSRect thumb_start = GetStartRectRelativeTo(tile); |
435 CGFloat scale_small_to_big = NSWidth(thumb_start) / NSWidth(thumb_rect_); | |
viettrungluu
2010/12/15 17:36:57
What is this scale and where does it come from?
A
Nico
2010/12/15 18:52:29
:-(
Renamed the variable. It's the ratio between
| |
435 NSRect rect = favicon_rect_; | 436 NSRect rect = favicon_rect_; |
436 rect.origin.x += NSMinX(thumb_start) - NSMinX(thumb_rect_); | 437 rect.origin.x -= NSMinX(thumb_rect_); |
viettrungluu
2010/12/15 17:36:57
Just make a helper function and do:
x = ScaleRe
Nico
2010/12/15 18:52:29
Ah, but this doesn't do (x - origin) * scale + ori
| |
437 rect.origin.y += NSMinY(thumb_start) - NSMinY(thumb_rect_); | 438 rect.origin.x *= scale_small_to_big; |
439 rect.origin.x += NSMinX(thumb_start); | |
440 rect.origin.y -= NSMinY(thumb_rect_); | |
441 rect.origin.y *= scale_small_to_big; | |
442 rect.origin.y += NSMinY(thumb_start); | |
443 rect.size.width *= scale_small_to_big; | |
444 rect.size.height *= scale_small_to_big; | |
438 return rect; | 445 return rect; |
439 } | 446 } |
440 | 447 |
441 SkBitmap Tile::favicon() const { | 448 SkBitmap Tile::favicon() const { |
442 if (contents_->is_app()) { | 449 if (contents_->is_app()) { |
443 SkBitmap* icon = contents_->GetExtensionAppIcon(); | 450 SkBitmap* icon = contents_->GetExtensionAppIcon(); |
444 if (icon) | 451 if (icon) |
445 return *icon; | 452 return *icon; |
446 } | 453 } |
447 return contents_->GetFavIcon(); | 454 return contents_->GetFavIcon(); |
448 } | 455 } |
449 | 456 |
450 NSRect Tile::GetTitleStartRectRelativeTo(const Tile& tile) const { | 457 NSRect Tile::GetTitleStartRectRelativeTo(const Tile& tile) const { |
451 NSRect thumb_start = GetStartRectRelativeTo(tile); | 458 NSRect thumb_start = GetStartRectRelativeTo(tile); |
459 CGFloat scale_small_to_big = NSWidth(thumb_start) / NSWidth(thumb_rect_); | |
452 NSRect rect = title_rect_; | 460 NSRect rect = title_rect_; |
453 rect.origin.x += NSMinX(thumb_start) - NSMinX(thumb_rect_); | 461 rect.origin.x -= NSMinX(thumb_rect_); |
454 rect.origin.y += NSMinY(thumb_start) - NSMinY(thumb_rect_); | 462 rect.origin.x *= scale_small_to_big; |
463 rect.origin.x += NSMinX(thumb_start); | |
464 rect.origin.y -= NSMinY(thumb_rect_); | |
465 rect.origin.y *= scale_small_to_big; | |
466 rect.origin.y += NSMinY(thumb_start); | |
467 rect.size.width *= scale_small_to_big; | |
468 rect.size.height *= scale_small_to_big; | |
455 return rect; | 469 return rect; |
456 } | 470 } |
457 | 471 |
458 // Changes |title_rect| and |favicon_rect| such that the favicon's and the | 472 // Changes |title_rect| and |favicon_rect| such that the favicon's and the |
459 // title's vertical center is aligned and that the minimum distance between | 473 // title's vertical center is aligned and that the minimum distance between |
460 // the thumb rect and favicon and title rects doesn't change. | 474 // the thumb rect and favicon and title rects doesn't change. |
461 void Tile::set_font_metrics(CGFloat ascender, CGFloat descender) { | 475 void Tile::set_font_metrics(CGFloat ascender, CGFloat descender) { |
462 // Make the title height big enough to fit the font, and adopt the title | 476 // Make the title height big enough to fit the font, and adopt the title |
463 // position to keep its distance from the thumb rect. | 477 // position to keep its distance from the thumb rect. |
464 title_rect_.origin.y -= ascender + descender - NSHeight(title_rect_); | 478 title_rect_.origin.y -= ascender + descender - NSHeight(title_rect_); |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
819 tiles_[i]->title_rect_ = tiles_[i + step]->title_rect_; | 833 tiles_[i]->title_rect_ = tiles_[i + step]->title_rect_; |
820 } | 834 } |
821 tiles_[from_index]->thumb_rect_ = thumb; | 835 tiles_[from_index]->thumb_rect_ = thumb; |
822 tiles_[from_index]->start_thumb_rect_ = start_thumb; | 836 tiles_[from_index]->start_thumb_rect_ = start_thumb; |
823 tiles_[from_index]->favicon_rect_ = favicon; | 837 tiles_[from_index]->favicon_rect_ = favicon; |
824 tiles_[from_index]->title_rect_ = title; | 838 tiles_[from_index]->title_rect_ = title; |
825 } | 839 } |
826 | 840 |
827 } // namespace tabpose | 841 } // namespace tabpose |
828 | 842 |
829 void AnimateCALayerFrameFromTo( | 843 void AnimateScaledCALayerFrameFromTo( |
830 CALayer* layer, const NSRect& from, const NSRect& to, | 844 CALayer* layer, |
845 const NSRect& from, CGFloat from_scale, | |
846 const NSRect& to, CGFloat to_scale, | |
831 NSTimeInterval duration, id boundsAnimationDelegate) { | 847 NSTimeInterval duration, id boundsAnimationDelegate) { |
832 // http://developer.apple.com/mac/library/qa/qa2008/qa1620.html | 848 // http://developer.apple.com/mac/library/qa/qa2008/qa1620.html |
833 CABasicAnimation* animation; | 849 CABasicAnimation* animation; |
834 | 850 |
835 animation = [CABasicAnimation animationWithKeyPath:@"bounds"]; | 851 animation = [CABasicAnimation animationWithKeyPath:@"bounds"]; |
836 animation.fromValue = [NSValue valueWithRect:from]; | 852 animation.fromValue = [NSValue valueWithRect:from]; |
837 animation.toValue = [NSValue valueWithRect:to]; | 853 animation.toValue = [NSValue valueWithRect:to]; |
838 animation.duration = duration; | 854 animation.duration = duration; |
839 animation.timingFunction = | 855 animation.timingFunction = |
840 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; | 856 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; |
841 animation.delegate = boundsAnimationDelegate; | 857 animation.delegate = boundsAnimationDelegate; |
842 | 858 |
843 // Update the layer's bounds so the layer doesn't snap back when the animation | 859 // Update the layer's bounds so the layer doesn't snap back when the animation |
844 // completes. | 860 // completes. |
845 layer.bounds = NSRectToCGRect(to); | 861 layer.bounds = NSRectToCGRect(to); |
846 | 862 |
847 // Add the animation, overriding the implicit animation. | 863 // Add the animation, overriding the implicit animation. |
848 [layer addAnimation:animation forKey:@"bounds"]; | 864 [layer addAnimation:animation forKey:@"bounds"]; |
849 | 865 |
850 // Prepare the animation from the current position to the new position. | 866 // Prepare the animation from the current position to the new position. |
851 NSPoint opoint = from.origin; | 867 NSPoint opoint = from.origin; |
852 NSPoint point = to.origin; | 868 NSPoint point = to.origin; |
853 | 869 |
854 // Adapt to anchorPoint. | 870 // Adapt to anchorPoint. |
855 opoint.x += NSWidth(from) * layer.anchorPoint.x; | 871 opoint.x += NSWidth(from) * from_scale * layer.anchorPoint.x; |
856 opoint.y += NSHeight(from) * layer.anchorPoint.y; | 872 opoint.y += NSHeight(from) * from_scale * layer.anchorPoint.y; |
857 point.x += NSWidth(to) * layer.anchorPoint.x; | 873 point.x += NSWidth(to) * to_scale * layer.anchorPoint.x; |
858 point.y += NSHeight(to) * layer.anchorPoint.y; | 874 point.y += NSHeight(to) * to_scale * layer.anchorPoint.y; |
859 | 875 |
860 animation = [CABasicAnimation animationWithKeyPath:@"position"]; | 876 animation = [CABasicAnimation animationWithKeyPath:@"position"]; |
861 animation.fromValue = [NSValue valueWithPoint:opoint]; | 877 animation.fromValue = [NSValue valueWithPoint:opoint]; |
862 animation.toValue = [NSValue valueWithPoint:point]; | 878 animation.toValue = [NSValue valueWithPoint:point]; |
863 animation.duration = duration; | 879 animation.duration = duration; |
864 animation.timingFunction = | 880 animation.timingFunction = |
865 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; | 881 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; |
866 | 882 |
867 // Update the layer's position so that the layer doesn't snap back when the | 883 // Update the layer's position so that the layer doesn't snap back when the |
868 // animation completes. | 884 // animation completes. |
869 layer.position = NSPointToCGPoint(point); | 885 layer.position = NSPointToCGPoint(point); |
870 | 886 |
871 // Add the animation, overriding the implicit animation. | 887 // Add the animation, overriding the implicit animation. |
872 [layer addAnimation:animation forKey:@"position"]; | 888 [layer addAnimation:animation forKey:@"position"]; |
873 } | 889 } |
874 | 890 |
891 void AnimateCALayerFrameFromTo( | |
892 CALayer* layer, const NSRect& from, const NSRect& to, | |
893 NSTimeInterval duration, id boundsAnimationDelegate) { | |
894 AnimateScaledCALayerFrameFromTo( | |
895 layer, from, 1.0, to, 1.0, duration, boundsAnimationDelegate); | |
896 } | |
897 | |
875 void AnimateCALayerOpacityFromTo( | 898 void AnimateCALayerOpacityFromTo( |
876 CALayer* layer, double from, double to, NSTimeInterval duration) { | 899 CALayer* layer, double from, double to, NSTimeInterval duration) { |
877 CABasicAnimation* animation; | 900 CABasicAnimation* animation; |
878 animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; | 901 animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; |
879 animation.fromValue = [NSNumber numberWithFloat:from]; | 902 animation.fromValue = [NSNumber numberWithFloat:from]; |
880 animation.toValue = [NSNumber numberWithFloat:to]; | 903 animation.toValue = [NSNumber numberWithFloat:to]; |
881 animation.duration = duration; | 904 animation.duration = duration; |
882 | 905 |
883 layer.opacity = to; | 906 layer.opacity = to; |
884 // Add the animation, overriding the implicit animation. | 907 // Add the animation, overriding the implicit animation. |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1008 nil); | 1031 nil); |
1009 AnimateCALayerOpacityFromTo(faviconLayer, 0.0, 1.0, interval); | 1032 AnimateCALayerOpacityFromTo(faviconLayer, 0.0, 1.0, interval); |
1010 } else { | 1033 } else { |
1011 faviconLayer.frame = NSRectToCGRect(tile.favicon_rect()); | 1034 faviconLayer.frame = NSRectToCGRect(tile.favicon_rect()); |
1012 } | 1035 } |
1013 faviconLayer.contents = (id)favicon.get(); | 1036 faviconLayer.contents = (id)favicon.get(); |
1014 faviconLayer.zPosition = 1; // On top of the thumb shadow. | 1037 faviconLayer.zPosition = 1; // On top of the thumb shadow. |
1015 [bgLayer_ addSublayer:faviconLayer]; | 1038 [bgLayer_ addSublayer:faviconLayer]; |
1016 [allFaviconLayers_ addObject:faviconLayer]; | 1039 [allFaviconLayers_ addObject:faviconLayer]; |
1017 | 1040 |
1041 // CATextLayers can't animate their fontSize property, at least on 10.5. | |
1042 // Animate transform.scale instead. | |
1043 | |
1044 // The scaling should have its origin in the layer's upper left corner. | |
1045 // This needs to be set before |AnimateCALayerFrameFromTo()| is called. | |
1018 CATextLayer* titleLayer = [CATextLayer layer]; | 1046 CATextLayer* titleLayer = [CATextLayer layer]; |
1047 titleLayer.anchorPoint = CGPointMake(0, 1); | |
1019 if (showZoom) { | 1048 if (showZoom) { |
1020 AnimateCALayerFrameFromTo( | 1049 NSRect fromRect = |
1021 titleLayer, | 1050 tile.GetTitleStartRectRelativeTo(tileSet_->selected_tile()); |
1022 tile.GetTitleStartRectRelativeTo(tileSet_->selected_tile()), | 1051 NSRect toRect = tile.title_rect(); |
1023 tile.title_rect(), | 1052 CGFloat scale = NSWidth(fromRect) / NSWidth(toRect); |
1024 interval, | 1053 fromRect.size = toRect.size; |
1025 nil); | 1054 |
1026 AnimateCALayerOpacityFromTo(titleLayer, 0.0, 1.0, interval); | 1055 // Add scale animation. |
1056 CABasicAnimation* scaleAnimation = | |
1057 [CABasicAnimation animationWithKeyPath:@"transform.scale"]; | |
1058 scaleAnimation.fromValue = [NSNumber numberWithDouble:scale]; | |
1059 scaleAnimation.toValue = [NSNumber numberWithDouble:1.0]; | |
1060 scaleAnimation.duration = interval; | |
1061 scaleAnimation.timingFunction = | |
1062 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; | |
1063 [titleLayer addAnimation:scaleAnimation forKey:@"transform.scale"]; | |
1064 | |
1065 // Add the position and opacity animations. | |
1066 AnimateScaledCALayerFrameFromTo( | |
1067 titleLayer, fromRect, scale, toRect, 1.0, interval, nil); | |
1068 AnimateCALayerOpacityFromTo(faviconLayer, 0.0, 1.0, interval); | |
1027 } else { | 1069 } else { |
1028 titleLayer.frame = NSRectToCGRect(tile.title_rect()); | 1070 titleLayer.frame = NSRectToCGRect(tile.title_rect()); |
1029 } | 1071 } |
1030 titleLayer.string = base::SysUTF16ToNSString(tile.title()); | 1072 titleLayer.string = base::SysUTF16ToNSString(tile.title()); |
1031 titleLayer.fontSize = [font pointSize]; | 1073 titleLayer.fontSize = [font pointSize]; |
1032 titleLayer.truncationMode = kCATruncationEnd; | 1074 titleLayer.truncationMode = kCATruncationEnd; |
1033 titleLayer.font = font; | 1075 titleLayer.font = font; |
1034 titleLayer.zPosition = 1; // On top of the thumb shadow. | 1076 titleLayer.zPosition = 1; // On top of the thumb shadow. |
1035 [bgLayer_ addSublayer:titleLayer]; | 1077 [bgLayer_ addSublayer:titleLayer]; |
1036 [allTitleLayers_ addObject:titleLayer]; | 1078 [allTitleLayers_ addObject:titleLayer]; |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1276 CALayer* layer = [allThumbnailLayers_ objectAtIndex:i]; | 1318 CALayer* layer = [allThumbnailLayers_ objectAtIndex:i]; |
1277 // Add a delegate to one of the implicit animations to get a notification | 1319 // Add a delegate to one of the implicit animations to get a notification |
1278 // once the animations are done. | 1320 // once the animations are done. |
1279 if (static_cast<int>(i) == tileSet_->selected_index()) { | 1321 if (static_cast<int>(i) == tileSet_->selected_index()) { |
1280 CAAnimation* animation = [CAAnimation animation]; | 1322 CAAnimation* animation = [CAAnimation animation]; |
1281 animation.delegate = self; | 1323 animation.delegate = self; |
1282 [animation setValue:kAnimationIdFadeOut forKey:kAnimationIdKey]; | 1324 [animation setValue:kAnimationIdFadeOut forKey:kAnimationIdKey]; |
1283 [layer addAnimation:animation forKey:@"frame"]; | 1325 [layer addAnimation:animation forKey:@"frame"]; |
1284 } | 1326 } |
1285 | 1327 |
1328 // Thumbnail. | |
1286 layer.frame = NSRectToCGRect( | 1329 layer.frame = NSRectToCGRect( |
1287 tile.GetStartRectRelativeTo(tileSet_->selected_tile())); | 1330 tile.GetStartRectRelativeTo(tileSet_->selected_tile())); |
1288 | 1331 |
1289 if (static_cast<int>(i) == tileSet_->selected_index()) { | 1332 if (static_cast<int>(i) == tileSet_->selected_index()) { |
1290 // Redraw layer at big resolution, so that zoom-in isn't blocky. | 1333 // Redraw layer at big resolution, so that zoom-in isn't blocky. |
1291 [layer setNeedsDisplay]; | 1334 [layer setNeedsDisplay]; |
1292 } | 1335 } |
1293 | 1336 |
1337 // Title. | |
1294 CALayer* faviconLayer = [allFaviconLayers_ objectAtIndex:i]; | 1338 CALayer* faviconLayer = [allFaviconLayers_ objectAtIndex:i]; |
1295 faviconLayer.frame = NSRectToCGRect( | 1339 faviconLayer.frame = NSRectToCGRect( |
1296 tile.GetFaviconStartRectRelativeTo(tileSet_->selected_tile())); | 1340 tile.GetFaviconStartRectRelativeTo(tileSet_->selected_tile())); |
1297 faviconLayer.opacity = 0; | 1341 faviconLayer.opacity = 0; |
1342 | |
1343 // Favicon. | |
1344 // The |fontSize| cannot be animated directly, animate the layer's scale | |
1345 // instead. scale affects the rendered width, so keep the small bounds. | |
viettrungluu
2010/12/15 17:36:57
"|scale|". Or should that be |transform.scale|? ("
Nico
2010/12/15 18:52:29
With "small", it's clear that it refers to the zoo
| |
1298 CALayer* titleLayer = [allTitleLayers_ objectAtIndex:i]; | 1346 CALayer* titleLayer = [allTitleLayers_ objectAtIndex:i]; |
1299 titleLayer.frame = NSRectToCGRect( | 1347 NSRect titleRect = tile.title_rect(); |
1300 tile.GetTitleStartRectRelativeTo(tileSet_->selected_tile())); | 1348 NSRect titleToRect = |
1349 tile.GetTitleStartRectRelativeTo(tileSet_->selected_tile()); | |
1350 CGFloat scale = NSWidth(titleToRect) / NSWidth(titleRect); | |
1351 titleToRect.origin.x += | |
1352 NSWidth(titleRect) * scale * titleLayer.anchorPoint.x; | |
1353 titleToRect.origin.y += | |
1354 NSHeight(titleRect) * scale * titleLayer.anchorPoint.y; | |
1355 titleLayer.position = NSPointToCGPoint(titleToRect.origin); | |
1356 [titleLayer setValue:[NSNumber numberWithDouble:scale] | |
1357 forKeyPath:@"transform.scale"]; | |
1301 titleLayer.opacity = 0; | 1358 titleLayer.opacity = 0; |
1302 } | 1359 } |
1303 } | 1360 } |
viettrungluu
2010/12/15 17:36:57
This is getting ridiculously big. Please break it
Nico
2010/12/15 18:52:29
It's a sweet 77 lines short!
Alright, done.
| |
1304 | 1361 |
1305 - (void)animationDidStop:(CAAnimation*)animation finished:(BOOL)finished { | 1362 - (void)animationDidStop:(CAAnimation*)animation finished:(BOOL)finished { |
1306 NSString* animationId = [animation valueForKey:kAnimationIdKey]; | 1363 NSString* animationId = [animation valueForKey:kAnimationIdKey]; |
1307 if ([animationId isEqualToString:kAnimationIdFadeIn]) { | 1364 if ([animationId isEqualToString:kAnimationIdFadeIn]) { |
1308 if (finished && state_ == tabpose::kFadingIn) { | 1365 if (finished && state_ == tabpose::kFadingIn) { |
1309 // If the user clicks while the fade in animation is still running, | 1366 // If the user clicks while the fade in animation is still running, |
1310 // |state_| is already kFadingOut. In that case, don't do anything. | 1367 // |state_| is already kFadingOut. In that case, don't do anything. |
1311 state_ = tabpose::kFadedIn; | 1368 state_ = tabpose::kFadedIn; |
1312 | 1369 |
1313 selectionHighlight_.hidden = NO; | 1370 selectionHighlight_.hidden = NO; |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1483 tile.set_tab_contents(contents->tab_contents()); | 1540 tile.set_tab_contents(contents->tab_contents()); |
1484 ThumbnailLayer* thumbLayer = [allThumbnailLayers_ objectAtIndex:index]; | 1541 ThumbnailLayer* thumbLayer = [allThumbnailLayers_ objectAtIndex:index]; |
1485 [thumbLayer setTabContents:contents->tab_contents()]; | 1542 [thumbLayer setTabContents:contents->tab_contents()]; |
1486 } | 1543 } |
1487 | 1544 |
1488 - (void)tabStripModelDeleted { | 1545 - (void)tabStripModelDeleted { |
1489 [self close]; | 1546 [self close]; |
1490 } | 1547 } |
1491 | 1548 |
1492 @end | 1549 @end |
OLD | NEW |