| 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/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" |
| 11 #include "base/sys_string_conversions.h" | 11 #include "base/sys_string_conversions.h" |
| 12 #include "chrome/app/chrome_dll_resource.h" | 12 #include "chrome/app/chrome_dll_resource.h" |
| 13 #include "chrome/browser/browser.h" | 13 #include "chrome/browser/browser.h" |
| 14 #include "chrome/browser/find_bar.h" | 14 #include "chrome/browser/find_bar.h" |
| 15 #include "chrome/browser/find_bar_controller.h" | 15 #include "chrome/browser/find_bar_controller.h" |
| 16 #include "chrome/browser/metrics/user_metrics.h" | 16 #include "chrome/browser/metrics/user_metrics.h" |
| 17 #include "chrome/browser/profile.h" | 17 #include "chrome/browser/profile.h" |
| 18 #import "chrome/browser/cocoa/browser_window_controller.h" | 18 #import "chrome/browser/cocoa/browser_window_controller.h" |
| 19 #import "chrome/browser/cocoa/constrained_window_mac.h" | 19 #import "chrome/browser/cocoa/constrained_window_mac.h" |
| 20 #import "chrome/browser/cocoa/tab_strip_view.h" | 20 #import "chrome/browser/cocoa/tab_strip_view.h" |
| 21 #import "chrome/browser/cocoa/tab_cell.h" | |
| 22 #import "chrome/browser/cocoa/tab_contents_controller.h" | 21 #import "chrome/browser/cocoa/tab_contents_controller.h" |
| 23 #import "chrome/browser/cocoa/tab_controller.h" | 22 #import "chrome/browser/cocoa/tab_controller.h" |
| 24 #import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h" | 23 #import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h" |
| 25 #import "chrome/browser/cocoa/tab_view.h" | 24 #import "chrome/browser/cocoa/tab_view.h" |
| 26 #import "chrome/browser/cocoa/throbber_view.h" | 25 #import "chrome/browser/cocoa/throbber_view.h" |
| 27 #include "chrome/browser/tab_contents/navigation_controller.h" | 26 #include "chrome/browser/tab_contents/navigation_controller.h" |
| 28 #include "chrome/browser/tab_contents/navigation_entry.h" | 27 #include "chrome/browser/tab_contents/navigation_entry.h" |
| 29 #include "chrome/browser/tab_contents/tab_contents.h" | 28 #include "chrome/browser/tab_contents/tab_contents.h" |
| 30 #include "chrome/browser/tab_contents/tab_contents_view.h" | 29 #include "chrome/browser/tab_contents/tab_contents_view.h" |
| 31 #include "chrome/browser/tabs/tab_strip_model.h" | 30 #include "chrome/browser/tabs/tab_strip_model.h" |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 [NSAnimationContext beginGrouping]; | 418 [NSAnimationContext beginGrouping]; |
| 420 [[NSAnimationContext currentContext] setDuration:0.000001]; | 419 [[NSAnimationContext currentContext] setDuration:0.000001]; |
| 421 tabFrame.origin.x = placeholderFrame_.origin.x; | 420 tabFrame.origin.x = placeholderFrame_.origin.x; |
| 422 // TODO(alcor): reenable this | 421 // TODO(alcor): reenable this |
| 423 //tabFrame.size.height += 10.0 * placeholderStretchiness_; | 422 //tabFrame.size.height += 10.0 * placeholderStretchiness_; |
| 424 id target = animate ? [[tab view] animator] : [tab view]; | 423 id target = animate ? [[tab view] animator] : [tab view]; |
| 425 [target setFrame:tabFrame]; | 424 [target setFrame:tabFrame]; |
| 426 [NSAnimationContext endGrouping]; | 425 [NSAnimationContext endGrouping]; |
| 427 | 426 |
| 428 // Store the frame by identifier to aviod redundant calls to animator. | 427 // Store the frame by identifier to aviod redundant calls to animator. |
| 429 NSValue *identifier = [NSValue valueWithPointer:[tab view]]; | 428 NSValue* identifier = [NSValue valueWithPointer:[tab view]]; |
| 430 [targetFrames_ setObject:[NSValue valueWithRect:tabFrame] | 429 [targetFrames_ setObject:[NSValue valueWithRect:tabFrame] |
| 431 forKey:identifier]; | 430 forKey:identifier]; |
| 432 continue; | 431 continue; |
| 433 } else { | 432 } else { |
| 434 // If our left edge is to the left of the placeholder's left, but our mid | 433 // 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. | 434 // is to the right of it we should slide over to make space for it. |
| 436 if (placeholderTab_ && gap < 0 && NSMidX(tabFrame) > minX) { | 435 if (placeholderTab_ && gap < 0 && NSMidX(tabFrame) > minX) { |
| 437 gap = i; | 436 gap = i; |
| 438 offset += NSWidth(tabFrame); | 437 offset += NSWidth(tabFrame); |
| 439 offset -= kTabOverlap; | 438 offset -= kTabOverlap; |
| 440 tabFrame.origin.x = offset; | 439 tabFrame.origin.x = offset; |
| 441 } | 440 } |
| 442 | 441 |
| 443 // Animate the tab in by putting it below the horizon, but don't bother | 442 // Animate the tab in by putting it below the horizon, but don't bother |
| 444 // if we only have 1 tab. | 443 // if we only have 1 tab. |
| 445 BOOL shouldAnimate = animate && [tabContentsArray_ count] > 1; | 444 BOOL shouldAnimate = animate && [tabContentsArray_ count] > 1; |
| 446 if (newTab && visible && shouldAnimate) { | 445 if (newTab && visible && shouldAnimate) { |
| 447 [[tab view] setFrame:NSOffsetRect(tabFrame, 0, -NSHeight(tabFrame))]; | 446 [[tab view] setFrame:NSOffsetRect(tabFrame, 0, -NSHeight(tabFrame))]; |
| 448 } | 447 } |
| 449 | 448 |
| 450 // Set the width. Selected tabs are slightly wider when things get | 449 // Set the width. Selected tabs are slightly wider when things get |
| 451 // really small and thus we enforce a different minimum width. | 450 // really small and thus we enforce a different minimum width. |
| 452 tabFrame.size.width = | 451 tabFrame.size.width = |
| 453 [tab selected] ? MAX(baseTabWidth, kMinSelectedTabWidth) : | 452 [tab selected] ? MAX(baseTabWidth, kMinSelectedTabWidth) : |
| 454 baseTabWidth; | 453 baseTabWidth; |
| 455 | 454 |
| 456 // Check the frame by identifier to avoid redundant calls to animator. | 455 // Check the frame by identifier to avoid redundant calls to animator. |
| 457 id frameTarget = visible && animate ? [[tab view] animator] : [tab view]; | 456 id frameTarget = visible && animate ? [[tab view] animator] : [tab view]; |
| 458 NSValue *identifier = [NSValue valueWithPointer:[tab view]]; | 457 NSValue* identifier = [NSValue valueWithPointer:[tab view]]; |
| 459 NSValue *oldTargetValue = [targetFrames_ objectForKey:identifier]; | 458 NSValue* oldTargetValue = [targetFrames_ objectForKey:identifier]; |
| 460 if (!oldTargetValue || | 459 if (!oldTargetValue || |
| 461 !NSEqualRects([oldTargetValue rectValue], tabFrame)) { | 460 !NSEqualRects([oldTargetValue rectValue], tabFrame)) { |
| 462 [frameTarget setFrame:tabFrame]; | 461 [frameTarget setFrame:tabFrame]; |
| 463 [targetFrames_ setObject:[NSValue valueWithRect:tabFrame] | 462 [targetFrames_ setObject:[NSValue valueWithRect:tabFrame] |
| 464 forKey:identifier]; | 463 forKey:identifier]; |
| 465 } | 464 } |
| 466 enclosingRect = NSUnionRect(tabFrame, enclosingRect); | 465 enclosingRect = NSUnionRect(tabFrame, enclosingRect); |
| 467 } | 466 } |
| 468 | 467 |
| 469 offset += NSWidth(tabFrame); | 468 offset += NSWidth(tabFrame); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 // Clear the tab controller's target. | 633 // Clear the tab controller's target. |
| 635 // TODO(viettrungluu): [crbug.com/23829] Find a better way to handle the tab | 634 // TODO(viettrungluu): [crbug.com/23829] Find a better way to handle the tab |
| 636 // controller's target. | 635 // controller's target. |
| 637 TabController* tabController = [tabArray_ objectAtIndex:index]; | 636 TabController* tabController = [tabArray_ objectAtIndex:index]; |
| 638 [tabController setTarget:nil]; | 637 [tabController setTarget:nil]; |
| 639 | 638 |
| 640 if ([hoveredTab_ isEqual:tab]) { | 639 if ([hoveredTab_ isEqual:tab]) { |
| 641 hoveredTab_ = nil; | 640 hoveredTab_ = nil; |
| 642 } | 641 } |
| 643 | 642 |
| 644 NSValue *identifier = [NSValue valueWithPointer:tab]; | 643 NSValue* identifier = [NSValue valueWithPointer:tab]; |
| 645 [targetFrames_ removeObjectForKey:identifier]; | 644 [targetFrames_ removeObjectForKey:identifier]; |
| 646 | 645 |
| 647 // Once we're totally done with the tab, delete its controller | 646 // Once we're totally done with the tab, delete its controller |
| 648 [tabArray_ removeObjectAtIndex:index]; | 647 [tabArray_ removeObjectAtIndex:index]; |
| 649 | 648 |
| 650 // Send a broadcast that the number of tabs have changed. | 649 // Send a broadcast that the number of tabs have changed. |
| 651 [[NSNotificationCenter defaultCenter] | 650 [[NSNotificationCenter defaultCenter] |
| 652 postNotificationName:kTabStripNumberOfTabsChanged | 651 postNotificationName:kTabStripNumberOfTabsChanged |
| 653 object:self]; | 652 object:self]; |
| 654 | 653 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 [tabContentsArray_ insertObject:movedController.get() atIndex:to]; | 774 [tabContentsArray_ insertObject:movedController.get() atIndex:to]; |
| 776 scoped_nsobject<TabView> movedView( | 775 scoped_nsobject<TabView> movedView( |
| 777 [[tabArray_ objectAtIndex:from] retain]); | 776 [[tabArray_ objectAtIndex:from] retain]); |
| 778 [tabArray_ removeObjectAtIndex:from]; | 777 [tabArray_ removeObjectAtIndex:from]; |
| 779 [tabArray_ insertObject:movedView.get() atIndex:to]; | 778 [tabArray_ insertObject:movedView.get() atIndex:to]; |
| 780 | 779 |
| 781 [self layoutTabs]; | 780 [self layoutTabs]; |
| 782 } | 781 } |
| 783 | 782 |
| 784 - (void)setFrameOfSelectedTab:(NSRect)frame { | 783 - (void)setFrameOfSelectedTab:(NSRect)frame { |
| 785 NSView *view = [self selectedTabView]; | 784 NSView* view = [self selectedTabView]; |
| 786 NSValue *identifier = [NSValue valueWithPointer:view]; | 785 NSValue* identifier = [NSValue valueWithPointer:view]; |
| 787 [targetFrames_ setObject:[NSValue valueWithRect:frame] | 786 [targetFrames_ setObject:[NSValue valueWithRect:frame] |
| 788 forKey:identifier]; | 787 forKey:identifier]; |
| 789 [view setFrame:frame]; | 788 [view setFrame:frame]; |
| 790 } | 789 } |
| 791 | 790 |
| 792 - (NSView *)selectedTabView { | 791 - (NSView*)selectedTabView { |
| 793 int selectedIndex = tabModel_->selected_index(); | 792 int selectedIndex = tabModel_->selected_index(); |
| 794 return [self viewAtIndex:selectedIndex]; | 793 return [self viewAtIndex:selectedIndex]; |
| 795 } | 794 } |
| 796 | 795 |
| 797 // Find the index based on the x coordinate of the placeholder. If there is | 796 // Find the index based on the x coordinate of the placeholder. If there is |
| 798 // no placeholder, this returns the end of the tab strip. | 797 // no placeholder, this returns the end of the tab strip. |
| 799 - (int)indexOfPlaceholder { | 798 - (int)indexOfPlaceholder { |
| 800 double placeholderX = placeholderFrame_.origin.x; | 799 double placeholderX = placeholderFrame_.origin.x; |
| 801 int index = 0; | 800 int index = 0; |
| 802 int location = 0; | 801 int location = 0; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 830 // is no placeholder, it will go at the end. Used when dragging from another | 829 // is no placeholder, it will go at the end. Used when dragging from another |
| 831 // window when we don't have access to the TabContents as part of our strip. | 830 // window when we don't have access to the TabContents as part of our strip. |
| 832 - (void)dropTabContents:(TabContents*)contents { | 831 - (void)dropTabContents:(TabContents*)contents { |
| 833 int index = [self indexOfPlaceholder]; | 832 int index = [self indexOfPlaceholder]; |
| 834 | 833 |
| 835 // Insert it into this tab strip. We want it in the foreground and to not | 834 // Insert it into this tab strip. We want it in the foreground and to not |
| 836 // inherit the current tab's group. | 835 // inherit the current tab's group. |
| 837 tabModel_->InsertTabContentsAt(index, contents, true, false); | 836 tabModel_->InsertTabContentsAt(index, contents, true, false); |
| 838 } | 837 } |
| 839 | 838 |
| 840 - (void)applyTheme { | |
| 841 for (TabController* tab in tabArray_.get()) { | |
| 842 [tab applyTheme]; | |
| 843 } | |
| 844 } | |
| 845 | |
| 846 // Called when the tab strip view changes size. As we only registered for | 839 // Called when the tab strip view changes size. As we only registered for |
| 847 // changes on our view, we know it's only for our view. Layout w/out | 840 // changes on our view, we know it's only for our view. Layout w/out |
| 848 // animations since they are blocked by the resize nested runloop. We need | 841 // animations since they are blocked by the resize nested runloop. We need |
| 849 // the views to adjust immediately. Neither the tabs nor their z-order are | 842 // the views to adjust immediately. Neither the tabs nor their z-order are |
| 850 // changed, so we don't need to update the subviews. | 843 // changed, so we don't need to update the subviews. |
| 851 - (void)tabViewFrameChanged:(NSNotification*)info { | 844 - (void)tabViewFrameChanged:(NSNotification*)info { |
| 852 [self layoutTabsWithAnimation:NO regenerateSubviews:NO]; | 845 [self layoutTabsWithAnimation:NO regenerateSubviews:NO]; |
| 853 } | 846 } |
| 854 | 847 |
| 855 - (BOOL)inRapidClosureMode { | 848 - (BOOL)inRapidClosureMode { |
| 856 return availableResizeWidth_ != kUseFullAvailableWidth; | 849 return availableResizeWidth_ != kUseFullAvailableWidth; |
| 857 } | 850 } |
| 858 | 851 |
| 859 - (void)mouseMoved:(NSEvent *)event { | 852 - (void)mouseMoved:(NSEvent*)event { |
| 860 // Use hit test to figure out what view we are hovering over. | 853 // Use hit test to figure out what view we are hovering over. |
| 861 TabView* targetView = (TabView*)[tabView_ hitTest:[event locationInWindow]]; | 854 TabView* targetView = (TabView*)[tabView_ hitTest:[event locationInWindow]]; |
| 862 if (![targetView isKindOfClass:[TabView class]]) { | 855 if (![targetView isKindOfClass:[TabView class]]) { |
| 863 if ([[targetView superview] isKindOfClass:[TabView class]]) { | 856 if ([[targetView superview] isKindOfClass:[TabView class]]) { |
| 864 targetView = (TabView*)[targetView superview]; | 857 targetView = (TabView*)[targetView superview]; |
| 865 } else { | 858 } else { |
| 866 targetView = nil; | 859 targetView = nil; |
| 867 } | 860 } |
| 868 } | 861 } |
| 869 | 862 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 985 BrowserWindowController* controller = | 978 BrowserWindowController* controller = |
| 986 (BrowserWindowController*)[[switchView_ window] windowController]; | 979 (BrowserWindowController*)[[switchView_ window] windowController]; |
| 987 DCHECK(index >= 0); | 980 DCHECK(index >= 0); |
| 988 if (index >= 0) { | 981 if (index >= 0) { |
| 989 [controller setTab:[self viewAtIndex:index] isDraggable:YES]; | 982 [controller setTab:[self viewAtIndex:index] isDraggable:YES]; |
| 990 } | 983 } |
| 991 } | 984 } |
| 992 | 985 |
| 993 | 986 |
| 994 @end | 987 @end |
| OLD | NEW |