Chromium Code Reviews| 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/cocoa/tabpose_window.h" | 5 #import "chrome/browser/cocoa/tabpose_window.h" |
| 6 | 6 |
| 7 #import <QuartzCore/QuartzCore.h> | 7 #import <QuartzCore/QuartzCore.h> |
| 8 | 8 |
| 9 #import "chrome/browser/cocoa/browser_window_controller.h" | 9 #import "chrome/browser/cocoa/browser_window_controller.h" |
| 10 #import "chrome/browser/cocoa/tab_strip_controller.h" | 10 #import "chrome/browser/cocoa/tab_strip_controller.h" |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 [self setBackgroundColor:[NSColor clearColor]]; | 363 [self setBackgroundColor:[NSColor clearColor]]; |
| 364 [self setUpLayers:rect slomo:slomo]; | 364 [self setUpLayers:rect slomo:slomo]; |
| 365 [self setAcceptsMouseMovedEvents:YES]; | 365 [self setAcceptsMouseMovedEvents:YES]; |
| 366 [parent addChildWindow:self ordered:NSWindowAbove]; | 366 [parent addChildWindow:self ordered:NSWindowAbove]; |
| 367 [self makeKeyAndOrderFront:self]; | 367 [self makeKeyAndOrderFront:self]; |
| 368 } | 368 } |
| 369 return self; | 369 return self; |
| 370 } | 370 } |
| 371 | 371 |
| 372 - (CALayer*)selectedLayer { | 372 - (CALayer*)selectedLayer { |
| 373 return [allLayers_ objectAtIndex:tileSet_->selected_index()]; | 373 return [allThumbnailLayers_ objectAtIndex:tileSet_->selected_index()]; |
| 374 } | 374 } |
| 375 | 375 |
| 376 - (void)selectTileAtIndex:(int)newIndex { | 376 - (void)selectTileAtIndex:(int)newIndex { |
| 377 // TODO(thakis): Have a nicer indicator for the current selection | 377 ScopedCAActionDisabler disabler; |
| 378 // (a blue outline, probably). | 378 const tabpose::Tile& tile = tileSet_->tile_at(newIndex); |
| 379 int oldIndex = tileSet_->selected_index(); | 379 selectionHighlight_.frame = |
| 380 CALayer* oldSelectedLayer = [allLayers_ objectAtIndex:oldIndex]; | 380 NSRectToCGRect(NSInsetRect(tile.thumb_rect(), -6, -6)); |
| 381 oldSelectedLayer.backgroundColor = CGColorGetConstantColor(kCGColorBlack); | |
| 382 CALayer* newSelectedLayer = [allLayers_ objectAtIndex:newIndex]; | |
| 383 newSelectedLayer.backgroundColor = CGColorGetConstantColor(kCGColorWhite); | |
| 384 | 381 |
| 385 tileSet_->set_selected_index(newIndex); | 382 tileSet_->set_selected_index(newIndex); |
| 386 } | 383 } |
| 387 | 384 |
| 388 - (void)setUpLayers:(NSRect)bgLayerRect slomo:(BOOL)slomo { | 385 - (void)setUpLayers:(NSRect)bgLayerRect slomo:(BOOL)slomo { |
| 389 // Root layer -- covers whole window. | 386 // Root layer -- covers whole window. |
| 390 rootLayer_ = [CALayer layer]; | 387 rootLayer_ = [CALayer layer]; |
| 391 [[self contentView] setLayer:rootLayer_]; | 388 [[self contentView] setLayer:rootLayer_]; |
| 392 [[self contentView] setWantsLayer:YES]; | 389 [[self contentView] setWantsLayer:YES]; |
| 393 | 390 |
| 394 // Background layer -- the visible part of the window. | 391 // Background layer -- the visible part of the window. |
| 395 gray_.reset(CGColorCreateGenericGray(0.39, 1.0)); | 392 gray_.reset(CGColorCreateGenericGray(0.39, 1.0)); |
| 396 bgLayer_ = [CALayer layer]; | 393 bgLayer_ = [CALayer layer]; |
| 397 bgLayer_.backgroundColor = gray_; | 394 bgLayer_.backgroundColor = gray_; |
| 398 bgLayer_.frame = NSRectToCGRect(bgLayerRect); | 395 bgLayer_.frame = NSRectToCGRect(bgLayerRect); |
| 399 bgLayer_.masksToBounds = YES; | 396 bgLayer_.masksToBounds = YES; |
| 400 [rootLayer_ addSublayer:bgLayer_]; | 397 [rootLayer_ addSublayer:bgLayer_]; |
| 401 | 398 |
| 399 // Selection highlight layer. | |
| 400 darkBlue_.reset(CGColorCreateGenericRGB(0.25, 0.34, 0.86, 1.0)); | |
|
viettrungluu
2010/08/10 00:42:33
Out of which orifice did you get these numbers? :P
| |
| 401 selectionHighlight_ = [CALayer layer]; | |
| 402 selectionHighlight_.backgroundColor = darkBlue_; | |
| 403 selectionHighlight_.cornerRadius = 5.0; | |
| 404 selectionHighlight_.zPosition = -1; // Behind other layers. | |
| 405 selectionHighlight_.hidden = YES; | |
| 406 [bgLayer_ addSublayer:selectionHighlight_]; | |
| 407 | |
| 402 // Top gradient. | 408 // Top gradient. |
| 403 CALayer* gradientLayer = [DarkGradientLayer layer]; | 409 CALayer* gradientLayer = [DarkGradientLayer layer]; |
| 404 gradientLayer.frame = CGRectMake( | 410 gradientLayer.frame = CGRectMake( |
| 405 0, | 411 0, |
| 406 NSHeight(bgLayerRect) - kTopGradientHeight, | 412 NSHeight(bgLayerRect) - kTopGradientHeight, |
| 407 NSWidth(bgLayerRect), | 413 NSWidth(bgLayerRect), |
| 408 kTopGradientHeight); | 414 kTopGradientHeight); |
| 409 [gradientLayer setNeedsDisplay]; // Draw once. | 415 [gradientLayer setNeedsDisplay]; // Draw once. |
| 410 [bgLayer_ addSublayer:gradientLayer]; | 416 [bgLayer_ addSublayer:gradientLayer]; |
| 411 | 417 |
| 412 // Layers for the tab thumbnails. | 418 // Layers for the tab thumbnails. |
| 413 tileSet_->Build(tabStripModel_); | 419 tileSet_->Build(tabStripModel_); |
| 414 tileSet_->Layout(bgLayerRect); | 420 tileSet_->Layout(bgLayerRect); |
| 415 | 421 |
| 416 allLayers_.reset( | 422 allThumbnailLayers_.reset( |
| 417 [[NSMutableArray alloc] initWithCapacity:tabStripModel_->count()]); | 423 [[NSMutableArray alloc] initWithCapacity:tabStripModel_->count()]); |
| 418 for (int i = 0; i < tabStripModel_->count(); ++i) { | 424 for (int i = 0; i < tabStripModel_->count(); ++i) { |
| 419 CALayer* layer = [CALayer layer]; | 425 CALayer* layer = [CALayer layer]; |
| 420 | 426 |
| 421 // Background color as placeholder for now. | 427 // Background color as placeholder for now. |
| 422 layer.backgroundColor = CGColorGetConstantColor(kCGColorBlack); | 428 layer.backgroundColor = CGColorGetConstantColor(kCGColorWhite); |
| 423 | 429 |
| 424 AnimateCALayerFrameFromTo( | 430 AnimateCALayerFrameFromTo( |
| 425 layer, | 431 layer, |
| 426 tileSet_->tile_at(i).GetStartRectRelativeTo(tileSet_->selected_tile()), | 432 tileSet_->tile_at(i).GetStartRectRelativeTo(tileSet_->selected_tile()), |
| 427 tileSet_->tile_at(i).thumb_rect(), | 433 tileSet_->tile_at(i).thumb_rect(), |
| 428 kDefaultAnimationDuration * (slomo ? kSlomoFactor : 1), | 434 kDefaultAnimationDuration * (slomo ? kSlomoFactor : 1), |
| 429 i == tileSet_->selected_index() ? self : nil); | 435 i == tileSet_->selected_index() ? self : nil); |
| 430 | 436 |
| 431 // Add a delegate to one of the animations to get a notification once the | 437 // Add a delegate to one of the animations to get a notification once the |
| 432 // animations are done. | 438 // animations are done. |
| 433 if (i == tileSet_->selected_index()) { | 439 if (i == tileSet_->selected_index()) { |
| 434 CAAnimation* animation = [layer animationForKey:@"bounds"]; | 440 CAAnimation* animation = [layer animationForKey:@"bounds"]; |
| 435 DCHECK(animation); | 441 DCHECK(animation); |
| 436 [animation setValue:kAnimationIdFadeIn forKey:kAnimationIdKey]; | 442 [animation setValue:kAnimationIdFadeIn forKey:kAnimationIdKey]; |
| 437 } | 443 } |
| 438 | 444 |
| 439 layer.shadowRadius = 10; | 445 layer.shadowRadius = 10; |
| 440 layer.shadowOffset = CGSizeMake(0, -10); | 446 layer.shadowOffset = CGSizeMake(0, -10); |
| 441 | 447 |
| 442 [bgLayer_ addSublayer:layer]; | 448 [bgLayer_ addSublayer:layer]; |
| 443 [allLayers_ addObject:layer]; | 449 [allThumbnailLayers_ addObject:layer]; |
| 444 } | 450 } |
| 445 [self selectTileAtIndex:tileSet_->selected_index()]; | 451 [self selectTileAtIndex:tileSet_->selected_index()]; |
| 446 } | 452 } |
| 447 | 453 |
| 448 - (BOOL)canBecomeKeyWindow { | 454 - (BOOL)canBecomeKeyWindow { |
| 449 return YES; | 455 return YES; |
| 450 } | 456 } |
| 451 | 457 |
| 452 - (void)keyDown:(NSEvent*)event { | 458 - (void)keyDown:(NSEvent*)event { |
| 453 // Overridden to prevent beeps. | 459 // Overridden to prevent beeps. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 473 tileSet_->ResetSelectedIndex(); | 479 tileSet_->ResetSelectedIndex(); |
| 474 [self fadeAway:([event modifierFlags] & NSShiftKeyMask) != 0]; | 480 [self fadeAway:([event modifierFlags] & NSShiftKeyMask) != 0]; |
| 475 break; | 481 break; |
| 476 // TODO(thakis): Support moving the selection via arrow keys. | 482 // TODO(thakis): Support moving the selection via arrow keys. |
| 477 } | 483 } |
| 478 } | 484 } |
| 479 | 485 |
| 480 - (void)mouseMoved:(NSEvent*)event { | 486 - (void)mouseMoved:(NSEvent*)event { |
| 481 int newIndex = -1; | 487 int newIndex = -1; |
| 482 CGPoint p = NSPointToCGPoint([event locationInWindow]); | 488 CGPoint p = NSPointToCGPoint([event locationInWindow]); |
| 483 for (NSUInteger i = 0; i < [allLayers_ count]; ++i) { | 489 for (NSUInteger i = 0; i < [allThumbnailLayers_ count]; ++i) { |
| 484 CALayer* layer = [allLayers_ objectAtIndex:i]; | 490 CALayer* layer = [allThumbnailLayers_ objectAtIndex:i]; |
| 485 CGPoint lp = [layer convertPoint:p fromLayer:rootLayer_]; | 491 CGPoint lp = [layer convertPoint:p fromLayer:rootLayer_]; |
| 486 if ([static_cast<CALayer*>([layer presentationLayer]) containsPoint:lp]) | 492 if ([static_cast<CALayer*>([layer presentationLayer]) containsPoint:lp]) |
| 487 newIndex = i; | 493 newIndex = i; |
| 488 } | 494 } |
| 489 if (newIndex >= 0) | 495 if (newIndex >= 0) |
| 490 [self selectTileAtIndex:newIndex]; | 496 [self selectTileAtIndex:newIndex]; |
| 491 } | 497 } |
| 492 | 498 |
| 493 - (void)mouseDown:(NSEvent*)event { | 499 - (void)mouseDown:(NSEvent*)event { |
| 494 [self fadeAway:([event modifierFlags] & NSShiftKeyMask) != 0]; | 500 [self fadeAway:([event modifierFlags] & NSShiftKeyMask) != 0]; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 524 // Select chosen tab. | 530 // Select chosen tab. |
| 525 tabStripModel_->SelectTabContentsAt(tileSet_->selected_index(), | 531 tabStripModel_->SelectTabContentsAt(tileSet_->selected_index(), |
| 526 /*user_gesture=*/true); | 532 /*user_gesture=*/true); |
| 527 | 533 |
| 528 { | 534 { |
| 529 ScopedCAActionDisabler disableCAActions; | 535 ScopedCAActionDisabler disableCAActions; |
| 530 | 536 |
| 531 // Move the selected layer on top of all other layers. | 537 // Move the selected layer on top of all other layers. |
| 532 [self selectedLayer].zPosition = 1; | 538 [self selectedLayer].zPosition = 1; |
| 533 | 539 |
| 540 selectionHighlight_.hidden = YES; | |
| 541 | |
| 534 // Running animations with shadows is slow, so turn shadows off before | 542 // Running animations with shadows is slow, so turn shadows off before |
| 535 // running the exit animation. | 543 // running the exit animation. |
| 536 for (CALayer* layer in allLayers_.get()) | 544 for (CALayer* layer in allThumbnailLayers_.get()) |
| 537 layer.shadowOpacity = 0.0; | 545 layer.shadowOpacity = 0.0; |
| 538 } | 546 } |
| 539 | 547 |
| 540 // Animate layers out, all in one transaction. | 548 // Animate layers out, all in one transaction. |
| 541 CGFloat duration = kDefaultAnimationDuration * (slomo ? kSlomoFactor : 1); | 549 CGFloat duration = kDefaultAnimationDuration * (slomo ? kSlomoFactor : 1); |
| 542 ScopedCAActionSetDuration durationSetter(duration); | 550 ScopedCAActionSetDuration durationSetter(duration); |
| 543 for (NSUInteger i = 0; i < [allLayers_ count]; ++i) { | 551 for (NSUInteger i = 0; i < [allThumbnailLayers_ count]; ++i) { |
| 544 CALayer* layer = [allLayers_ objectAtIndex:i]; | 552 CALayer* layer = [allThumbnailLayers_ objectAtIndex:i]; |
| 545 // |start_thumb_rect_| was relative to |initial_index_|, now this needs to | 553 // |start_thumb_rect_| was relative to |initial_index_|, now this needs to |
| 546 // be relative to |selectedIndex_| (whose start rect was relative to | 554 // be relative to |selectedIndex_| (whose start rect was relative to |
| 547 // |initial_index_| too) | 555 // |initial_index_| too) |
| 548 CGRect newFrame = NSRectToCGRect( | 556 CGRect newFrame = NSRectToCGRect( |
| 549 tileSet_->tile_at(i).GetStartRectRelativeTo(tileSet_->selected_tile())); | 557 tileSet_->tile_at(i).GetStartRectRelativeTo(tileSet_->selected_tile())); |
| 550 | 558 |
| 551 // Add a delegate to one of the implicit animations to get a notification | 559 // Add a delegate to one of the implicit animations to get a notification |
| 552 // once the animations are done. | 560 // once the animations are done. |
| 553 if (static_cast<int>(i) == tileSet_->selected_index()) { | 561 if (static_cast<int>(i) == tileSet_->selected_index()) { |
| 554 CAAnimation* animation = [CAAnimation animation]; | 562 CAAnimation* animation = [CAAnimation animation]; |
| 555 animation.delegate = self; | 563 animation.delegate = self; |
| 556 [animation setValue:kAnimationIdFadeOut forKey:kAnimationIdKey]; | 564 [animation setValue:kAnimationIdFadeOut forKey:kAnimationIdKey]; |
| 557 [layer addAnimation:animation forKey:@"frame"]; | 565 [layer addAnimation:animation forKey:@"frame"]; |
| 558 } | 566 } |
| 559 | 567 |
| 560 layer.frame = newFrame; | 568 layer.frame = newFrame; |
| 561 } | 569 } |
| 562 } | 570 } |
| 563 | 571 |
| 564 - (void)animationDidStop:(CAAnimation*)animation finished:(BOOL)finished { | 572 - (void)animationDidStop:(CAAnimation*)animation finished:(BOOL)finished { |
| 565 NSString* animationId = [animation valueForKey:kAnimationIdKey]; | 573 NSString* animationId = [animation valueForKey:kAnimationIdKey]; |
| 566 if ([animationId isEqualToString:kAnimationIdFadeIn]) { | 574 if ([animationId isEqualToString:kAnimationIdFadeIn]) { |
| 567 if (finished) { | 575 if (finished) { |
| 568 // If the user clicks while the fade in animation is still running, | 576 // If the user clicks while the fade in animation is still running, |
| 569 // |state_| is already kFadingOut. In that case, don't do anything. | 577 // |state_| is already kFadingOut. In that case, don't do anything. |
| 570 DCHECK_EQ(tabpose::kFadingIn, state_); | 578 DCHECK_EQ(tabpose::kFadingIn, state_); |
| 571 state_ = tabpose::kFadedIn; | 579 state_ = tabpose::kFadedIn; |
| 572 | 580 |
| 581 selectionHighlight_.hidden = NO; | |
| 582 | |
| 573 // Running animations with shadows is slow, so turn shadows on only after | 583 // Running animations with shadows is slow, so turn shadows on only after |
| 574 // the animation is done. | 584 // the animation is done. |
| 575 ScopedCAActionDisabler disableCAActions; | 585 ScopedCAActionDisabler disableCAActions; |
| 576 for (CALayer* layer in allLayers_.get()) | 586 for (CALayer* layer in allThumbnailLayers_.get()) |
| 577 layer.shadowOpacity = 0.5; | 587 layer.shadowOpacity = 0.5; |
| 578 } | 588 } |
| 579 } else if ([animationId isEqualToString:kAnimationIdFadeOut]) { | 589 } else if ([animationId isEqualToString:kAnimationIdFadeOut]) { |
| 580 DCHECK_EQ(tabpose::kFadingOut, state_); | 590 DCHECK_EQ(tabpose::kFadingOut, state_); |
| 581 [self close]; | 591 [self close]; |
| 582 } | 592 } |
| 583 } | 593 } |
| 584 | 594 |
| 585 @end | 595 @end |
| OLD | NEW |