| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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 "ios/chrome/browser/ui/tabs/tab_strip_controller.h" | 5 #import "ios/chrome/browser/ui/tabs/tab_strip_controller.h" |
| 6 #import "ios/chrome/browser/ui/tabs/tab_strip_controller_private.h" | 6 #import "ios/chrome/browser/ui/tabs/tab_strip_controller_private.h" |
| 7 | 7 |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 - (NSUInteger)maxNumCollapsedTabs; | 308 - (NSUInteger)maxNumCollapsedTabs; |
| 309 | 309 |
| 310 // Returns the tab overlap width depending on the current layout mode. | 310 // Returns the tab overlap width depending on the current layout mode. |
| 311 - (CGFloat)tabOverlap; | 311 - (CGFloat)tabOverlap; |
| 312 | 312 |
| 313 // Returns the minimum tab view width depending on the current layout mode. | 313 // Returns the minimum tab view width depending on the current layout mode. |
| 314 - (CGFloat)minTabWidth; | 314 - (CGFloat)minTabWidth; |
| 315 | 315 |
| 316 // Updates the content offset of the tab strip view in order to keep the | 316 // Updates the content offset of the tab strip view in order to keep the |
| 317 // selected tab view visible. | 317 // selected tab view visible. |
| 318 // Content offset adjustement is only needed/performed in compact mode. | 318 // Content offset adjustement is only needed/performed in compact mode or |
| 319 // regular mode for newly opened tabs. |
| 319 // This method must be called with a valid |tabIndex|. | 320 // This method must be called with a valid |tabIndex|. |
| 320 - (void)updateContentOffsetForTabIndex:(NSUInteger)tabIndex; | 321 - (void)updateContentOffsetForTabIndex:(NSUInteger)tabIndex |
| 322 isNewTab:(BOOL)isNewTab; |
| 321 | 323 |
| 322 // Update the frame of the tab strip view (scrollview) frame, content inset and | 324 // Update the frame of the tab strip view (scrollview) frame, content inset and |
| 323 // toggle buttons states depending on the current layout mode. | 325 // toggle buttons states depending on the current layout mode. |
| 324 - (void)updateScrollViewFrameForToggleButton; | 326 - (void)updateScrollViewFrameForToggleButton; |
| 325 | 327 |
| 326 @end | 328 @end |
| 327 | 329 |
| 328 @implementation TabStripController | 330 @implementation TabStripController |
| 329 | 331 |
| 330 @synthesize buttonNewTab = _buttonNewTab; | 332 @synthesize buttonNewTab = _buttonNewTab; |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 632 NSUInteger index = [self modelIndexForTabView:(TabView*)sender]; | 634 NSUInteger index = [self modelIndexForTabView:(TabView*)sender]; |
| 633 DCHECK_NE(NSNotFound, static_cast<NSInteger>(index)); | 635 DCHECK_NE(NSNotFound, static_cast<NSInteger>(index)); |
| 634 if (index == NSNotFound) | 636 if (index == NSNotFound) |
| 635 return; | 637 return; |
| 636 Tab* tappedTab = [_tabModel tabAtIndex:index]; | 638 Tab* tappedTab = [_tabModel tabAtIndex:index]; |
| 637 Tab* currentTab = [_tabModel currentTab]; | 639 Tab* currentTab = [_tabModel currentTab]; |
| 638 if (IsIPadIdiom() && (currentTab != tappedTab)) { | 640 if (IsIPadIdiom() && (currentTab != tappedTab)) { |
| 639 [currentTab updateSnapshotWithOverlay:YES visibleFrameOnly:YES]; | 641 [currentTab updateSnapshotWithOverlay:YES visibleFrameOnly:YES]; |
| 640 } | 642 } |
| 641 [_tabModel setCurrentTab:tappedTab]; | 643 [_tabModel setCurrentTab:tappedTab]; |
| 642 [self updateContentOffsetForTabIndex:index]; | 644 [self updateContentOffsetForTabIndex:index isNewTab:NO]; |
| 643 } | 645 } |
| 644 | 646 |
| 645 - (void)closeTab:(id)sender { | 647 - (void)closeTab:(id)sender { |
| 646 // Ignore taps while in reordering mode. | 648 // Ignore taps while in reordering mode. |
| 647 // TODO(rohitrao): We should just hide the close buttons instead. | 649 // TODO(rohitrao): We should just hide the close buttons instead. |
| 648 if ([self isReorderingTabs]) | 650 if ([self isReorderingTabs]) |
| 649 return; | 651 return; |
| 650 | 652 |
| 651 base::RecordAction(UserMetricsAction("MobileTabStripCloseTab")); | 653 base::RecordAction(UserMetricsAction("MobileTabStripCloseTab")); |
| 652 DCHECK([sender isKindOfClass:[UIButton class]]); | 654 DCHECK([sender isKindOfClass:[UIButton class]]); |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 936 - (void)tabModel:(TabModel*)model | 938 - (void)tabModel:(TabModel*)model |
| 937 didInsertTab:(Tab*)tab | 939 didInsertTab:(Tab*)tab |
| 938 atIndex:(NSUInteger)modelIndex | 940 atIndex:(NSUInteger)modelIndex |
| 939 inForeground:(BOOL)fg { | 941 inForeground:(BOOL)fg { |
| 940 TabView* view = [self tabViewForTab:tab isSelected:fg]; | 942 TabView* view = [self tabViewForTab:tab isSelected:fg]; |
| 941 [_tabArray insertObject:view atIndex:[self indexForModelIndex:modelIndex]]; | 943 [_tabArray insertObject:view atIndex:[self indexForModelIndex:modelIndex]]; |
| 942 [[self tabStripView] addSubview:view]; | 944 [[self tabStripView] addSubview:view]; |
| 943 | 945 |
| 944 [self updateContentSizeAndRepositionViews]; | 946 [self updateContentSizeAndRepositionViews]; |
| 945 [self setNeedsLayoutWithAnimation]; | 947 [self setNeedsLayoutWithAnimation]; |
| 946 [self updateContentOffsetForTabIndex:modelIndex]; | 948 [self updateContentOffsetForTabIndex:modelIndex isNewTab:YES]; |
| 947 } | 949 } |
| 948 | 950 |
| 949 // Observer method. | 951 // Observer method. |
| 950 - (void)tabModel:(TabModel*)model | 952 - (void)tabModel:(TabModel*)model |
| 951 didRemoveTab:(Tab*)tab | 953 didRemoveTab:(Tab*)tab |
| 952 atIndex:(NSUInteger)modelIndex { | 954 atIndex:(NSUInteger)modelIndex { |
| 953 // Keep the actual view around while it is animating out. Once the animation | 955 // Keep the actual view around while it is animating out. Once the animation |
| 954 // is done, remove the view. | 956 // is done, remove the view. |
| 955 NSUInteger index = [self indexForModelIndex:modelIndex]; | 957 NSUInteger index = [self indexForModelIndex:modelIndex]; |
| 956 TabView* view = [_tabArray objectAtIndex:index]; | 958 TabView* view = [_tabArray objectAtIndex:index]; |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1243 } | 1245 } |
| 1244 | 1246 |
| 1245 - (CGFloat)tabOverlap { | 1247 - (CGFloat)tabOverlap { |
| 1246 return IsCompactTablet() ? kTabOverlapForCompactLayout : kTabOverlap; | 1248 return IsCompactTablet() ? kTabOverlapForCompactLayout : kTabOverlap; |
| 1247 } | 1249 } |
| 1248 | 1250 |
| 1249 - (CGFloat)minTabWidth { | 1251 - (CGFloat)minTabWidth { |
| 1250 return IsCompactTablet() ? kMinTabWidthForCompactLayout : kMinTabWidth; | 1252 return IsCompactTablet() ? kMinTabWidthForCompactLayout : kMinTabWidth; |
| 1251 } | 1253 } |
| 1252 | 1254 |
| 1253 - (void)updateContentOffsetForTabIndex:(NSUInteger)tabIndex { | 1255 - (void)updateContentOffsetForTabIndex:(NSUInteger)tabIndex |
| 1256 isNewTab:(BOOL)isNewTab { |
| 1254 DCHECK_NE(NSNotFound, static_cast<NSInteger>(tabIndex)); | 1257 DCHECK_NE(NSNotFound, static_cast<NSInteger>(tabIndex)); |
| 1255 | 1258 |
| 1259 if (experimental_flags::IsTabStripAutoScrollNewTabsEnabled() && isNewTab) { |
| 1260 // The following code calculates the amount of scroll needed to make |
| 1261 // |tabIndex| visible in the "virtual" coordinate system, where root is x=0 |
| 1262 // and it contains all the tabs laid out as if the tabstrip was infinitely |
| 1263 // long. The amount of scroll is calculated as a desired length that it is |
| 1264 // just large enough to contain all the tabs to the left of |tabIndex|, with |
| 1265 // the standard overlap. |
| 1266 NSUInteger numNonClosingTabsToLeft = 0; |
| 1267 NSUInteger i = 0; |
| 1268 for (TabView* tab in _tabArray.get()) { |
| 1269 if ([_closingTabs containsObject:tab]) |
| 1270 ++i; |
| 1271 |
| 1272 if (i == tabIndex) |
| 1273 break; |
| 1274 |
| 1275 ++numNonClosingTabsToLeft; |
| 1276 ++i; |
| 1277 } |
| 1278 |
| 1279 const CGFloat tabHeight = CGRectGetHeight([_tabStripView bounds]); |
| 1280 CGRect scrollRect = |
| 1281 CGRectMake(_currentTabWidth * numNonClosingTabsToLeft - |
| 1282 ([self tabOverlap] * (numNonClosingTabsToLeft - 1)), |
| 1283 0, _currentTabWidth, tabHeight); |
| 1284 [_tabStripView scrollRectToVisible:scrollRect animated:YES]; |
| 1285 return; |
| 1286 } |
| 1287 |
| 1256 if (IsCompactTablet()) { | 1288 if (IsCompactTablet()) { |
| 1257 if (tabIndex == [_tabArray count] - 1) { | 1289 if (tabIndex == [_tabArray count] - 1) { |
| 1258 const CGFloat tabStripAvailableSpace = | 1290 const CGFloat tabStripAvailableSpace = |
| 1259 _tabStripView.frame.size.width - _tabStripView.contentInset.right; | 1291 _tabStripView.frame.size.width - _tabStripView.contentInset.right; |
| 1260 if (_tabStripView.contentSize.width > tabStripAvailableSpace) { | 1292 if (_tabStripView.contentSize.width > tabStripAvailableSpace) { |
| 1261 CGFloat scrollToPoint = | 1293 CGFloat scrollToPoint = |
| 1262 _tabStripView.contentSize.width - tabStripAvailableSpace; | 1294 _tabStripView.contentSize.width - tabStripAvailableSpace; |
| 1263 [_tabStripView setContentOffset:CGPointMake(scrollToPoint, 0) | 1295 [_tabStripView setContentOffset:CGPointMake(scrollToPoint, 0) |
| 1264 animated:YES]; | 1296 animated:YES]; |
| 1265 } | 1297 } |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1596 } | 1628 } |
| 1597 completion:nil]; | 1629 completion:nil]; |
| 1598 } | 1630 } |
| 1599 } | 1631 } |
| 1600 | 1632 |
| 1601 - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { | 1633 - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { |
| 1602 [self updateScrollViewFrameForToggleButton]; | 1634 [self updateScrollViewFrameForToggleButton]; |
| 1603 [self updateContentSizeAndRepositionViews]; | 1635 [self updateContentSizeAndRepositionViews]; |
| 1604 NSUInteger selectedModelIndex = [_tabModel indexOfTab:[_tabModel currentTab]]; | 1636 NSUInteger selectedModelIndex = [_tabModel indexOfTab:[_tabModel currentTab]]; |
| 1605 if (selectedModelIndex != NSNotFound) { | 1637 if (selectedModelIndex != NSNotFound) { |
| 1606 [self updateContentOffsetForTabIndex:selectedModelIndex]; | 1638 [self updateContentOffsetForTabIndex:selectedModelIndex isNewTab:NO]; |
| 1607 } | 1639 } |
| 1608 } | 1640 } |
| 1609 | 1641 |
| 1610 - (void)setNeedsLayoutWithAnimation { | 1642 - (void)setNeedsLayoutWithAnimation { |
| 1611 _animateLayout = YES; | 1643 _animateLayout = YES; |
| 1612 [_tabStripView setNeedsLayout]; | 1644 [_tabStripView setNeedsLayout]; |
| 1613 } | 1645 } |
| 1614 | 1646 |
| 1615 @end | 1647 @end |
| 1616 | 1648 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1657 | 1689 |
| 1658 @implementation TabStripController (Testing) | 1690 @implementation TabStripController (Testing) |
| 1659 | 1691 |
| 1660 - (TabView*)existingTabViewForTab:(Tab*)tab { | 1692 - (TabView*)existingTabViewForTab:(Tab*)tab { |
| 1661 NSUInteger tabIndex = [_tabModel indexOfTab:tab]; | 1693 NSUInteger tabIndex = [_tabModel indexOfTab:tab]; |
| 1662 NSUInteger tabViewIndex = [self indexForModelIndex:tabIndex]; | 1694 NSUInteger tabViewIndex = [self indexForModelIndex:tabIndex]; |
| 1663 return [_tabArray objectAtIndex:tabViewIndex]; | 1695 return [_tabArray objectAtIndex:tabViewIndex]; |
| 1664 } | 1696 } |
| 1665 | 1697 |
| 1666 @end | 1698 @end |
| OLD | NEW |