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

Side by Side Diff: ios/chrome/browser/ui/tabs/tab_strip_controller.mm

Issue 2628533002: Fix tabs are not rendered properly when restore tabs after crash on iPad (Closed)
Patch Set: Addressed feedback Created 3 years, 11 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
« 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 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 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 // current position. (If dropped, the tab would be at this index in the model.) 279 // current position. (If dropped, the tab would be at this index in the model.)
280 // TODO(rohitrao): Implement this method. 280 // TODO(rohitrao): Implement this method.
281 - (NSUInteger)modelIndexForDraggedTab; 281 - (NSUInteger)modelIndexForDraggedTab;
282 #endif 282 #endif
283 283
284 // Returns the horizontal visible tab strip width used to compute the tab width 284 // Returns the horizontal visible tab strip width used to compute the tab width
285 // and the tabs and new tab button in regular layout mode. 285 // and the tabs and new tab button in regular layout mode.
286 // Takes into account whether or not the mode toggle button is showing. 286 // Takes into account whether or not the mode toggle button is showing.
287 - (CGFloat)tabStripVisibleSpace; 287 - (CGFloat)tabStripVisibleSpace;
288 288
289 // shift all of the tab strip subviews by an amount equal to the content offset
rohitrao (ping after 24h) 2017/01/24 14:19:23 Capitalize "Shift".
liaoyuke 2017/01/25 16:49:37 Done.
290 // change, which effectively places the subviews back where they were before the
291 // change, in terms of screen coordinates.
292 - (void)shiftTabStripSubviews:(CGPoint)oldContentOffset;
293
289 // Updates the scroll view's content size based on the current set of tabs and 294 // Updates the scroll view's content size based on the current set of tabs and
290 // closing tabs. After updating the content size, repositions views so they 295 // closing tabs. After updating the content size, repositions views so they
291 // they will appear stationary on screen. 296 // they will appear stationary on screen.
292 - (void)updateContentSizeAndRepositionViews; 297 - (void)updateContentSizeAndRepositionViews;
293 298
294 // Returns the frame, in the scroll view content's coordinate system, of the 299 // Returns the frame, in the scroll view content's coordinate system, of the
295 // given tab view. 300 // given tab view.
296 - (CGRect)scrollViewFrameForTab:(TabView*)view; 301 - (CGRect)scrollViewFrameForTab:(TabView*)view;
297 302
298 // Returns the portion of |frame| which is not covered by |frameOnTop|. 303 // Returns the portion of |frame| which is not covered by |frameOnTop|.
299 - (CGRect)calculateVisibleFrameForFrame:(CGRect)frame 304 - (CGRect)calculateVisibleFrameForFrame:(CGRect)frame
300 whenUnderFrame:(CGRect)frameOnTop; 305 whenUnderFrame:(CGRect)frameOnTop;
301 306
302 // Schedules a layout of the scroll view and sets the internal |_animateLayout| 307 // Schedules a layout of the scroll view and sets the internal |_animateLayout|
303 // flag so that the layout will be animated. 308 // flag so that the layout will be animated.
304 - (void)setNeedsLayoutWithAnimation; 309 - (void)setNeedsLayoutWithAnimation;
305 310
306 // Returns the maximum number of collapsed tabs depending on the current layout 311 // Returns the maximum number of collapsed tabs depending on the current layout
307 // mode. 312 // mode.
308 - (NSUInteger)maxNumCollapsedTabs; 313 - (NSUInteger)maxNumCollapsedTabs;
309 314
310 // Returns the tab overlap width depending on the current layout mode. 315 // Returns the tab overlap width depending on the current layout mode.
311 - (CGFloat)tabOverlap; 316 - (CGFloat)tabOverlap;
312 317
313 // Returns the minimum tab view width depending on the current layout mode. 318 // Returns the minimum tab view width depending on the current layout mode.
314 - (CGFloat)minTabWidth; 319 - (CGFloat)minTabWidth;
315 320
321 // Automatically scroll the tab strip view to keep the newly inserted tab view
322 // visible.
323 // This method must be called with a valid |tabIndex|.
324 - (void)AutoScrollForNewTab:(NSUInteger)tabIndex;
rohitrao (ping after 24h) 2017/01/24 14:19:23 Lowercase "a" to start the method name.
liaoyuke 2017/01/25 16:49:37 Done.
325
316 // Updates the content offset of the tab strip view in order to keep the 326 // Updates the content offset of the tab strip view in order to keep the
317 // selected tab view visible. 327 // selected tab view visible.
318 // Content offset adjustement is only needed/performed in compact mode or 328 // Content offset adjustement is only needed/performed in compact mode or
319 // regular mode for newly opened tabs. 329 // regular mode for newly opened tabs.
320 // This method must be called with a valid |tabIndex|. 330 // This method must be called with a valid |tabIndex|.
321 - (void)updateContentOffsetForTabIndex:(NSUInteger)tabIndex 331 - (void)updateContentOffsetForTabIndex:(NSUInteger)tabIndex
322 isNewTab:(BOOL)isNewTab; 332 isNewTab:(BOOL)isNewTab;
323 333
324 // Update the frame of the tab strip view (scrollview) frame, content inset and 334 // Update the frame of the tab strip view (scrollview) frame, content inset and
325 // toggle buttons states depending on the current layout mode. 335 // toggle buttons states depending on the current layout mode.
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 1172
1163 - (void)removeTabSwitcherToggleButton { 1173 - (void)removeTabSwitcherToggleButton {
1164 // Remove the button view. 1174 // Remove the button view.
1165 DCHECK(_tabSwitcherToggleButton); 1175 DCHECK(_tabSwitcherToggleButton);
1166 [_tabSwitcherToggleButton removeFromSuperview]; 1176 [_tabSwitcherToggleButton removeFromSuperview];
1167 _tabSwitcherToggleButton = nil; 1177 _tabSwitcherToggleButton = nil;
1168 // Extend the scroll view. 1178 // Extend the scroll view.
1169 [self updateScrollViewFrameForToggleButton]; 1179 [self updateScrollViewFrameForToggleButton];
1170 } 1180 }
1171 1181
1182 - (void)shiftTabStripSubviews:(CGPoint)oldContentOffset {
1183 CGFloat dx = [_tabStripView contentOffset].x - oldContentOffset.x;
1184 for (UIView* view in [_tabStripView subviews]) {
1185 CGRect frame = [view frame];
1186 frame.origin.x += dx;
1187 [view setFrame:frame];
1188 _targetFrames.AddFrame(view, frame);
1189 }
1190 }
1191
1172 - (void)updateContentSizeAndRepositionViews { 1192 - (void)updateContentSizeAndRepositionViews {
1173 // TODO(rohitrao): The following lines are duplicated in 1193 // TODO(rohitrao): The following lines are duplicated in
1174 // layoutTabStripSubviews. Find a way to consolidate this logic. 1194 // layoutTabStripSubviews. Find a way to consolidate this logic.
1175 const NSUInteger tabCount = [_tabArray count] - [_closingTabs count]; 1195 const NSUInteger tabCount = [_tabArray count] - [_closingTabs count];
1176 if (!tabCount) 1196 if (!tabCount)
1177 return; 1197 return;
1178 const CGFloat tabHeight = CGRectGetHeight([_tabStripView bounds]); 1198 const CGFloat tabHeight = CGRectGetHeight([_tabStripView bounds]);
1179 CGFloat visibleSpace = [self tabStripVisibleSpace]; 1199 CGFloat visibleSpace = [self tabStripVisibleSpace];
1180 _currentTabWidth = 1200 _currentTabWidth =
1181 (visibleSpace + ([self tabOverlap] * (tabCount - 1))) / tabCount; 1201 (visibleSpace + ([self tabOverlap] * (tabCount - 1))) / tabCount;
1182 _currentTabWidth = MIN(_currentTabWidth, kMaxTabWidth); 1202 _currentTabWidth = MIN(_currentTabWidth, kMaxTabWidth);
1183 _currentTabWidth = MAX(_currentTabWidth, [self minTabWidth]); 1203 _currentTabWidth = MAX(_currentTabWidth, [self minTabWidth]);
1184 1204
1185 // Set the content size to be large enough to contain all the tabs at the 1205 // Set the content size to be large enough to contain all the tabs at the
1186 // desired width, with the standard overlap, plus the new tab button. 1206 // desired width, with the standard overlap, plus the new tab button.
1187 CGSize contentSize = CGSizeMake( 1207 CGSize contentSize = CGSizeMake(
1188 _currentTabWidth * tabCount - ([self tabOverlap] * (tabCount - 1)) + 1208 _currentTabWidth * tabCount - ([self tabOverlap] * (tabCount - 1)) +
1189 CGRectGetWidth([_buttonNewTab frame]) - kNewTabOverlap, 1209 CGRectGetWidth([_buttonNewTab frame]) - kNewTabOverlap,
1190 tabHeight); 1210 tabHeight);
1191 if (CGSizeEqualToSize([_tabStripView contentSize], contentSize)) 1211 if (CGSizeEqualToSize([_tabStripView contentSize], contentSize))
1192 return; 1212 return;
1193 1213
1194 // Background: The scroll view might change the content offset when updating 1214 // Background: The scroll view might change the content offset when updating
1195 // the content size. This can happen when the old content offset would result 1215 // the content size. This can happen when the old content offset would result
1196 // in an overscroll at the new content size. (Note that the content offset 1216 // in an overscroll at the new content size. (Note that the content offset
1197 // will never change if the content size is growing.) 1217 // will never change if the content size is growing.)
1198 // 1218 //
1199 // To handle this without making views appear to jump, shift all of the 1219 // To handle this without making views appear to jump, shift all of the
1200 // subviews by an amount equal to the size change. This effectively places 1220 // subviews by an amount equal to the size change.
1201 // the subviews back where they were before the change, in terms of screen
1202 // coordinates.
1203 CGPoint oldOffset = [_tabStripView contentOffset]; 1221 CGPoint oldOffset = [_tabStripView contentOffset];
1204 [_tabStripView setContentSize:contentSize]; 1222 [_tabStripView setContentSize:contentSize];
1205 1223 [self shiftTabStripSubviews:oldOffset];
1206 CGFloat dx = [_tabStripView contentOffset].x - oldOffset.x;
1207 for (UIView* view in [_tabStripView subviews]) {
1208 CGRect frame = [view frame];
1209 frame.origin.x += dx;
1210 [view setFrame:frame];
1211 _targetFrames.AddFrame(view, frame);
1212 }
1213 } 1224 }
1214 1225
1215 - (CGRect)scrollViewFrameForTab:(TabView*)view { 1226 - (CGRect)scrollViewFrameForTab:(TabView*)view {
1216 NSUInteger index = [self modelIndexForTabView:view]; 1227 NSUInteger index = [self modelIndexForTabView:view];
1217 1228
1218 CGRect frame = [view frame]; 1229 CGRect frame = [view frame];
1219 frame.origin.x = 1230 frame.origin.x =
1220 (_currentTabWidth * index) - ([self tabOverlap] * (index - 1)); 1231 (_currentTabWidth * index) - ([self tabOverlap] * (index - 1));
1221 return frame; 1232 return frame;
1222 } 1233 }
(...skipping 22 matching lines...) Expand all
1245 } 1256 }
1246 1257
1247 - (CGFloat)tabOverlap { 1258 - (CGFloat)tabOverlap {
1248 return IsCompactTablet() ? kTabOverlapForCompactLayout : kTabOverlap; 1259 return IsCompactTablet() ? kTabOverlapForCompactLayout : kTabOverlap;
1249 } 1260 }
1250 1261
1251 - (CGFloat)minTabWidth { 1262 - (CGFloat)minTabWidth {
1252 return IsCompactTablet() ? kMinTabWidthForCompactLayout : kMinTabWidth; 1263 return IsCompactTablet() ? kMinTabWidthForCompactLayout : kMinTabWidth;
1253 } 1264 }
1254 1265
1266 - (void)updateContentOffsetForLastTab {
rohitrao (ping after 24h) 2017/01/24 14:19:23 Is this needed?
liaoyuke 2017/01/25 16:49:37 Done.
1267 }
1268
1269 - (void)AutoScrollForNewTab:(NSUInteger)tabIndex {
1270 DCHECK_NE(NSNotFound, static_cast<NSInteger>(tabIndex));
1271
1272 // The following code calculates the amount of scroll needed to make
1273 // |tabIndex| visible in the "virtual" coordinate system, where root is x=0
1274 // and it contains all the tabs laid out as if the tabstrip was infinitely
1275 // long. The amount of scroll is calculated as a desired length that it is
1276 // just large enough to contain all the tabs to the left of |tabIndex|, with
1277 // the standard overlap.
1278 if (tabIndex == [_tabArray count] - 1) {
1279 const CGFloat tabStripAvailableSpace =
1280 _tabStripView.frame.size.width - _tabStripView.contentInset.right;
1281 CGPoint oldOffset = [_tabStripView contentOffset];
1282 if (_tabStripView.contentSize.width > tabStripAvailableSpace) {
1283 CGFloat scrollToPoint =
1284 _tabStripView.contentSize.width - tabStripAvailableSpace;
1285 [_tabStripView setContentOffset:CGPointMake(scrollToPoint, 0)];
1286 }
1287
1288 // To handle content offset change without making views appear to jump,
1289 // shift all of the subviews by an amount equal to the size change.
1290 [self shiftTabStripSubviews:oldOffset];
1291 return;
1292 }
1293
1294 NSUInteger numNonClosingTabsToLeft = 0;
1295 NSUInteger i = 0;
1296 for (TabView* tab in _tabArray.get()) {
1297 if ([_closingTabs containsObject:tab])
1298 ++i;
1299
1300 if (i == tabIndex)
1301 break;
1302
1303 ++numNonClosingTabsToLeft;
1304 ++i;
1305 }
1306
1307 const CGFloat tabHeight = CGRectGetHeight([_tabStripView bounds]);
1308 CGRect scrollRect =
1309 CGRectMake(_currentTabWidth * numNonClosingTabsToLeft -
1310 ([self tabOverlap] * (numNonClosingTabsToLeft - 1)),
1311 0, _currentTabWidth, tabHeight);
1312 [_tabStripView scrollRectToVisible:scrollRect animated:YES];
1313 }
1314
1255 - (void)updateContentOffsetForTabIndex:(NSUInteger)tabIndex 1315 - (void)updateContentOffsetForTabIndex:(NSUInteger)tabIndex
1256 isNewTab:(BOOL)isNewTab { 1316 isNewTab:(BOOL)isNewTab {
1257 DCHECK_NE(NSNotFound, static_cast<NSInteger>(tabIndex)); 1317 DCHECK_NE(NSNotFound, static_cast<NSInteger>(tabIndex));
1258 1318
1259 if (experimental_flags::IsTabStripAutoScrollNewTabsEnabled() && isNewTab) { 1319 if (experimental_flags::IsTabStripAutoScrollNewTabsEnabled() && isNewTab) {
1260 // The following code calculates the amount of scroll needed to make 1320 [self AutoScrollForNewTab:tabIndex];
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; 1321 return;
1286 } 1322 }
1287 1323
1288 if (IsCompactTablet()) { 1324 if (IsCompactTablet()) {
1289 if (tabIndex == [_tabArray count] - 1) { 1325 if (tabIndex == [_tabArray count] - 1) {
1290 const CGFloat tabStripAvailableSpace = 1326 const CGFloat tabStripAvailableSpace =
1291 _tabStripView.frame.size.width - _tabStripView.contentInset.right; 1327 _tabStripView.frame.size.width - _tabStripView.contentInset.right;
1292 if (_tabStripView.contentSize.width > tabStripAvailableSpace) { 1328 if (_tabStripView.contentSize.width > tabStripAvailableSpace) {
1293 CGFloat scrollToPoint = 1329 CGFloat scrollToPoint =
1294 _tabStripView.contentSize.width - tabStripAvailableSpace; 1330 _tabStripView.contentSize.width - tabStripAvailableSpace;
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 1725
1690 @implementation TabStripController (Testing) 1726 @implementation TabStripController (Testing)
1691 1727
1692 - (TabView*)existingTabViewForTab:(Tab*)tab { 1728 - (TabView*)existingTabViewForTab:(Tab*)tab {
1693 NSUInteger tabIndex = [_tabModel indexOfTab:tab]; 1729 NSUInteger tabIndex = [_tabModel indexOfTab:tab];
1694 NSUInteger tabViewIndex = [self indexForModelIndex:tabIndex]; 1730 NSUInteger tabViewIndex = [self indexForModelIndex:tabIndex];
1695 return [_tabArray objectAtIndex:tabViewIndex]; 1731 return [_tabArray objectAtIndex:tabViewIndex];
1696 } 1732 }
1697 1733
1698 @end 1734 @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