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

Side by Side Diff: ios/chrome/browser/ui/ntp/google_landing_view_controller.mm

Issue 2857123003: Move frame-related methods out of GoogleLandingViewController (Closed)
Patch Set: Fix the number of columns Created 3 years, 7 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/ntp/google_landing_view_controller.h" 5 #import "ios/chrome/browser/ui/ntp/google_landing_view_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/mac/foundation_util.h" 9 #include "base/mac/foundation_util.h"
10 #include "base/metrics/user_metrics.h" 10 #include "base/metrics/user_metrics.h"
11 #include "base/strings/sys_string_conversions.h" 11 #include "base/strings/sys_string_conversions.h"
12 #include "components/strings/grit/components_strings.h" 12 #include "components/strings/grit/components_strings.h"
13 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" 13 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
14 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" 14 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h"
15 #include "ios/chrome/browser/ui/commands/ios_command_ids.h" 15 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
16 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_mos t_visited_item.h"
17 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collectio n_utils.h"
16 #import "ios/chrome/browser/ui/context_menu/context_menu_coordinator.h" 18 #import "ios/chrome/browser/ui/context_menu/context_menu_coordinator.h"
17 #import "ios/chrome/browser/ui/ntp/google_landing_data_source.h" 19 #import "ios/chrome/browser/ui/ntp/google_landing_data_source.h"
18 #import "ios/chrome/browser/ui/ntp/most_visited_cell.h" 20 #import "ios/chrome/browser/ui/ntp/most_visited_cell.h"
19 #import "ios/chrome/browser/ui/ntp/most_visited_layout.h" 21 #import "ios/chrome/browser/ui/ntp/most_visited_layout.h"
20 #import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h" 22 #import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h"
21 #import "ios/chrome/browser/ui/ntp/new_tab_page_header_view.h" 23 #import "ios/chrome/browser/ui/ntp/new_tab_page_header_view.h"
22 #import "ios/chrome/browser/ui/ntp/whats_new_header_view.h" 24 #import "ios/chrome/browser/ui/ntp/whats_new_header_view.h"
23 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller. h" 25 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller. h"
24 #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h" 26 #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h"
25 #include "ios/chrome/browser/ui/ui_util.h" 27 #include "ios/chrome/browser/ui/ui_util.h"
(...skipping 11 matching lines...) Expand all
37 using base::UserMetricsAction; 39 using base::UserMetricsAction;
38 40
39 namespace { 41 namespace {
40 42
41 enum { 43 enum {
42 SectionWithOmnibox, 44 SectionWithOmnibox,
43 SectionWithMostVisited, 45 SectionWithMostVisited,
44 NumberOfCollectionViewSections, 46 NumberOfCollectionViewSections,
45 }; 47 };
46 48
47 enum InterfaceOrientation {
48 ALL,
49 IPHONE_LANDSCAPE,
50 };
51
52 const CGFloat kVoiceSearchButtonWidth = 48; 49 const CGFloat kVoiceSearchButtonWidth = 48;
53 const UIEdgeInsets kSearchBoxStretchInsets = {3, 3, 3, 3}; 50 const UIEdgeInsets kSearchBoxStretchInsets = {3, 3, 3, 3};
54 51
55 // Height for the doodle frame when Google is not the default search engine.
56 const CGFloat kNonGoogleSearchDoodleHeight = 60;
57 // Height for the header view on tablet when Google is not the default search
58 // engine.
59 const CGFloat kNonGoogleSearchHeaderHeightIPad = 10;
60
61 const CGFloat kHintLabelSidePadding = 12; 52 const CGFloat kHintLabelSidePadding = 12;
62 const CGFloat kNTPSearchFieldBottomPadding = 16;
63 const CGFloat kWhatsNewHeaderHiddenHeight = 8; 53 const CGFloat kWhatsNewHeaderHiddenHeight = 8;
64 const CGFloat kDoodleTopMarginIPadPortrait = 82;
65 const CGFloat kDoodleTopMarginIPadLandscape = 82;
66 const NSInteger kMaxNumMostVisitedFaviconRows = 2; 54 const NSInteger kMaxNumMostVisitedFaviconRows = 2;
67 const CGFloat kMaxSearchFieldFrameMargin = 200;
68 const CGFloat kShiftTilesDownAnimationDuration = 0.2; 55 const CGFloat kShiftTilesDownAnimationDuration = 0.2;
69 56
70 const CGFloat kMostVisitedPaddingIPhone = 16;
71 const CGFloat kMostVisitedPaddingIPadFavicon = 24;
72
73 } // namespace 57 } // namespace
74 58
75 @interface GoogleLandingViewController (UsedByGoogleLandingView) 59 @interface GoogleLandingViewController (UsedByGoogleLandingView)
76 // Update frames for subviews depending on the interface orientation. 60 // Update frames for subviews depending on the interface orientation.
77 - (void)updateSubviewFrames; 61 - (void)updateSubviewFrames;
78 // Resets the collection view's inset to 0. 62 // Resets the collection view's inset to 0.
79 - (void)resetSectionInset; 63 - (void)resetSectionInset;
80 - (void)reloadData; 64 - (void)reloadData;
81 @end 65 @end
82 66
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 @property(nonatomic, assign) int tabCount; 181 @property(nonatomic, assign) int tabCount;
198 182
199 // |YES| if the google landing toolbar can show the forward arrow, cached and 183 // |YES| if the google landing toolbar can show the forward arrow, cached and
200 // pushed into the header view. 184 // pushed into the header view.
201 @property(nonatomic, assign) BOOL canGoForward; 185 @property(nonatomic, assign) BOOL canGoForward;
202 186
203 // |YES| if the google landing toolbar can show the back arrow, cached and 187 // |YES| if the google landing toolbar can show the back arrow, cached and
204 // pushed into the header view. 188 // pushed into the header view.
205 @property(nonatomic, assign) BOOL canGoBack; 189 @property(nonatomic, assign) BOOL canGoBack;
206 190
207 // iPhone landscape uses a slightly different layout for the doodle and search
208 // field frame. Returns the proper frame from |frames| based on orientation,
209 // centered in the view.
210 - (CGRect)getOrientationFrame:(const CGRect[])frames;
211 // Returns the proper frame for the doodle.
212 - (CGRect)doodleFrame;
213 // Returns the proper frame for the search field.
214 - (CGRect)searchFieldFrame;
215 // Returns the height to use for the What's New promo view. 191 // Returns the height to use for the What's New promo view.
216 - (CGFloat)promoHeaderHeight; 192 - (CGFloat)promoHeaderHeight;
217 // Add fake search field and voice search microphone. 193 // Add fake search field and voice search microphone.
218 - (void)addSearchField; 194 - (void)addSearchField;
219 // Add most visited collection view. 195 // Add most visited collection view.
220 - (void)addMostVisited; 196 - (void)addMostVisited;
221 // Update the iPhone fakebox's frame based on the current scroll view offset. 197 // Update the iPhone fakebox's frame based on the current scroll view offset.
222 - (void)updateSearchField; 198 - (void)updateSearchField;
223 // Scrolls most visited to the top of the view when the omnibox is focused. 199 // Scrolls most visited to the top of the view when the omnibox is focused.
224 - (void)locationBarBecomesFirstResponder; 200 - (void)locationBarBecomesFirstResponder;
(...skipping 14 matching lines...) Expand all
239 // Helper method to set UICollectionViewFlowLayout insets for most visited. 215 // Helper method to set UICollectionViewFlowLayout insets for most visited.
240 - (void)setFlowLayoutInset:(UICollectionViewFlowLayout*)layout; 216 - (void)setFlowLayoutInset:(UICollectionViewFlowLayout*)layout;
241 // Instructs the UICollectionView and UIView to reload it's data and layout. 217 // Instructs the UICollectionView and UIView to reload it's data and layout.
242 - (void)reloadData; 218 - (void)reloadData;
243 // Returns the size of |self.mostVisitedData|. 219 // Returns the size of |self.mostVisitedData|.
244 - (NSUInteger)numberOfItems; 220 - (NSUInteger)numberOfItems;
245 // Returns the number of non empty tiles (as opposed to the placeholder tiles). 221 // Returns the number of non empty tiles (as opposed to the placeholder tiles).
246 - (NSInteger)numberOfNonEmptyTilesShown; 222 - (NSInteger)numberOfNonEmptyTilesShown;
247 // Returns the URL for the mosted visited item in |self.mostVisitedData|. 223 // Returns the URL for the mosted visited item in |self.mostVisitedData|.
248 - (GURL)urlForIndex:(NSUInteger)index; 224 - (GURL)urlForIndex:(NSUInteger)index;
249 // Returns the expected height of the NewTabPageHeaderView.
250 - (CGFloat)heightForSectionWithOmnibox;
251 // Returns the nearest ancestor view that is kind of |aClass|. 225 // Returns the nearest ancestor view that is kind of |aClass|.
252 - (UIView*)nearestAncestorOfView:(UIView*)view withClass:(Class)aClass; 226 - (UIView*)nearestAncestorOfView:(UIView*)view withClass:(Class)aClass;
253 // Updates the collection view's scroll view offset for the next frame of the 227 // Updates the collection view's scroll view offset for the next frame of the
254 // shiftTilesDown animation. 228 // shiftTilesDown animation.
255 - (void)shiftTilesDownAnimationDidFire:(CADisplayLink*)link; 229 - (void)shiftTilesDownAnimationDidFire:(CADisplayLink*)link;
256 // Returns the size to use for Most Visited cells in the NTP. 230 // Returns the size to use for Most Visited cells in the NTP.
257 - (CGSize)mostVisitedCellSize; 231 - (CGSize)mostVisitedCellSize;
258 // Returns the padding for use between Most Visited cells.
259 - (CGFloat)mostVisitedCellPadding;
260 232
261 @end 233 @end
262 234
263 @implementation GoogleLandingViewController 235 @implementation GoogleLandingViewController
264 236
265 @dynamic view; 237 @dynamic view;
266 @synthesize logoVendor = _logoVendor; 238 @synthesize logoVendor = _logoVendor;
267 @synthesize dataSource = _dataSource; 239 @synthesize dataSource = _dataSource;
268 // Property declared in NewTabPagePanelProtocol. 240 // Property declared in NewTabPagePanelProtocol.
269 @synthesize delegate = _delegate; 241 @synthesize delegate = _delegate;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 #pragma mark - Private 327 #pragma mark - Private
356 328
357 - (CGSize)mostVisitedCellSize { 329 - (CGSize)mostVisitedCellSize {
358 if (IsIPadIdiom()) { 330 if (IsIPadIdiom()) {
359 // On iPads, split-screen and slide-over may require showing smaller cells. 331 // On iPads, split-screen and slide-over may require showing smaller cells.
360 CGSize maximumCellSize = [MostVisitedCell maximumSize]; 332 CGSize maximumCellSize = [MostVisitedCell maximumSize];
361 CGSize viewSize = self.view.bounds.size; 333 CGSize viewSize = self.view.bounds.size;
362 CGFloat smallestDimension = 334 CGFloat smallestDimension =
363 viewSize.height > viewSize.width ? viewSize.width : viewSize.height; 335 viewSize.height > viewSize.width ? viewSize.width : viewSize.height;
364 CGFloat cellWidth = AlignValueToPixel( 336 CGFloat cellWidth = AlignValueToPixel(
365 (smallestDimension - 3 * [self mostVisitedCellPadding]) / 2); 337 (smallestDimension - 3 * [ContentSuggestionsMostVisitedCell spacing]) /
338 2);
366 if (cellWidth < maximumCellSize.width) { 339 if (cellWidth < maximumCellSize.width) {
367 return CGSizeMake(cellWidth, cellWidth); 340 return CGSizeMake(cellWidth, cellWidth);
368 } else { 341 } else {
369 return maximumCellSize; 342 return maximumCellSize;
370 } 343 }
371 } else { 344 } else {
372 return [MostVisitedCell maximumSize]; 345 return [MostVisitedCell maximumSize];
373 } 346 }
374 } 347 }
375 348
376 - (CGFloat)mostVisitedCellPadding {
377 return IsIPadIdiom() ? kMostVisitedPaddingIPadFavicon
378 : kMostVisitedPaddingIPhone;
379 }
380
381 - (CGFloat)viewWidth { 349 - (CGFloat)viewWidth {
382 return [self.view frame].size.width; 350 return [self.view frame].size.width;
383 } 351 }
384 352
385 - (int)numberOfColumns { 353 - (int)numberOfColumns {
386 CGFloat width = [self viewWidth]; 354 CGFloat width = [self viewWidth];
387 CGFloat padding = [self mostVisitedCellPadding];
388 // Try to fit 4 columns.
389 if (width >= 5 * padding + _mostVisitedCellSize.width * 4)
390 return 4;
391 // Try to fit 3 columns.
392 if (width >= 4 * padding + _mostVisitedCellSize.width * 3)
393 return 3;
394 // Try to fit 2 columns.
395 if (width >= 3 * padding + _mostVisitedCellSize.width * 2)
396 return 2;
397 // We never want to have a layout with only one column, however: At launch,
398 // the view's size is initialized to the width of 320, which can only fit
399 // one column on iPhone 6 and 6+. TODO(crbug.com/506183): Get rid of the
400 // unecessary resize, and add a NOTREACHED() here.
401 return 1;
402 }
403 355
404 - (CGFloat)leftMargin { 356 NSUInteger columns = [ContentSuggestionsMostVisitedCell
405 int columns = [self numberOfColumns]; 357 numberOfTilesForWidth:width -
406 CGFloat whitespace = [self viewWidth] - columns * _mostVisitedCellSize.width - 358 2 * [ContentSuggestionsMostVisitedCell spacing]];
407 (columns - 1) * [self mostVisitedCellPadding]; 359 DCHECK(columns > 1);
408 CGFloat margin = AlignValueToPixel(whitespace / 2); 360 return columns;
409 DCHECK(margin >= [self mostVisitedCellPadding]);
410 return margin;
411 }
412
413 - (CGRect)doodleFrame {
414 const CGRect kDoodleFrame[2] = {
415 {{0, 66}, {0, 120}}, {{0, 56}, {0, 120}},
416 };
417 CGRect doodleFrame = [self getOrientationFrame:kDoodleFrame];
418 if (!IsIPadIdiom() && !self.logoIsShowing)
419 doodleFrame.size.height = kNonGoogleSearchDoodleHeight;
420 if (IsIPadIdiom()) {
421 doodleFrame.origin.y = IsPortrait() ? kDoodleTopMarginIPadPortrait
422 : kDoodleTopMarginIPadLandscape;
423 }
424 return doodleFrame;
425 }
426
427 - (CGRect)searchFieldFrame {
428 CGFloat y = CGRectGetMaxY([self doodleFrame]);
429 CGFloat leftMargin = [self leftMargin];
430 if (leftMargin > kMaxSearchFieldFrameMargin)
431 leftMargin = kMaxSearchFieldFrameMargin;
432 const CGRect kSearchFieldFrame[2] = {
433 {{leftMargin, y + 32}, {0, 50}}, {{leftMargin, y + 16}, {0, 50}},
434 };
435 CGRect searchFieldFrame = [self getOrientationFrame:kSearchFieldFrame];
436 if (IsIPadIdiom()) {
437 CGFloat iPadTopMargin = IsPortrait() ? kDoodleTopMarginIPadPortrait
438 : kDoodleTopMarginIPadLandscape;
439 searchFieldFrame.origin.y += iPadTopMargin - 32;
440 }
441 return searchFieldFrame;
442 }
443
444 - (CGRect)getOrientationFrame:(const CGRect[])frames {
445 UIInterfaceOrientation orient =
446 [[UIApplication sharedApplication] statusBarOrientation];
447 InterfaceOrientation inter_orient =
448 (IsIPadIdiom() || UIInterfaceOrientationIsPortrait(orient))
449 ? ALL
450 : IPHONE_LANDSCAPE;
451
452 // Calculate width based on screen width and origin x.
453 CGRect frame = frames[inter_orient];
454 frame.size.width = fmax(self.view.bounds.size.width - 2 * frame.origin.x, 50);
455 return frame;
456 } 361 }
457 362
458 - (CGFloat)promoHeaderHeight { 363 - (CGFloat)promoHeaderHeight {
459 CGFloat promoMaxWidth = [self viewWidth] - 2 * [self leftMargin]; 364 CGFloat promoMaxWidth =
365 [self viewWidth] -
366 2 * content_suggestions::leftMarginForWidth([self viewWidth]);
460 NSString* text = self.promoText; 367 NSString* text = self.promoText;
461 return [WhatsNewHeaderView heightToFitText:text inWidth:promoMaxWidth]; 368 return [WhatsNewHeaderView heightToFitText:text inWidth:promoMaxWidth];
462 } 369 }
463 370
464 - (void)updateLogoAndFakeboxDisplay { 371 - (void)updateLogoAndFakeboxDisplay {
465 if (self.logoVendor.showingLogo != self.logoIsShowing) { 372 if (self.logoVendor.showingLogo != self.logoIsShowing) {
466 self.logoVendor.showingLogo = self.logoIsShowing; 373 self.logoVendor.showingLogo = self.logoIsShowing;
467 if (_viewLoaded) { 374 if (_viewLoaded) {
468 [self updateSubviewFrames]; 375 [self updateSubviewFrames];
469 376
470 // Adjust the height of |_headerView| to fit its content which may have 377 // Adjust the height of |_headerView| to fit its content which may have
471 // been shifted due to the visibility of the doodle. 378 // been shifted due to the visibility of the doodle.
472 CGRect headerFrame = [_headerView frame]; 379 CGRect headerFrame = [_headerView frame];
473 headerFrame.size.height = [self heightForSectionWithOmnibox]; 380 headerFrame.size.height = content_suggestions::heightForLogoHeader(
381 [self viewWidth], self.logoIsShowing, self.promoCanShow);
474 [_headerView setFrame:headerFrame]; 382 [_headerView setFrame:headerFrame];
475 383
476 // Adjust vertical positioning of |_promoHeaderView|. 384 // Adjust vertical positioning of |_promoHeaderView|.
477 CGFloat omniboxHeaderHeight = 385 CGFloat omniboxHeaderHeight =
478 [self collectionView:_mostVisitedView 386 [self collectionView:_mostVisitedView
479 layout:[_mostVisitedView 387 layout:[_mostVisitedView
480 collectionViewLayout] 388 collectionViewLayout]
481 referenceSizeForHeaderInSection:0] 389 referenceSizeForHeaderInSection:0]
482 .height; 390 .height;
483 CGRect whatsNewFrame = [_promoHeaderView frame]; 391 CGRect whatsNewFrame = [_promoHeaderView frame];
484 whatsNewFrame.origin.y = omniboxHeaderHeight; 392 whatsNewFrame.origin.y = omniboxHeaderHeight;
485 [_promoHeaderView setFrame:whatsNewFrame]; 393 [_promoHeaderView setFrame:whatsNewFrame];
486 } 394 }
487 if (IsIPadIdiom()) 395 if (IsIPadIdiom())
488 [_searchTapTarget setHidden:!self.logoIsShowing]; 396 [_searchTapTarget setHidden:!self.logoIsShowing];
489 } 397 }
490 } 398 }
491 399
492 // Initialize and add a search field tap target and a voice search button. 400 // Initialize and add a search field tap target and a voice search button.
493 - (void)addSearchField { 401 - (void)addSearchField {
494 CGRect searchFieldFrame = [self searchFieldFrame]; 402 CGRect searchFieldFrame = content_suggestions::searchFieldFrame(
403 [self viewWidth], self.logoIsShowing);
495 _searchTapTarget.reset([[UIButton alloc] initWithFrame:searchFieldFrame]); 404 _searchTapTarget.reset([[UIButton alloc] initWithFrame:searchFieldFrame]);
496 if (IsIPadIdiom()) { 405 if (IsIPadIdiom()) {
497 UIImage* searchBoxImage = [[UIImage imageNamed:@"ntp_google_search_box"] 406 UIImage* searchBoxImage = [[UIImage imageNamed:@"ntp_google_search_box"]
498 resizableImageWithCapInsets:kSearchBoxStretchInsets]; 407 resizableImageWithCapInsets:kSearchBoxStretchInsets];
499 [_searchTapTarget setBackgroundImage:searchBoxImage 408 [_searchTapTarget setBackgroundImage:searchBoxImage
500 forState:UIControlStateNormal]; 409 forState:UIControlStateNormal];
501 } 410 }
502 [_searchTapTarget setAdjustsImageWhenHighlighted:NO]; 411 [_searchTapTarget setAdjustsImageWhenHighlighted:NO];
503 [_searchTapTarget addTarget:self 412 [_searchTapTarget addTarget:self
504 action:@selector(searchFieldTapped:) 413 action:@selector(searchFieldTapped:)
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 forControlEvents:UIControlEventTouchDown]; 546 forControlEvents:UIControlEventTouchDown];
638 547
639 // Use a GenericChromeCommand because |sender| already has a tag set for a 548 // Use a GenericChromeCommand because |sender| already has a tag set for a
640 // different command. 549 // different command.
641 base::scoped_nsobject<GenericChromeCommand> command( 550 base::scoped_nsobject<GenericChromeCommand> command(
642 [[GenericChromeCommand alloc] initWithTag:IDC_PRELOAD_VOICE_SEARCH]); 551 [[GenericChromeCommand alloc] initWithTag:IDC_PRELOAD_VOICE_SEARCH]);
643 [sender chromeExecuteCommand:command]; 552 [sender chromeExecuteCommand:command];
644 } 553 }
645 554
646 - (void)setFlowLayoutInset:(UICollectionViewFlowLayout*)layout { 555 - (void)setFlowLayoutInset:(UICollectionViewFlowLayout*)layout {
647 CGFloat leftMargin = [self leftMargin]; 556 CGFloat leftMargin =
557 content_suggestions::leftMarginForWidth([self viewWidth]);
648 [layout setSectionInset:UIEdgeInsetsMake(0, leftMargin, 0, leftMargin)]; 558 [layout setSectionInset:UIEdgeInsetsMake(0, leftMargin, 0, leftMargin)];
649 } 559 }
650 560
651 - (void)resetSectionInset { 561 - (void)resetSectionInset {
652 UICollectionViewFlowLayout* flowLayout = 562 UICollectionViewFlowLayout* flowLayout =
653 (UICollectionViewFlowLayout*)[_mostVisitedView collectionViewLayout]; 563 (UICollectionViewFlowLayout*)[_mostVisitedView collectionViewLayout];
654 [flowLayout setSectionInset:UIEdgeInsetsZero]; 564 [flowLayout setSectionInset:UIEdgeInsetsZero];
655 } 565 }
656 566
657 - (void)updateSubviewFrames { 567 - (void)updateSubviewFrames {
658 _mostVisitedCellSize = [self mostVisitedCellSize]; 568 _mostVisitedCellSize = [self mostVisitedCellSize];
659 UICollectionViewFlowLayout* flowLayout = 569 UICollectionViewFlowLayout* flowLayout =
660 base::mac::ObjCCastStrict<UICollectionViewFlowLayout>( 570 base::mac::ObjCCastStrict<UICollectionViewFlowLayout>(
661 [_mostVisitedView collectionViewLayout]); 571 [_mostVisitedView collectionViewLayout]);
662 [flowLayout setItemSize:_mostVisitedCellSize]; 572 [flowLayout setItemSize:_mostVisitedCellSize];
663 self.logoVendor.view.frame = [self doodleFrame]; 573 self.logoVendor.view.frame =
574 content_suggestions::doodleFrame([self viewWidth], self.logoIsShowing);
664 575
665 [self setFlowLayoutInset:flowLayout]; 576 [self setFlowLayoutInset:flowLayout];
666 [flowLayout invalidateLayout]; 577 [flowLayout invalidateLayout];
667 [_promoHeaderView setSideMargin:[self leftMargin]]; 578 [_promoHeaderView
579 setSideMargin:content_suggestions::leftMarginForWidth([self viewWidth])];
668 580
669 // On the iPhone 6 Plus, if the app is started in landscape after a fresh 581 // On the iPhone 6 Plus, if the app is started in landscape after a fresh
670 // install, the UICollectionViewLayout incorrectly sizes the widths of the 582 // install, the UICollectionViewLayout incorrectly sizes the widths of the
671 // supplementary views to the portrait width. Correct that here to ensure 583 // supplementary views to the portrait width. Correct that here to ensure
672 // that the header is property laid out to the UICollectionView's width. 584 // that the header is property laid out to the UICollectionView's width.
673 // crbug.com/491131 585 // crbug.com/491131
674 CGFloat collectionViewWidth = CGRectGetWidth([_mostVisitedView bounds]); 586 CGFloat collectionViewWidth = CGRectGetWidth([_mostVisitedView bounds]);
675 CGFloat collectionViewMinX = CGRectGetMinX([_mostVisitedView bounds]); 587 CGFloat collectionViewMinX = CGRectGetMinX([_mostVisitedView bounds]);
676 for (UIView* supplementaryView in _supplementaryViews.get()) { 588 for (UIView* supplementaryView in _supplementaryViews.get()) {
677 CGRect supplementaryViewFrame = supplementaryView.frame; 589 CGRect supplementaryViewFrame = supplementaryView.frame;
678 supplementaryViewFrame.origin.x = collectionViewMinX; 590 supplementaryViewFrame.origin.x = collectionViewMinX;
679 supplementaryViewFrame.size.width = collectionViewWidth; 591 supplementaryViewFrame.size.width = collectionViewWidth;
680 supplementaryView.frame = supplementaryViewFrame; 592 supplementaryView.frame = supplementaryViewFrame;
681 } 593 }
682 594
683 BOOL isScrollableNTP = !IsIPadIdiom() || IsCompactTablet(); 595 BOOL isScrollableNTP = !IsIPadIdiom() || IsCompactTablet();
684 if (isScrollableNTP && _scrolledToTop) { 596 if (isScrollableNTP && _scrolledToTop) {
685 // Set the scroll view's offset to the pinned offset to keep the omnibox 597 // Set the scroll view's offset to the pinned offset to keep the omnibox
686 // at the top of the screen if it isn't already. 598 // at the top of the screen if it isn't already.
687 CGFloat pinnedOffsetY = [self pinnedOffsetY]; 599 CGFloat pinnedOffsetY = [self pinnedOffsetY];
688 if ([_mostVisitedView contentOffset].y < pinnedOffsetY) { 600 if ([_mostVisitedView contentOffset].y < pinnedOffsetY) {
689 [_mostVisitedView setContentOffset:CGPointMake(0, pinnedOffsetY)]; 601 [_mostVisitedView setContentOffset:CGPointMake(0, pinnedOffsetY)];
690 } else { 602 } else {
691 [self updateSearchField]; 603 [self updateSearchField];
692 } 604 }
693 } else { 605 } else {
694 [_searchTapTarget setFrame:[self searchFieldFrame]]; 606 [_searchTapTarget setFrame:content_suggestions::searchFieldFrame(
607 [self viewWidth], self.logoIsShowing)];
695 } 608 }
696 609
697 if (!_viewLoaded) { 610 if (!_viewLoaded) {
698 _viewLoaded = YES; 611 _viewLoaded = YES;
699 [self.logoVendor fetchDoodle]; 612 [self.logoVendor fetchDoodle];
700 } 613 }
701 [self.delegate updateNtpBarShadowForPanelController:self]; 614 [self.delegate updateNtpBarShadowForPanelController:self];
702 } 615 }
703 616
704 // Initialize and add a panel with most visited sites. 617 // Initialize and add a panel with most visited sites.
705 - (void)addMostVisited { 618 - (void)addMostVisited {
706 CGRect mostVisitedFrame = [self.view bounds]; 619 CGRect mostVisitedFrame = [self.view bounds];
707 base::scoped_nsobject<UICollectionViewFlowLayout> flowLayout; 620 base::scoped_nsobject<UICollectionViewFlowLayout> flowLayout;
708 if (IsIPadIdiom()) 621 if (IsIPadIdiom())
709 flowLayout.reset([[UICollectionViewFlowLayout alloc] init]); 622 flowLayout.reset([[UICollectionViewFlowLayout alloc] init]);
710 else 623 else
711 flowLayout.reset([[MostVisitedLayout alloc] init]); 624 flowLayout.reset([[MostVisitedLayout alloc] init]);
712 625
713 [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical]; 626 [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
714 [flowLayout setItemSize:_mostVisitedCellSize]; 627 [flowLayout setItemSize:_mostVisitedCellSize];
715 [flowLayout setMinimumInteritemSpacing:8]; 628 [flowLayout setMinimumInteritemSpacing:8];
716 [flowLayout setMinimumLineSpacing:[self mostVisitedCellPadding]]; 629 [flowLayout
630 setMinimumLineSpacing:[ContentSuggestionsMostVisitedCell spacing]];
717 DCHECK(!_mostVisitedView); 631 DCHECK(!_mostVisitedView);
718 _mostVisitedView.reset([[UICollectionView alloc] 632 _mostVisitedView.reset([[UICollectionView alloc]
719 initWithFrame:mostVisitedFrame 633 initWithFrame:mostVisitedFrame
720 collectionViewLayout:flowLayout]); 634 collectionViewLayout:flowLayout]);
721 [_mostVisitedView setAutoresizingMask:UIViewAutoresizingFlexibleHeight | 635 [_mostVisitedView setAutoresizingMask:UIViewAutoresizingFlexibleHeight |
722 UIViewAutoresizingFlexibleWidth]; 636 UIViewAutoresizingFlexibleWidth];
723 [_mostVisitedView setDelegate:self]; 637 [_mostVisitedView setDelegate:self];
724 [_mostVisitedView setDataSource:self]; 638 [_mostVisitedView setDataSource:self];
725 [_mostVisitedView registerClass:[MostVisitedCell class] 639 [_mostVisitedView registerClass:[MostVisitedCell class]
726 forCellWithReuseIdentifier:@"classCell"]; 640 forCellWithReuseIdentifier:@"classCell"];
727 [_mostVisitedView setBackgroundColor:[UIColor clearColor]]; 641 [_mostVisitedView setBackgroundColor:[UIColor clearColor]];
728 [_mostVisitedView setBounces:YES]; 642 [_mostVisitedView setBounces:YES];
729 [_mostVisitedView setShowsHorizontalScrollIndicator:NO]; 643 [_mostVisitedView setShowsHorizontalScrollIndicator:NO];
730 [_mostVisitedView setShowsVerticalScrollIndicator:NO]; 644 [_mostVisitedView setShowsVerticalScrollIndicator:NO];
731 [_mostVisitedView registerClass:[WhatsNewHeaderView class] 645 [_mostVisitedView registerClass:[WhatsNewHeaderView class]
732 forSupplementaryViewOfKind:UICollectionElementKindSectionHeader 646 forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
733 withReuseIdentifier:@"whatsNew"]; 647 withReuseIdentifier:@"whatsNew"];
734 [_mostVisitedView registerClass:[NewTabPageHeaderView class] 648 [_mostVisitedView registerClass:[NewTabPageHeaderView class]
735 forSupplementaryViewOfKind:UICollectionElementKindSectionHeader 649 forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
736 withReuseIdentifier:@"header"]; 650 withReuseIdentifier:@"header"];
737 [_mostVisitedView setAccessibilityIdentifier:@"Google Landing"]; 651 [_mostVisitedView setAccessibilityIdentifier:@"Google Landing"];
738 652
739 [self.view addSubview:_mostVisitedView]; 653 [self.view addSubview:_mostVisitedView];
740 } 654 }
741 655
742 - (void)updateSearchField { 656 - (void)updateSearchField {
743 NSArray* constraints = 657 NSArray* constraints =
744 @[ _hintLabelLeadingConstraint, _voiceTapTrailingConstraint ]; 658 @[ _hintLabelLeadingConstraint, _voiceTapTrailingConstraint ];
745 [_headerView updateSearchField:_searchTapTarget 659 [_headerView updateSearchField:_searchTapTarget
746 withInitialFrame:[self searchFieldFrame] 660 withInitialFrame:content_suggestions::searchFieldFrame(
661 [self viewWidth], self.logoIsShowing)
747 subviewConstraints:constraints 662 subviewConstraints:constraints
748 forOffset:[_mostVisitedView contentOffset].y]; 663 forOffset:[_mostVisitedView contentOffset].y];
749 } 664 }
750 665
751 - (void)addOverscrollActions { 666 - (void)addOverscrollActions {
752 if (!IsIPadIdiom()) { 667 if (!IsIPadIdiom()) {
753 _overscrollActionsController.reset([[OverscrollActionsController alloc] 668 _overscrollActionsController.reset([[OverscrollActionsController alloc]
754 initWithScrollView:_mostVisitedView]); 669 initWithScrollView:_mostVisitedView]);
755 [_overscrollActionsController setStyle:OverscrollStyle::NTP_NON_INCOGNITO]; 670 [_overscrollActionsController setStyle:OverscrollStyle::NTP_NON_INCOGNITO];
756 [_overscrollActionsController setDelegate:self]; 671 [_overscrollActionsController setDelegate:self];
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 // -invalidateLayout is necessary because sometimes the flowLayout has the 809 // -invalidateLayout is necessary because sometimes the flowLayout has the
895 // wrong cached size and will throw an internal exception if the 810 // wrong cached size and will throw an internal exception if the
896 // -numberOfItems shrinks. -setNeedsLayout is needed in case 811 // -numberOfItems shrinks. -setNeedsLayout is needed in case
897 // -numberOfItems increases enough to add a new row and change the height 812 // -numberOfItems increases enough to add a new row and change the height
898 // of _mostVisitedView. 813 // of _mostVisitedView.
899 [_mostVisitedView reloadData]; 814 [_mostVisitedView reloadData];
900 [[_mostVisitedView collectionViewLayout] invalidateLayout]; 815 [[_mostVisitedView collectionViewLayout] invalidateLayout];
901 [self.view setNeedsLayout]; 816 [self.view setNeedsLayout];
902 } 817 }
903 818
904 - (CGFloat)heightForSectionWithOmnibox {
905 CGFloat headerHeight =
906 CGRectGetMaxY([self searchFieldFrame]) + kNTPSearchFieldBottomPadding;
907 if (IsIPadIdiom()) {
908 if (self.logoIsShowing) {
909 if (!self.promoCanShow) {
910 UIInterfaceOrientation orient =
911 [[UIApplication sharedApplication] statusBarOrientation];
912 const CGFloat kTopSpacingMaterialPortrait = 56;
913 const CGFloat kTopSpacingMaterialLandscape = 32;
914 headerHeight += UIInterfaceOrientationIsPortrait(orient)
915 ? kTopSpacingMaterialPortrait
916 : kTopSpacingMaterialLandscape;
917 }
918 } else {
919 headerHeight = kNonGoogleSearchHeaderHeightIPad;
920 }
921 }
922 return headerHeight;
923 }
924
925 #pragma mark - ToolbarOwner 819 #pragma mark - ToolbarOwner
926 820
927 - (ToolbarController*)relinquishedToolbarController { 821 - (ToolbarController*)relinquishedToolbarController {
928 return [_headerView relinquishedToolbarController]; 822 return [_headerView relinquishedToolbarController];
929 } 823 }
930 824
931 - (void)reparentToolbarController { 825 - (void)reparentToolbarController {
932 [_headerView reparentToolbarController]; 826 [_headerView reparentToolbarController];
933 } 827 }
934 828
935 #pragma mark - UICollectionView Methods. 829 #pragma mark - UICollectionView Methods.
936 830
937 - (CGSize)collectionView:(UICollectionView*)collectionView 831 - (CGSize)collectionView:(UICollectionView*)collectionView
938 layout: 832 layout:
939 (UICollectionViewLayout*)collectionViewLayout 833 (UICollectionViewLayout*)collectionViewLayout
940 referenceSizeForHeaderInSection:(NSInteger)section { 834 referenceSizeForHeaderInSection:(NSInteger)section {
941 CGFloat headerHeight = 0; 835 CGFloat headerHeight = 0;
942 if (section == SectionWithOmnibox) { 836 if (section == SectionWithOmnibox) {
943 headerHeight = [self heightForSectionWithOmnibox]; 837 headerHeight = content_suggestions::heightForLogoHeader(
838 [self viewWidth], self.logoIsShowing, self.promoCanShow);
944 ((UICollectionViewFlowLayout*)collectionViewLayout).headerReferenceSize = 839 ((UICollectionViewFlowLayout*)collectionViewLayout).headerReferenceSize =
945 CGSizeMake(0, headerHeight); 840 CGSizeMake(0, headerHeight);
946 } else if (section == SectionWithMostVisited) { 841 } else if (section == SectionWithMostVisited) {
947 if (self.promoCanShow) { 842 if (self.promoCanShow) {
948 headerHeight = [self promoHeaderHeight]; 843 headerHeight = [self promoHeaderHeight];
949 } else { 844 } else {
950 headerHeight = kWhatsNewHeaderHiddenHeight; 845 headerHeight = kWhatsNewHeaderHiddenHeight;
951 } 846 }
952 } 847 }
953 return CGSizeMake(0, headerHeight); 848 return CGSizeMake(0, headerHeight);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 return _headerView; 918 return _headerView;
1024 } 919 }
1025 920
1026 if (indexPath.section == SectionWithMostVisited) { 921 if (indexPath.section == SectionWithMostVisited) {
1027 if (!_promoHeaderView) { 922 if (!_promoHeaderView) {
1028 _promoHeaderView.reset([[collectionView 923 _promoHeaderView.reset([[collectionView
1029 dequeueReusableSupplementaryViewOfKind: 924 dequeueReusableSupplementaryViewOfKind:
1030 UICollectionElementKindSectionHeader 925 UICollectionElementKindSectionHeader
1031 withReuseIdentifier:@"whatsNew" 926 withReuseIdentifier:@"whatsNew"
1032 forIndexPath:indexPath] retain]); 927 forIndexPath:indexPath] retain]);
1033 [_promoHeaderView setSideMargin:[self leftMargin]]; 928 [_promoHeaderView setSideMargin:content_suggestions::leftMarginForWidth(
929 [self viewWidth])];
1034 [_promoHeaderView setDelegate:self]; 930 [_promoHeaderView setDelegate:self];
1035 if (self.promoCanShow) { 931 if (self.promoCanShow) {
1036 [_promoHeaderView setText:self.promoText]; 932 [_promoHeaderView setText:self.promoText];
1037 [_promoHeaderView setIcon:self.promoIcon]; 933 [_promoHeaderView setIcon:self.promoIcon];
1038 [self.dataSource promoViewed]; 934 [self.dataSource promoViewed];
1039 } 935 }
1040 [_supplementaryViews addObject:_promoHeaderView]; 936 [_supplementaryViews addObject:_promoHeaderView];
1041 } 937 }
1042 return _promoHeaderView; 938 return _promoHeaderView;
1043 } 939 }
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
1514 - (void)setCanGoForward:(BOOL)canGoForward { 1410 - (void)setCanGoForward:(BOOL)canGoForward {
1515 _canGoForward = canGoForward; 1411 _canGoForward = canGoForward;
1516 [_headerView setCanGoForward:self.canGoForward]; 1412 [_headerView setCanGoForward:self.canGoForward];
1517 } 1413 }
1518 1414
1519 - (void)setCanGoBack:(BOOL)canGoBack { 1415 - (void)setCanGoBack:(BOOL)canGoBack {
1520 _canGoBack = canGoBack; 1416 _canGoBack = canGoBack;
1521 [_headerView setCanGoBack:self.canGoBack]; 1417 [_headerView setCanGoBack:self.canGoBack];
1522 } 1418 }
1523 @end 1419 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698