Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(814)

Side by Side Diff: chrome/browser/cocoa/tab_strip_controller.mm

Issue 243049: Cancel previous new tab "submarine" animations when starting the animation fo... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/tab_strip_controller.h" 5 #import "chrome/browser/cocoa/tab_strip_controller.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "app/resource_bundle.h" 8 #include "app/resource_bundle.h"
9 #include "base/mac_util.h" 9 #include "base/mac_util.h"
10 #include "base/nsimage_cache_mac.h" 10 #include "base/nsimage_cache_mac.h"
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 // the ordering in the TabStripModel. This call isn't that expensive, though 353 // the ordering in the TabStripModel. This call isn't that expensive, though
354 // it is O(n) in the number of tabs. Tabs will animate to their new position 354 // it is O(n) in the number of tabs. Tabs will animate to their new position
355 // if the window is visible and |animate| is YES. 355 // if the window is visible and |animate| is YES.
356 // TODO(pinkerton): Handle drag placeholders via proxy objects, perhaps a 356 // TODO(pinkerton): Handle drag placeholders via proxy objects, perhaps a
357 // subclass of TabContentsController with everything stubbed out or by 357 // subclass of TabContentsController with everything stubbed out or by
358 // abstracting a base class interface. 358 // abstracting a base class interface.
359 // TODO(pinkerton): Note this doesn't do too well when the number of min-sized 359 // TODO(pinkerton): Note this doesn't do too well when the number of min-sized
360 // tabs would cause an overflow. 360 // tabs would cause an overflow.
361 - (void)layoutTabsWithAnimation:(BOOL)animate 361 - (void)layoutTabsWithAnimation:(BOOL)animate
362 regenerateSubviews:(BOOL)doUpdate { 362 regenerateSubviews:(BOOL)doUpdate {
363 // A very short duration used to cancel in-progress animations by making the
364 // new animation happen "instantly".
365 const float kInstantly = 0.000001;
Mark Mentovai 2009/10/13 17:30:23 Can you #include <limits> and use the std::numeric
363 const float kTabOverlap = 20.0; 366 const float kTabOverlap = 20.0;
364 const float kNewTabButtonOffset = 8.0; 367 const float kNewTabButtonOffset = 8.0;
365 const float kMaxTabWidth = [TabController maxTabWidth]; 368 const float kMaxTabWidth = [TabController maxTabWidth];
366 const float kMinTabWidth = [TabController minTabWidth]; 369 const float kMinTabWidth = [TabController minTabWidth];
367 const float kMinSelectedTabWidth = [TabController minSelectedTabWidth]; 370 const float kMinSelectedTabWidth = [TabController minSelectedTabWidth];
368 371
369 NSRect enclosingRect = NSZeroRect; 372 NSRect enclosingRect = NSZeroRect;
370 [NSAnimationContext beginGrouping]; 373 [NSAnimationContext beginGrouping];
371 [[NSAnimationContext currentContext] setDuration:0.2]; 374 [[NSAnimationContext currentContext] setDuration:0.2];
372 375
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 // and animate it in. 413 // and animate it in.
411 BOOL newTab = [[tab view] isHidden]; 414 BOOL newTab = [[tab view] isHidden];
412 if (newTab) { 415 if (newTab) {
413 [[tab view] setHidden:NO]; 416 [[tab view] setHidden:NO];
414 } 417 }
415 418
416 if (isPlaceholder) { 419 if (isPlaceholder) {
417 // Move the current tab to the correct location instantly. 420 // Move the current tab to the correct location instantly.
418 // We need a duration or else it doesn't cancel an inflight animation. 421 // We need a duration or else it doesn't cancel an inflight animation.
419 [NSAnimationContext beginGrouping]; 422 [NSAnimationContext beginGrouping];
420 [[NSAnimationContext currentContext] setDuration:0.000001]; 423 [[NSAnimationContext currentContext] setDuration:kInstantly];
Mark Mentovai 2009/10/13 17:30:23 Seems kind of funny to say "set duration to instan
421 tabFrame.origin.x = placeholderFrame_.origin.x; 424 tabFrame.origin.x = placeholderFrame_.origin.x;
422 // TODO(alcor): reenable this 425 // TODO(alcor): reenable this
423 //tabFrame.size.height += 10.0 * placeholderStretchiness_; 426 //tabFrame.size.height += 10.0 * placeholderStretchiness_;
424 id target = animate ? [[tab view] animator] : [tab view]; 427 id target = animate ? [[tab view] animator] : [tab view];
425 [target setFrame:tabFrame]; 428 [target setFrame:tabFrame];
426 [NSAnimationContext endGrouping]; 429 [NSAnimationContext endGrouping];
427 430
428 // Store the frame by identifier to aviod redundant calls to animator. 431 // Store the frame by identifier to aviod redundant calls to animator.
429 NSValue* identifier = [NSValue valueWithPointer:[tab view]]; 432 NSValue* identifier = [NSValue valueWithPointer:[tab view]];
430 [targetFrames_ setObject:[NSValue valueWithRect:tabFrame] 433 [targetFrames_ setObject:[NSValue valueWithRect:tabFrame]
431 forKey:identifier]; 434 forKey:identifier];
432 continue; 435 continue;
433 } else { 436 } else {
434 // If our left edge is to the left of the placeholder's left, but our mid 437 // If our left edge is to the left of the placeholder's left, but our mid
435 // is to the right of it we should slide over to make space for it. 438 // is to the right of it we should slide over to make space for it.
436 if (placeholderTab_ && gap < 0 && NSMidX(tabFrame) > minX) { 439 if (placeholderTab_ && gap < 0 && NSMidX(tabFrame) > minX) {
437 gap = i; 440 gap = i;
438 offset += NSWidth(tabFrame); 441 offset += NSWidth(tabFrame);
439 offset -= kTabOverlap; 442 offset -= kTabOverlap;
440 tabFrame.origin.x = offset; 443 tabFrame.origin.x = offset;
441 } 444 }
442 445
443 // Animate the tab in by putting it below the horizon, but don't bother
444 // if we only have 1 tab.
445 BOOL shouldAnimate = animate && [tabContentsArray_ count] > 1;
446 if (newTab && visible && shouldAnimate) {
447 [[tab view] setFrame:NSOffsetRect(tabFrame, 0, -NSHeight(tabFrame))];
448 }
449
450 // Set the width. Selected tabs are slightly wider when things get 446 // Set the width. Selected tabs are slightly wider when things get
451 // really small and thus we enforce a different minimum width. 447 // really small and thus we enforce a different minimum width.
452 tabFrame.size.width = 448 tabFrame.size.width =
453 [tab selected] ? MAX(baseTabWidth, kMinSelectedTabWidth) : 449 [tab selected] ? MAX(baseTabWidth, kMinSelectedTabWidth) :
454 baseTabWidth; 450 baseTabWidth;
455 451
452 // Animate a new tab in by putting it below the horizon, but don't bother
453 // if we only have 1 tab.
454 BOOL shouldAnimate = animate && [tabContentsArray_ count] > 1;
455 if (newTab && visible && shouldAnimate) {
456 [[tab view] setFrame:NSOffsetRect(tabFrame, 0, -NSHeight(tabFrame))];
457 }
458
456 // Check the frame by identifier to avoid redundant calls to animator. 459 // Check the frame by identifier to avoid redundant calls to animator.
457 id frameTarget = visible && animate ? [[tab view] animator] : [tab view]; 460 id frameTarget = visible && animate ? [[tab view] animator] : [tab view];
458 NSValue* identifier = [NSValue valueWithPointer:[tab view]]; 461 NSValue* identifier = [NSValue valueWithPointer:[tab view]];
459 NSValue* oldTargetValue = [targetFrames_ objectForKey:identifier]; 462 NSValue* oldTargetValue = [targetFrames_ objectForKey:identifier];
460 if (!oldTargetValue || 463 if (!oldTargetValue ||
461 !NSEqualRects([oldTargetValue rectValue], tabFrame)) { 464 !NSEqualRects([oldTargetValue rectValue], tabFrame)) {
462 [frameTarget setFrame:tabFrame]; 465 [frameTarget setFrame:tabFrame];
463 [targetFrames_ setObject:[NSValue valueWithRect:tabFrame] 466 [targetFrames_ setObject:[NSValue valueWithRect:tabFrame]
464 forKey:identifier]; 467 forKey:identifier];
465 } 468 }
469
466 enclosingRect = NSUnionRect(tabFrame, enclosingRect); 470 enclosingRect = NSUnionRect(tabFrame, enclosingRect);
467 } 471 }
468 472
469 offset += NSWidth(tabFrame); 473 offset += NSWidth(tabFrame);
470 offset -= kTabOverlap; 474 offset -= kTabOverlap;
471 i++; 475 i++;
472 } 476 }
473 477
474 // Hide the new tab button if we're explicitly told to. It may already 478 // Hide the new tab button if we're explicitly told to. It may already
475 // be hidden, doing it again doesn't hurt. Otherwise position it 479 // be hidden, doing it again doesn't hurt. Otherwise position it
476 // appropriately, showing it if necessary. 480 // appropriately, showing it if necessary.
477 if (forceNewTabButtonHidden_) { 481 if (forceNewTabButtonHidden_) {
478 [newTabButton_ setHidden:YES]; 482 [newTabButton_ setHidden:YES];
479 } else { 483 } else {
480 NSRect newTabNewFrame = [newTabButton_ frame]; 484 NSRect newTabNewFrame = [newTabButton_ frame];
481 // We've already ensured there's enough space for the new tab button 485 // We've already ensured there's enough space for the new tab button
482 // so we don't have to check it against the available width. We do need 486 // so we don't have to check it against the available width. We do need
483 // to make sure we put it after any placeholder. 487 // to make sure we put it after any placeholder.
484 newTabNewFrame.origin = NSMakePoint(offset, 0); 488 newTabNewFrame.origin = NSMakePoint(offset, 0);
485 newTabNewFrame.origin.x = MAX(newTabNewFrame.origin.x, 489 newTabNewFrame.origin.x = MAX(newTabNewFrame.origin.x,
486 NSMaxX(placeholderFrame_)) + 490 NSMaxX(placeholderFrame_)) +
487 kNewTabButtonOffset; 491 kNewTabButtonOffset;
488 if ([tabContentsArray_ count]) 492 if ([tabContentsArray_ count])
489 [newTabButton_ setHidden:NO]; 493 [newTabButton_ setHidden:NO];
490 494
491 if (!NSEqualRects(newTabTargetFrame_, newTabNewFrame)) { 495 if (!NSEqualRects(newTabTargetFrame_, newTabNewFrame)) {
492 [newTabButton_ setFrame:newTabNewFrame]; 496 // Move the new tab button into place. We want to animate the new tab
497 // button if it's moving to the left (closing a tab), but not when it's
498 // moving to the right (inserting a new tab). If moving right, we need
499 // to use a very small duration to make sure we cancel any in-flight
500 // animation to the left.
501 BOOL movingLeft = NSMinX(newTabNewFrame) < NSMinX(newTabTargetFrame_);
502 id target = animate ? [newTabButton_ animator] : newTabButton_;
503 [NSAnimationContext beginGrouping];
Mark Mentovai 2009/10/13 17:30:23 Adding this is what fixed the bug I was seeing ear
504 if (!movingLeft)
505 [[NSAnimationContext currentContext] setDuration:kInstantly];
506 [target setFrame:newTabNewFrame];
507 [NSAnimationContext endGrouping];
493 newTabTargetFrame_ = newTabNewFrame; 508 newTabTargetFrame_ = newTabNewFrame;
494 // Move the new tab button into place.
495 } 509 }
496 } 510 }
497 511
498 [NSAnimationContext endGrouping]; 512 [NSAnimationContext endGrouping];
499 [dragBlockingView_ setFrame:enclosingRect]; 513 [dragBlockingView_ setFrame:enclosingRect];
500 } 514 }
501 515
502 // When we're told to layout from the public API we always want to animate. 516 // When we're told to layout from the public API we always want to animate.
503 - (void)layoutTabs { 517 - (void)layoutTabs {
504 [self layoutTabsWithAnimation:YES regenerateSubviews:YES]; 518 [self layoutTabsWithAnimation:YES regenerateSubviews:YES];
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 BrowserWindowController* controller = 993 BrowserWindowController* controller =
980 (BrowserWindowController*)[[switchView_ window] windowController]; 994 (BrowserWindowController*)[[switchView_ window] windowController];
981 DCHECK(index >= 0); 995 DCHECK(index >= 0);
982 if (index >= 0) { 996 if (index >= 0) {
983 [controller setTab:[self viewAtIndex:index] isDraggable:YES]; 997 [controller setTab:[self viewAtIndex:index] isDraggable:YES];
984 } 998 }
985 } 999 }
986 1000
987 1001
988 @end 1002 @end
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698